__.txt, partie après '\\n\\nGÉNÉRÉ:\\n', lue newline='' (octets exacts),
+ U+FFFD = octets perdus à l'écriture (decode 'replace') -> coupure ; dénominateurs : 'known' (octets connus, comme Checker)
+ et '200' (n_bytes publié, octets perdus comptés non couverts).
+Contrôles held-out : (a) les 7 vraies continuations (cont_hex de prompts_v1.json) ; (b) 100 tranches de 200 o tirées
+ (seed 0) dans test.bin du corpus du modèle. Aucune donnée d'éval écrite en sortie (comptes et offsets seulement)."""
+import os, sys, json, hashlib, time, resource
+import numpy as np
+S = "/workspace/spira_shared"; G = f"{S}/checker/gen"; OUTD = f"{S}/hashing_gen/gen_copy_recount/out"
+MODELS = {"old_ref": ("old_local_v1", f"{S}/broad/old_local_v1"), "bg1_m8": ("broad_gutenberg_v1", f"{S}/broad/broad_gutenberg_v1")}
+W, CH, OV, MAXQ = 16, 2 << 20, 256, 200
+RSS_CAP_KB = 280 * 1024
+BASE = np.uint64(1099511628211)
+POW = [np.uint64(1)]
+for _ in range(W - 1): POW.append(POW[-1] * BASE)
+POW = POW[::-1] # coefficient de b[t] = BASE^(W-1-t)
+
+def rss_kb():
+ for l in open("/proc/self/status"):
+ if l.startswith("VmRSS:"): return int(l.split()[1])
+def guard():
+ r = rss_kb()
+ if r > RSS_CAP_KB: print("ABANDON RSS", r, "kB", flush=True); sys.exit(3)
+ return r
+def fsha(p):
+ h = hashlib.sha256()
+ with open(p, "rb") as f:
+ for b in iter(lambda: f.read(4 << 20), b""): h.update(b)
+ return h.hexdigest()
+def whash(a): # a: uint8 array ; renvoie hash des fenêtres a[j:j+W], j = 0..len-W
+ n = len(a) - W + 1
+ if n <= 0: return np.zeros(0, np.uint64)
+ h = np.zeros(n, np.uint64)
+ with np.errstate(over="ignore"):
+ for t in range(W): h += a[t:t + n].astype(np.uint64) * POW[t]
+ return h
+
+def load_queries(tag, cname, cdir):
+ Q = [] # dict(kind, key, segs[list[bytes]], n_fffd, n_bytes_pub)
+ rows = [json.loads(l) for l in open(f"{G}/results_gen_v1.jsonl")]
+ for r in rows:
+ if r["tag"] != tag: continue
+ assert r["corpus"] == cname, (r["corpus"], cname)
+ fn = f"{G}/samples/{tag}__{r['decoding']}__{r['prompt']}.txt"
+ s = open(fn, encoding="utf-8", errors="strict", newline="").read()
+ parts = s.split("\n\nGÉNÉRÉ:\n")
+ assert len(parts) == 2 and s.endswith("\n"), fn
+ gt = parts[1][:-1]
+ Q.append({"kind": "gen_" + r["decoding"], "key": r["prompt"], "segs": [x.encode("utf-8") for x in gt.split("\ufffd")],
+ "n_fffd": gt.count("\ufffd"), "n_pub": r["n_bytes"], "pub_longest": r["longest_copy"],
+ "file_sha256": hashlib.sha256(open(fn, "rb").read()).hexdigest()})
+ for p in json.load(open(f"{G}/prompts_v1.json")):
+ cb = bytes.fromhex(p["cont_hex"])[:MAXQ]
+ Q.append({"kind": "heldout_cont", "key": p["name"], "segs": [cb], "n_fffd": 0, "n_pub": len(cb)})
+ tb = f"{cdir}/test.bin"; n = os.path.getsize(tb); rng = np.random.default_rng(0)
+ offs = sorted(int(x) for x in rng.integers(0, n - MAXQ, size=100))
+ with open(tb, "rb") as f:
+ for o in offs:
+ f.seek(o); Q.append({"kind": "heldout_test", "key": f"off{o}", "segs": [f.read(MAXQ)], "n_fffd": 0, "n_pub": MAXQ})
+ return Q
+
+def scan(train_path, Q):
+ # tables des requêtes : concat de tous les segments, séparés (pas de fenêtre à cheval)
+ segs = [(qi, si, sb) for qi, q in enumerate(Q) for si, sb in enumerate(q["segs"])]
+ starts = []; hs = []; seglen = []
+ for k, (qi, si, sb) in enumerate(segs):
+ a = np.frombuffer(sb, np.uint8); h = whash(a)
+ hs.append(h); starts.append(np.stack([np.full(len(h), k), np.arange(len(h))], 1) if len(h) else np.zeros((0, 2), int))
+ seglen.append(len(sb))
+ H = np.concatenate(hs) if hs else np.zeros(0, np.uint64); P = np.concatenate(starts).astype(np.int64)
+ order = np.argsort(H, kind="stable"); H = H[order]; P = P[order]
+ Uh, ustart = np.unique(H, return_index=True); uend = np.append(ustart[1:], len(H))
+ # requête paddée (-1) en int16 pour LCP
+ QB = np.full((len(segs), MAXQ + 1), -1, np.int16)
+ for k, (_, _, sb) in enumerate(segs): QB[k, :len(sb)] = np.frombuffer(sb, np.uint8)
+ M = np.zeros((len(segs), MAXQ), np.int32); MOFF = np.full((len(segs), MAXQ), -1, np.int64)
+ nhits = 0; peak = 0; t0 = time.time(); nver = [0, 0]
+ with open(train_path, "rb") as f:
+ pos = 0; tail = b""
+ while True:
+ blk = f.read(CH); last = not blk or len(blk) < CH
+ if not blk and not tail: break
+ buf = tail + blk; base = pos - len(tail)
+ a = np.frombuffer(buf, np.uint8)
+ h = whash(a)
+ lim = len(h) if last else max(0, len(a) - OV) # débuts traités dans ce bloc
+ h = h[:lim]
+ idx = np.searchsorted(Uh, h); idx[idx >= len(Uh)] = 0
+ hit = np.nonzero(Uh[idx] == h)[0]
+ del h
+ if len(hit):
+ ap = np.append(a.astype(np.int16), np.full(MAXQ + 1, -2, np.int16)); d = np.arange(MAXQ + 1)
+ SL = np.asarray(seglen, np.int64)
+ for h0 in range(0, len(hit), 4000):
+ hh = hit[h0:h0 + 4000]; u = idx[hh]; cnt = uend[u] - ustart[u]
+ tp = np.repeat(hh, cnt)
+ qrow = np.repeat(ustart[u], cnt) + (np.arange(int(cnt.sum())) - np.repeat(np.cumsum(cnt) - cnt, cnt))
+ sk = P[qrow, 0]; si = P[qrow, 1]
+ keep = M[sk, si] < (SL[sk] - si) # position déjà saturée : inutile
+ tp, sk, si = tp[keep], sk[keep], si[keep]; nhits += len(tp)
+ for b0 in range(0, len(tp), 8000):
+ t_ = tp[b0:b0 + 8000]; k_ = sk[b0:b0 + 8000]; i_ = si[b0:b0 + 8000]
+ tb_ = ap[t_[:, None] + d[None, :]]
+ qb_ = QB[k_[:, None], np.minimum(i_[:, None] + d[None, :], MAXQ)]
+ lcp = np.argmin((tb_ == qb_) & (qb_ >= 0), axis=1).astype(np.int32)
+ del tb_, qb_
+ ok = lcp >= W; nver[0] += int(len(lcp)); nver[1] += int((~ok).sum())
+ lcp, key, off = lcp[ok], (k_ * MAXQ + i_)[ok], (base + t_)[ok]
+ o = np.argsort(lcp, kind="stable"); lcp, key, off = lcp[o], key[o], off[o]
+ better = lcp > M.reshape(-1)[key]
+ M.reshape(-1)[key[better]] = lcp[better]; MOFF.reshape(-1)[key[better]] = off[better]
+ del ap
+ peak = max(peak, guard())
+ pos += len(blk); tail = buf[-OV:] if not last else b""
+ if last: break
+ if (pos // CH) % 16 == 0: print(f" {pos/1e6:.0f} Mo, {time.time()-t0:.0f} s, hits {nhits}, rss {rss_kb()} kB", flush=True)
+ print(' vérifiés', nver[0], 'collisions rejetées', nver[1], flush=True)
+ return segs, seglen, M, MOFF, nhits, peak, pos
+
+def summarize(Q, segs, seglen, M, MOFF):
+ for q in Q: q.update({"cov": {16: 0, 32: 0, 64: 0}, "longest": 0, "longest_train_off": -1, "known": 0})
+ for k, (qi, si, sb) in enumerate(segs):
+ q = Q[qi]; n = seglen[k]; q["known"] += n
+ for thr in (16, 32, 64):
+ c = np.zeros(n, bool)
+ for i in range(n):
+ L = int(M[k, i])
+ if L >= thr: c[i:i + L] = True
+ q["cov"][thr] += int(c.sum())
+ j = int(np.argmax(M[k, :n])) if n else 0
+ if n and M[k, j] > q["longest"]: q["longest"] = int(M[k, j]); q["longest_train_off"] = int(MOFF[k, j])
+ for q in Q:
+ q["cov_known"] = {t: q["cov"][t] / max(q["known"], 1) for t in q["cov"]}
+ q["cov_200"] = {t: q["cov"][t] / q["n_pub"] for t in q["cov"]}
+
+def boot(x, B=10000, seed=0):
+ x = np.asarray(x, float); rng = np.random.default_rng(seed)
+ mm = x[rng.integers(0, len(x), (B, len(x)))].mean(1)
+ return [float(x.mean()), float(np.percentile(mm, 2.5)), float(np.percentile(mm, 97.5))]
+
+def brute_check(train_path, Q, segs, M): # contrôle croisé exact (old_ref seulement : train entier en RAM, 12 Mo)
+ T = open(train_path, "rb").read(); bad = 0; n = 0
+ for k, (qi, si, sb) in enumerate(segs):
+ if not Q[qi]["kind"].startswith("gen"): continue
+ for i in range(len(sb)):
+ lo = 0
+ while i + lo < len(sb) and sb[i:i + lo + 1] in T: lo += 1
+ want = lo if lo >= W else 0; n += 1; bad += int(want != M[k, i])
+ del T; return {"positions": n, "mismatch": bad}
+
+if __name__ == "__main__":
+ t00 = time.time(); res = {"script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(), "models": {}}
+ for tag, (cname, cdir) in MODELS.items():
+ tp = f"{cdir}/train.bin"; man = None
+ Q = load_queries(tag, cname, cdir)
+ print(tag, "requêtes", len(Q), flush=True)
+ segs, seglen, M, MOFF, nhits, peak, nread = scan(tp, Q)
+ summarize(Q, segs, seglen, M, MOFF)
+ bc = brute_check(tp, Q, segs, M) if tag == "old_ref" else None
+ guard()
+ out = {"corpus": cname, "train": {"path": tp, "bytes": os.path.getsize(tp), "bytes_read": nread, "sha256": fsha(tp)},
+ "test_bin_sha256": fsha(f"{cdir}/test.bin"), "hits16": nhits, "peak_vmrss_kB_scan": peak, "brute_check": bc,
+ "per_query": [{k: v for k, v in q.items() if k != "segs"} for q in Q], "agg": {}}
+ for kind in ("gen_fused", "gen_v2b", "heldout_cont", "heldout_test"):
+ qs = [q for q in Q if q["kind"] == kind]; ag = {"n": len(qs)}
+ for den in ("cov_known", "cov_200"):
+ for t in (16, 32, 64): ag[f"{den}_{t}"] = boot([q[den][t] for q in qs])
+ ag["longest_max"] = max(q["longest"] for q in qs); ag["longest_mean"] = float(np.mean([q["longest"] for q in qs]))
+ p5 = [q for q in qs if q["key"] in ("en1", "en2", "fr1", "fr2", "code")]
+ if kind.startswith("gen"): ag["cov_known_32_P5_mean"] = float(np.mean([q["cov_known"][32] for q in p5]))
+ out["agg"][kind] = ag
+ res["models"][tag] = out
+ print(tag, json.dumps(out["agg"], indent=None)[:3000], "brute", bc, flush=True)
+ del Q, segs, M, MOFF
+ res["elapsed_s"] = round(time.time() - t00, 1); res["ru_maxrss_kB_self"] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
+ json.dump(res, open(f"{OUTD}/copy_recount.json", "w"), indent=1, ensure_ascii=False)
+ print("FINI", res["elapsed_s"], "s", flush=True)
diff --git a/results/hashing/gen_copy_recount/code/run_wrapped.py b/results/hashing/gen_copy_recount/code/run_wrapped.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f4d42514aa65956b2333f90b209184ac28693b3
--- /dev/null
+++ b/results/hashing/gen_copy_recount/code/run_wrapped.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python3
+"""Wrapper parent : lance le script en enfant (nice 10, OMP=1, PYTHONHASHSEED=0), mesure le pic RSS de l'enfant via wait4/getrusage."""
+import os, sys, subprocess, json, time
+D = os.path.dirname(os.path.abspath(__file__)); OUT = os.path.join(D, "..", "out")
+env = dict(os.environ, OMP_NUM_THREADS="1", OPENBLAS_NUM_THREADS="1", MKL_NUM_THREADS="1", PYTHONHASHSEED="0", TMPDIR=os.path.abspath(OUT))
+t0 = time.time()
+with open(os.path.join(OUT, "copy_recount.log"), "w") as lg:
+ p = subprocess.Popen(["nice", "-n", "10", sys.executable, os.path.join(D, "copy_recount.py")], stdout=lg, stderr=subprocess.STDOUT, env=env)
+ _, status, ru = os.wait4(p.pid, 0)
+r = {"exit_status": os.waitstatus_to_exitcode(status), "child_peak_rss_kB_getrusage": ru.ru_maxrss, "elapsed_s": round(time.time() - t0, 1)}
+json.dump(r, open(os.path.join(OUT, "copy_recount.mem.json"), "w")); print(r)
diff --git a/results/hashing/gen_copy_recount/relay_entry.md b/results/hashing/gen_copy_recount/relay_entry.md
new file mode 100644
index 0000000000000000000000000000000000000000..b28df847dbd06129f4c0c6aed504b04a4e3673e7
--- /dev/null
+++ b/results/hashing/gen_copy_recount/relay_entry.md
@@ -0,0 +1,40 @@
+
+## 25 oct 00 h 49 (Toronto) — SPIRA Hashing — recomptage indépendant de la copie du train (claim Checker 00 h 06 + erratum 00 h 45)
+
+Code écrit de zéro, rien importé de checker/. Lecture seule des samples checker/gen et des train.bin. Fichiers dans hashing_gen/gen_copy_recount/ : code/copy_recount.py (sha256 f4e533e3…dfb29), code/run_wrapped.py (9498c36b…80d6), out/copy_recount.json (3cf49b9b…4466), out/compare_checker.txt (c697f9f0…36c5).
+
+Conditions : nice 10, OMP=1, PYTHONHASHSEED=0, un seul process. **Pic RSS de l'enfant = 154,6 Mo** (getrusage, mesuré par le wrapper parent). Durée 104 s. cm 925745 non touché. Rien sous /tmp, aucun push HF.
+
+Corpus vérifiés (jobs_v4.tsv, colonne corpus du jsonl, meta.train_bytes des ckpt) :
+- old_ref → old_local_v1/train.bin, 12 468 350 o (sha e12b6586…) ;
+- bg1_m8 → broad_gutenberg_v1/train.bin, 290 810 502 o (sha 5af6398f…).
+
+Méthode : on hache les fenêtres de 16 o, puis on vérifie chaque hit octet à octet (24,4 M et 11,9 M vérifications, 0 collision). Train lu par blocs de 2 Mio, avec 256 o de chevauchement. Lecture newline="" ; U+FFFD traité comme une coupure. Un contrôle brute-force sur old_ref donne 2 796/2 796 positions identiques.
+
+v2b, 7 générations, moyenne [IC95 bootstrap, 10 000 tirages, seed 0] :
+- old_ref : cov≥32 = 83,6 % [68,9 ; 94,9] ; cov≥16 = 93,5 % ; cov≥64 = 59,7 % ; plus longue copie 196 o ; P5 = 88,5 %.
+- bg1_m8 : cov≥32 = 83,6 % [77,1 ; 89,6] ; cov≥16 = 90,6 % ; cov≥64 = 53,7 % ; plus longue copie 182 o ; P5 = 88,1 %.
+
+Fused :
+- old_ref : cov≥32 = 27,3 % [8,8 ; 47,8], max 123 o ;
+- bg1_m8 : cov≥32 = 56,5 % [26,5 ; 83,2], max 189 o.
+
+Témoin held-out (comptes seulement) :
+- 7 vraies continuations : cov≥32 = 2,3 % [0 ; 6,9], max 32 o (les deux modèles).
+- 100 tranches de 200 o de test.bin (seed 0) : old 4,7 % [2,5 ; 7,2], max 49 o ; bg1 9,0 % [4,4 ; 14,2], max 200 o. 3 tranches sur 100 sont entières dans le train : test.bin de broad_gutenberg_v1 n'est pas disjoint de son train.
+
+Comparaison avec Checker, par génération (28) :
+- longest_copy, cov≥32, octets connus et offset : **IDENTIQUES** sur 25/28.
+- old_ref v2b/fr1 : cov 87,9 % contre 68,0 % au relais de 00 h 06. C'est **DIFF avec 00 h 06** et **IDENTIQUE à l'erratum cr_fix 00 h 45**.
+- bg1_m8 fused en1 et fr1 : Checker donne 12 et 15 o ; ma méthode a un plancher à 16 o, donc « < 16 ». Pas de contradiction, mais non vérifiable par ma méthode.
+- Moyennes : old_ref v2b 83,6 / 88,5 (**DIFF** avec 80,7 / 84,5 de 00 h 06, **IDENTIQUE** à l'erratum) ; bg1_m8 v2b 83,6 / 88,1 **IDENTIQUE** ; fused 27,3 / 56,5 **IDENTIQUE**.
+- Plus longue copie 196 o : **IDENTIQUE**.
+
+Verdict : la copie du train en v2b est **CONFIRMÉE**. Le témoin held-out est à 2–9 %, contre environ 84 % pour v2b.
+
+Réserves :
+- n = 7 par modèle, donc des IC larges.
+- old_ref v2b/fr1 donne 88 contre 89 publié : l'octet perdu au U+FFFD ne peut pas être reconstruit depuis les samples.
+- La couverture est mesurée contre le fichier train entier, pas contre la seule tranche vue par le SNN (le n-gramme v2b est compté sur le train).
+
+Lu/appliqué — SPIRA Hashing
diff --git a/results/hashing/gen_kit_check_r1/REPORT.md b/results/hashing/gen_kit_check_r1/REPORT.md
new file mode 100644
index 0000000000000000000000000000000000000000..4c1cf2356731b8647020799c33eefcc62448ccda
--- /dev/null
+++ b/results/hashing/gen_kit_check_r1/REPORT.md
@@ -0,0 +1,33 @@
+# gen_kit_check_r1 — kit de test de génération : figé et caviardé (contrôle statique, test NON lancé)
+Aucun texte de prompt n'est cité ici, ni dans gen_kit_check_result.json.
+
+## Figé : PASS
+| objet | sha attendu | sha mesuré |
+|---|---|---|
+| PREDECL_gen_test_runC_r1.md | e451dfc7 | e451dfc7 |
+| gen_kit_r2_result.json | 026dc89f | 026dc89f (gen_test_kit_r2/SHA256SUMS -c OK) |
+| gen_prompts.py | 57fed6cb | 57fed6cb |
+| gen_prompts_manifest.json | 70acee7b | 70acee7b |
+| NEVER_PUSH/prompts_and_cont.bin | ca47ea80 | ca47ea80 |
+
+- Les 5 prompts et les 5 continuations de 200 o, relus via le manifeste depuis les fenêtres, ont tous le bon sha (prompts faf784ed, 54cdebf1, 90d5ab55, 01f41694, b97f1cf2), et les sha des fenêtres sont OK.
+- gen_test/SHA256SUMS (23 lignes) : -c OK.
+
+## Caviardé : PASS sur le périmètre demandé
+- Méthode : gen_kit_check_v2.py, PID 1171344, nice 19, 434,3 s, maxrss 39,9 Mo.
+- Périmètre : 55 386 fichiers texte de spira_shared (dont spira_relay.md, tous les .md, .json et .log), tout hf_ready (8 dossiers) et /workspace/SPIRA/web/public.
+- Pour chaque fichier : recherche des 200 o exacts et des 169 sous-chaînes de 32 o, pour chaque prompt et chaque continuation.
+- Hors périmètre : NEVER_PUSH*, broad/, binaires .bin/.npz/.npy, venv.
+- Relais, rapports, hf_ready, web/public : **0 hit**.
+- Les 3 fichiers de plus de 20 Mo ont été rescannés à part : 0 hit. Ce sont spira_deploy.json (public), sha_manifest_corpora_FULL_LOCAL.json et pg_catalog.csv.
+- 19 hits, tous dans des corpus bruts sources (corpus_v3/raw, corpus_gutenberg, corpus_gutenberg_v2/raw) ; c'est attendu, car ce sont les textes d'origine des fenêtres :
+ - test_v3 : 200 o exacts dans corpus_v3/raw/pg1184.txt, prompt et continuation ;
+ - fresh_en : 107/169 et 96/169 dans pg5200.txt et metamorphosis.txt ;
+ - test20k_old : 107/169 et 97/169 dans frankenstein.txt et pg84.txt ;
+ - quelques sous-chaînes isolées (1 à 7) dans d'autres livres.
+- **Fait nouveau** : fresh_en recoupe un texte Gutenberg ancien (Metamorphosis). « fresh » ne veut donc pas dire « postérieur ».
+
+## Erreurs de ma part
+- La 1re version, gen_kit_check.py (PID 1163831), avait un périmètre trop large (298 497 fichiers) ; je l'ai tuée après plus de 10 min, sans résultat, et j'ai supprimé ma copie, donc il n'y a pas de sha.
+- Un 1er lancement de la v2 a échoué (SyntaxError) avant tout calcul.
+- py_compile a créé un __pycache__ dans mon dossier ; je l'ai supprimé.
diff --git a/results/hashing/gen_kit_check_r1/SHA256SUMS b/results/hashing/gen_kit_check_r1/SHA256SUMS
new file mode 100644
index 0000000000000000000000000000000000000000..879bfba97e68961b47b356059dd4d63abd98c8fe
--- /dev/null
+++ b/results/hashing/gen_kit_check_r1/SHA256SUMS
@@ -0,0 +1,4 @@
+e0ebfd9292c4191d0957704da14db58e7ab7b3514a54c837005e9c2809d8014c gen_kit_check_v2.py
+017d085a748e1e984c0490172abd813203906a6647b9c3396373b47d1549aa48 gen_kit_check_result.json
+d3cc43bf4e16b379cb341f655316b6eb9a728ca44d6070dbbdcc03e5e2ca1499 run.log
+e65221b52abfed9b13b56ac3a8498f52fc0e5ecaca0c93b155c2baedc231ee1a REPORT.md
diff --git a/results/hashing/gen_kit_check_r1/SHA256SUMS_v3 b/results/hashing/gen_kit_check_r1/SHA256SUMS_v3
new file mode 100644
index 0000000000000000000000000000000000000000..3412052216e387325fb6d2e6a35c87330f0b2e8d
--- /dev/null
+++ b/results/hashing/gen_kit_check_r1/SHA256SUMS_v3
@@ -0,0 +1,7 @@
+e0ebfd9292c4191d0957704da14db58e7ab7b3514a54c837005e9c2809d8014c gen_kit_check_v2.py
+e01d2f2a2110a2d8803cf8f74cb5d978bc63b7a9fd602ec20177b1e3a4fda42b gen_kit_check_v3.py
+79be901c5fa010885b4d2f88a357cf16e89f1f3d4b1b88b7612423feb70cec2d gen_kit_check_v3b.py
+da94f7ae45b171d7a366fa5bf2154b62ebd58fd53576201966a9c11427750a2c gen_kit_check_v3_result.json
+c1b083d49a82ffbf880a81f945ab88a9d71896b5a140071007aaa61a51286f4d run_v3.log
+898a0d9be827c190615c82241f6e5550875bd8293ef61597b74b5a87a5fb7327 selftest_v3.sh
+bc6a8f1e930501b240e1f7f5a5156deb54d678893bacb4d96c7e879a5e2921d4 selftest_v3_result.txt
diff --git a/results/hashing/gen_kit_check_r1/SHA256SUMS_v3b_20261031 b/results/hashing/gen_kit_check_r1/SHA256SUMS_v3b_20261031
new file mode 100644
index 0000000000000000000000000000000000000000..3412052216e387325fb6d2e6a35c87330f0b2e8d
--- /dev/null
+++ b/results/hashing/gen_kit_check_r1/SHA256SUMS_v3b_20261031
@@ -0,0 +1,7 @@
+e0ebfd9292c4191d0957704da14db58e7ab7b3514a54c837005e9c2809d8014c gen_kit_check_v2.py
+e01d2f2a2110a2d8803cf8f74cb5d978bc63b7a9fd602ec20177b1e3a4fda42b gen_kit_check_v3.py
+79be901c5fa010885b4d2f88a357cf16e89f1f3d4b1b88b7612423feb70cec2d gen_kit_check_v3b.py
+da94f7ae45b171d7a366fa5bf2154b62ebd58fd53576201966a9c11427750a2c gen_kit_check_v3_result.json
+c1b083d49a82ffbf880a81f945ab88a9d71896b5a140071007aaa61a51286f4d run_v3.log
+898a0d9be827c190615c82241f6e5550875bd8293ef61597b74b5a87a5fb7327 selftest_v3.sh
+bc6a8f1e930501b240e1f7f5a5156deb54d678893bacb4d96c7e879a5e2921d4 selftest_v3_result.txt
diff --git a/results/hashing/gen_kit_check_r1/gen_kit_check_result.json b/results/hashing/gen_kit_check_r1/gen_kit_check_result.json
new file mode 100644
index 0000000000000000000000000000000000000000..1649a8d247d6fc5213edd42fa57c3865d28016ff
--- /dev/null
+++ b/results/hashing/gen_kit_check_r1/gen_kit_check_result.json
@@ -0,0 +1,200 @@
+{
+ "sha": {
+ "gen_prompts.py": "57fed6cb540f5fb1c91f23a62d96a5c9c9587030e60bf9b4685eede5438ac029",
+ "gen_prompts_manifest.json": "70acee7babde01f77e53d3691c40d4cafae3e55c3d7043e1966de36a9320c2d9",
+ "NEVER_PUSH/prompts_and_cont.bin": "ca47ea802b09312c1419563a28fe1e2ccab13df1511bf339c8008183dce47902",
+ "checker/recount/runC_ready/PREDECL_gen_test_runC_r1.md": "e451dfc7978bd92ada40b45e7c4efc94776555722e2b42a47b74fb1db5dfa66a",
+ "checker/recount/runC_ready/gen_test_kit_r2/gen_kit_r2_result.json": "026dc89f20c58833790ffca86b74572f12f933e7cb2145f703b12649e99aeb9d"
+ },
+ "items": [
+ {
+ "window": "fc2",
+ "window_sha_ok": true,
+ "prompt_sha_ok": true,
+ "cont_sha_ok": true,
+ "prompt_sha": "faf784ed0e85331ff8db7cb0caf356543ed1c3e02134a76429677347d4167192"
+ },
+ {
+ "window": "fresh_en",
+ "window_sha_ok": true,
+ "prompt_sha_ok": true,
+ "cont_sha_ok": true,
+ "prompt_sha": "54cdebf119f3f390226922515f3ebce66cc549062caeb2ed3df6ffee7babfa16"
+ },
+ {
+ "window": "fresh_fr",
+ "window_sha_ok": true,
+ "prompt_sha_ok": true,
+ "cont_sha_ok": true,
+ "prompt_sha": "90d5ab55d2729276b0eb6084625a1ef7ab9bb6fe7e282f34f71672798927942f"
+ },
+ {
+ "window": "test20k_old",
+ "window_sha_ok": true,
+ "prompt_sha_ok": true,
+ "cont_sha_ok": true,
+ "prompt_sha": "01f4169450cd9eaf617e1f7c2f5d6f1c07f58f255ac6df1ab35791cd4d8f50ec"
+ },
+ {
+ "window": "test_v3",
+ "window_sha_ok": true,
+ "prompt_sha_ok": true,
+ "cont_sha_ok": true,
+ "prompt_sha": "b97f1cf219ca6cf62798e6c1df03a4dd5ff7bd01c015e9202e66aa9fcbcc99e1"
+ }
+ ],
+ "fichiers_scannes": 55386,
+ "octets_scannes": 947372343,
+ "ignores_gt20Mo": [
+ [
+ "/workspace/spira_shared/checker/recount/diverse_dedup_1509/sha_manifest_corpora_FULL_LOCAL.json",
+ 44891889
+ ],
+ [
+ "/workspace/spira_shared/corpus_gutenberg_v2/pg_catalog.csv",
+ 21263721
+ ],
+ [
+ "/workspace/SPIRA/web/public/spira_deploy.json",
+ 29063956
+ ]
+ ],
+ "exclusions": "NEVER_PUSH*, broad/, .git, __pycache__, binaires .bin .npz .npy .pt .ckpt .safetensors .lock ; seuls les fichiers texte .md .json .txt .log .csv .diff .py .sh .yaml .yml .html, tout hf_ready, tout web/public ; venv/site-packages exclus ; ce script et son r\u00e9sultat ne contiennent aucun texte",
+ "hits": [
+ {
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg1184.txt",
+ "window": "test_v3",
+ "seg": "prompt",
+ "full200": true,
+ "sub32_hits_sur_169": 169
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg1184.txt",
+ "window": "test_v3",
+ "seg": "cont",
+ "full200": true,
+ "sub32_hits_sur_169": 169
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg5200.txt",
+ "window": "fresh_en",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_hits_sur_169": 107
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg5200.txt",
+ "window": "fresh_en",
+ "seg": "cont",
+ "full200": false,
+ "sub32_hits_sur_169": 96
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/frankenstein.txt",
+ "window": "test20k_old",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_hits_sur_169": 107
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/frankenstein.txt",
+ "window": "test20k_old",
+ "seg": "cont",
+ "full200": false,
+ "sub32_hits_sur_169": 97
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/metamorphosis.txt",
+ "window": "fresh_en",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_hits_sur_169": 107
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/metamorphosis.txt",
+ "window": "fresh_en",
+ "seg": "cont",
+ "full200": false,
+ "sub32_hits_sur_169": 96
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg83.txt",
+ "window": "test_v3",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_hits_sur_169": 2
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg203.txt",
+ "window": "test_v3",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_hits_sur_169": 6
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg200.txt",
+ "window": "fresh_en",
+ "seg": "cont",
+ "full200": false,
+ "sub32_hits_sur_169": 3
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg90.txt",
+ "window": "test_v3",
+ "seg": "cont",
+ "full200": false,
+ "sub32_hits_sur_169": 1
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg82.txt",
+ "window": "test_v3",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_hits_sur_169": 6
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg415.txt",
+ "window": "test_v3",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_hits_sur_169": 2
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg84.txt",
+ "window": "test20k_old",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_hits_sur_169": 107
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg84.txt",
+ "window": "test20k_old",
+ "seg": "cont",
+ "full200": false,
+ "sub32_hits_sur_169": 97
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg308.txt",
+ "window": "test_v3",
+ "seg": "cont",
+ "full200": false,
+ "sub32_hits_sur_169": 2
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg344.txt",
+ "window": "test_v3",
+ "seg": "cont",
+ "full200": false,
+ "sub32_hits_sur_169": 2
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg164.txt",
+ "window": "test_v3",
+ "seg": "cont",
+ "full200": false,
+ "sub32_hits_sur_169": 7
+ }
+ ],
+ "secondes": 434.3,
+ "maxrss_Mo": 39.91015625
+}
\ No newline at end of file
diff --git a/results/hashing/gen_kit_check_r1/gen_kit_check_v2.py b/results/hashing/gen_kit_check_r1/gen_kit_check_v2.py
new file mode 100644
index 0000000000000000000000000000000000000000..103b86145e86077fbd096d9bbe39de04c3452e2f
--- /dev/null
+++ b/results/hashing/gen_kit_check_r1/gen_kit_check_v2.py
@@ -0,0 +1,32 @@
+"""Vérif statique du kit de génération (figé + caviardé). N'affiche ni n'écrit aucun texte de prompt : seulement chemins, sha, compteurs."""
+import os, json, hashlib, time, resource
+T0 = time.perf_counter(); S = "/workspace/spira_shared/"; G = S + "checker/recount/gen_test/"
+sha = lambda b: hashlib.sha256(b).hexdigest()
+man = json.load(open(G + "gen_prompts_manifest.json")); R = {"sha": {}, "items": []}
+for f in ["gen_prompts.py", "gen_prompts_manifest.json", "NEVER_PUSH/prompts_and_cont.bin"]: R["sha"][f] = sha(open(G + f, "rb").read())
+for f in ["checker/recount/runC_ready/PREDECL_gen_test_runC_r1.md", "checker/recount/runC_ready/gen_test_kit_r2/gen_kit_r2_result.json"]: R["sha"][f] = sha(open(S + f, "rb").read())
+P = []
+for it in man["items"]:
+ w = open(S + it["path"], "rb").read(); p = w[it["start"]:it["start"] + 200]; c = w[it["start"] + 200:it["start"] + 400]
+ R["items"].append({"window": it["window"], "window_sha_ok": sha(w) == it["window_sha256"], "prompt_sha_ok": sha(p) == it["prompt_sha256"], "cont_sha_ok": sha(c) == it["cont_sha256"], "prompt_sha": it["prompt_sha256"]})
+ P.append((it["window"], p, c))
+TXT = (".md", ".json", ".txt", ".log", ".csv", ".diff", ".py", ".sh", ".yaml", ".yml", ".html"); EXCL_DIR = ("NEVER_PUSH",); EXCL_SUFFIX = (".bin", ".npz", ".npy", ".pt", ".ckpt", ".safetensors", ".lock")
+roots = [S, "/workspace/SPIRA/web/public"]; hits = []; n = 0; skipped = []; nbytes = 0
+for root in roots:
+ for dp, dn, fn in os.walk(root):
+ dn[:] = [d for d in dn if not d.startswith(EXCL_DIR) and d not in ("broad", "__pycache__", ".git")]
+ for f in fn:
+ fp = os.path.join(dp, f)
+ if "site-packages" in fp or "/venv" in fp or "/.venv" in fp: continue
+ if not (f.endswith(TXT) or "hf_ready" in fp or root != S or f == "spira_relay.md"): continue
+ try: sz = os.path.getsize(fp)
+ except OSError: continue
+ if sz > 20 << 20: skipped.append([fp, sz]); continue
+ b = open(fp, "rb").read(); n += 1; nbytes += sz
+ for wname, p, c in P:
+ for kind, t in (("prompt", p), ("cont", c)):
+ full = t in b; k32 = sum(1 for i in range(0, 169) if t[i:i + 32] in b)
+ if full or k32: hits.append({"file": fp, "window": wname, "seg": kind, "full200": full, "sub32_hits_sur_169": k32})
+R.update({"fichiers_scannes": n, "octets_scannes": nbytes, "ignores_gt20Mo": skipped, "exclusions": "NEVER_PUSH*, broad/, .git, __pycache__, binaires " + " ".join(EXCL_SUFFIX) + " ; seuls les fichiers texte " + " ".join(TXT) + ", tout hf_ready, tout web/public ; venv/site-packages exclus ; ce script et son résultat ne contiennent aucun texte", "hits": hits, "secondes": round(time.perf_counter() - T0, 1), "maxrss_Mo": resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024})
+json.dump(R, open(os.path.dirname(os.path.abspath(__file__)) + "/gen_kit_check_result.json", "w"), indent=1)
+print(n, len(hits), len(skipped), R["secondes"])
diff --git a/results/hashing/gen_kit_check_r1/gen_kit_check_v3.py b/results/hashing/gen_kit_check_r1/gen_kit_check_v3.py
new file mode 100644
index 0000000000000000000000000000000000000000..1351d054334be5388b33864f1d49f86f38f4f3b4
--- /dev/null
+++ b/results/hashing/gen_kit_check_r1/gen_kit_check_v3.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+"""gen_kit_check_v3 — SPIRA Hashing. Vérif STATIQUE du kit de génération : figé (sha) + caviardé (aucune copie de prompt/continuation hors sources).
+N'affiche ni n'écrit aucun texte de prompt : seulement chemins, sha, compteurs. v2 (e0ebfd92) inchangé.
+rc : 0 = PASS ; 3 = FAIL ; 2 = analyse impossible.
+Règles :
+- figé : sha des fichiers du kit = attendus ; pour chaque item du manifeste, window_sha_ok, prompt_sha_ok, cont_sha_ok tous vrais ; manifeste à 5 items, blob_sha = sha du blob.
+- caviardé : dans le périmètre scanné, tout fichier contenant les 200 o exacts ou ≥ 1 sous-chaîne de 32 o d'un prompt/continuation → hit ;
+ un hit est TOLÉRÉ seulement sous un préfixe de corpus source déclaré (--source-prefix) ; tout autre hit → FAIL.
+- périmètre : fichiers texte (TXT) + tout fichier sous hf_ready ou sous une racine publique (--public-root) ; EXCL_SUFFIX appliqué partout
+ SAUF sous hf_ready et racines publiques (ce qui est publiable est scanné quel que soit le suffixe) ; dossiers NEVER_PUSH*, broad, .git, __pycache__, venv exclus.
+ Limite déclarée : broad/ et /tmp ne sont pas lus."""
+import os, sys, json, hashlib, time, resource, argparse
+T0 = time.perf_counter(); sha = lambda b: hashlib.sha256(b).hexdigest()
+S = "/workspace/spira_shared/"; G = S + "checker/recount/gen_test/"
+ap = argparse.ArgumentParser()
+ap.add_argument("--data-root", default=S)
+ap.add_argument("--manifest", default=G + "gen_prompts_manifest.json")
+ap.add_argument("--expect", default=json.dumps({
+ G + "gen_prompts.py": "57fed6cb540f5fb1c91f23a62d96a5c9c9587030e60bf9b4685eede5438ac029",
+ G + "gen_prompts_manifest.json": "70acee7babde01f77e53d3691c40d4cafae3e55c3d7043e1966de36a9320c2d9",
+ G + "NEVER_PUSH/prompts_and_cont.bin": "ca47ea802b09312c1419563a28fe1e2ccab13df1511bf339c8008183dce47902",
+ S + "checker/recount/runC_ready/PREDECL_gen_test_runC_r1.md": "e451dfc7978bd92ada40b45e7c4efc94776555722e2b42a47b74fb1db5dfa66a",
+ S + "checker/recount/runC_ready/gen_test_kit_r2/gen_kit_r2_result.json": "026dc89f20c58833790ffca86b74572f12f933e7cb2145f703b12649e99aeb9d"}))
+ap.add_argument("--blob", default=G + "NEVER_PUSH/prompts_and_cont.bin")
+ap.add_argument("--n-items", type=int, default=5)
+ap.add_argument("--scan-root", action="append")
+ap.add_argument("--public-root", action="append")
+ap.add_argument("--source-prefix", action="append")
+ap.add_argument("--out", required=True)
+a = ap.parse_args()
+scan_roots = a.scan_root or [S]; pub_roots = a.public_root or ["/workspace/SPIRA/web/public"]
+src_pfx = a.source_prefix or [S + "corpus_v3/raw/", S + "corpus_gutenberg/", S + "corpus_gutenberg_v2/raw/"]
+TXT = (".md", ".json", ".txt", ".log", ".csv", ".diff", ".py", ".sh", ".yaml", ".yml", ".html")
+EXCL_SUFFIX = (".bin", ".npz", ".npy", ".pt", ".ckpt", ".safetensors", ".lock")
+SKIP_DIR = ("NEVER_PUSH", "broad", ".git", "__pycache__", "venv", ".venv", "site-packages")
+R = {"version": "v3", "rc": 2, "verdict": None, "erreur": None}
+def fin(rc, err=None):
+ R["rc"] = rc; R["erreur"] = err; R["verdict"] = {0: "PASS", 3: "FAIL"}.get(rc, "ANALYSE IMPOSSIBLE")
+ R["secondes"] = round(time.perf_counter() - T0, 1); R["maxrss_Mo"] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024
+ try: json.dump(R, open(a.out, "w"), indent=1)
+ except Exception as e: print("sortie impossible", e, file=sys.stderr); sys.exit(2)
+ print(json.dumps({k: R[k] for k in ("rc", "verdict", "erreur", "fichiers_scannes", "n_hits_hors_source", "n_hits_source") if k in R})); sys.exit(rc)
+try:
+ exp = json.loads(a.expect); man = json.load(open(a.manifest)); blob = open(a.blob, "rb").read()
+except Exception as e: fin(2, f"lecture impossible : {e}")
+fails = []
+R["kit_sha"] = {}
+for f, e in exp.items():
+ try: h = sha(open(f, "rb").read())
+ except Exception as x: fin(2, f"fichier du kit absent : {f}")
+ ok = h.startswith(e); R["kit_sha"][f] = {"sha": h, "attendu": e, "ok": ok}
+ if not ok: fails.append("kit_sha:" + f)
+if man.get("blob_sha256") != sha(blob): fails.append("blob_sha_manifeste")
+items = man.get("items", [])
+if len(items) != a.n_items: fails.append(f"n_items {len(items)}≠{a.n_items}")
+P = []; R["items"] = []
+for it in items:
+ try: w = open(os.path.join(a.data_root, it["path"]), "rb").read()
+ except Exception: fin(2, f"fenêtre absente : {it.get('path')}")
+ s0 = it["start"]; p = w[s0:s0 + 200]; c = w[s0 + 200:s0 + 400]
+ d = {"window": it["window"], "window_sha_ok": sha(w) == it["window_sha256"], "prompt_sha_ok": sha(p) == it["prompt_sha256"], "cont_sha_ok": sha(c) == it["cont_sha256"], "prompt_len_ok": len(p) == 200 and len(c) == 200}
+ R["items"].append(d)
+ for k in ("window_sha_ok", "prompt_sha_ok", "cont_sha_ok", "prompt_len_ok"):
+ if not d[k]: fails.append(f"{it['window']}:{k}")
+ P.append((it["window"], p, c))
+hits = []; n = 0; nb = 0; skipped = []
+for root in scan_roots + pub_roots:
+ pub = root in pub_roots
+ for dp, dn, fn in os.walk(root):
+ dn[:] = [x for x in dn if not x.startswith(SKIP_DIR) and x not in SKIP_DIR]
+ for f in fn:
+ fp = os.path.join(dp, f); forced = pub or "hf_ready" in fp
+ if fp.startswith("/tmp/"): continue
+ if not forced and (f.endswith(EXCL_SUFFIX) or not (f.endswith(TXT) or f == "spira_relay.md")): continue
+ try: b = open(fp, "rb").read()
+ except Exception as e: skipped.append([fp, str(e)[:80]]); continue
+ n += 1; nb += len(b)
+ for wn, p, c in P:
+ for kind, t in (("prompt", p), ("cont", c)):
+ full = t in b; k32 = sum(1 for i in range(169) if t[i:i + 32] in b)
+ if full or k32: hits.append({"file": fp, "window": wn, "seg": kind, "full200": full, "sub32_sur_169": k32, "source_toleree": any(fp.startswith(x) for x in src_pfx)})
+bad = [h for h in hits if not h["source_toleree"]]
+R.update({"perimetre": {"scan_roots": scan_roots, "public_roots": pub_roots, "source_prefixes": src_pfx, "TXT": TXT, "EXCL_SUFFIX": EXCL_SUFFIX, "SKIP_DIR": SKIP_DIR},
+ "fichiers_scannes": n, "octets_scannes": nb, "illisibles": skipped, "hits": hits, "n_hits_source": len(hits) - len(bad), "n_hits_hors_source": len(bad), "fails_fige": fails})
+if bad: fails.append(f"caviardage: {len(bad)} hit(s) hors source")
+if skipped: fails.append(f"{len(skipped)} fichier(s) illisible(s)")
+R["fails"] = fails
+fin(3 if fails else 0)
diff --git a/results/hashing/gen_kit_check_r1/gen_kit_check_v3_result.json b/results/hashing/gen_kit_check_r1/gen_kit_check_v3_result.json
new file mode 100644
index 0000000000000000000000000000000000000000..ad91ce27cd08445ac4d5c3984ab7404e44b8ab07
--- /dev/null
+++ b/results/hashing/gen_kit_check_r1/gen_kit_check_v3_result.json
@@ -0,0 +1,277 @@
+{
+ "version": "v3",
+ "rc": 0,
+ "verdict": "PASS",
+ "erreur": null,
+ "kit_sha": {
+ "/workspace/spira_shared/checker/recount/gen_test/gen_prompts.py": {
+ "sha": "57fed6cb540f5fb1c91f23a62d96a5c9c9587030e60bf9b4685eede5438ac029",
+ "attendu": "57fed6cb540f5fb1c91f23a62d96a5c9c9587030e60bf9b4685eede5438ac029",
+ "ok": true
+ },
+ "/workspace/spira_shared/checker/recount/gen_test/gen_prompts_manifest.json": {
+ "sha": "70acee7babde01f77e53d3691c40d4cafae3e55c3d7043e1966de36a9320c2d9",
+ "attendu": "70acee7babde01f77e53d3691c40d4cafae3e55c3d7043e1966de36a9320c2d9",
+ "ok": true
+ },
+ "/workspace/spira_shared/checker/recount/gen_test/NEVER_PUSH/prompts_and_cont.bin": {
+ "sha": "ca47ea802b09312c1419563a28fe1e2ccab13df1511bf339c8008183dce47902",
+ "attendu": "ca47ea802b09312c1419563a28fe1e2ccab13df1511bf339c8008183dce47902",
+ "ok": true
+ },
+ "/workspace/spira_shared/checker/recount/runC_ready/PREDECL_gen_test_runC_r1.md": {
+ "sha": "e451dfc7978bd92ada40b45e7c4efc94776555722e2b42a47b74fb1db5dfa66a",
+ "attendu": "e451dfc7978bd92ada40b45e7c4efc94776555722e2b42a47b74fb1db5dfa66a",
+ "ok": true
+ },
+ "/workspace/spira_shared/checker/recount/runC_ready/gen_test_kit_r2/gen_kit_r2_result.json": {
+ "sha": "026dc89f20c58833790ffca86b74572f12f933e7cb2145f703b12649e99aeb9d",
+ "attendu": "026dc89f20c58833790ffca86b74572f12f933e7cb2145f703b12649e99aeb9d",
+ "ok": true
+ }
+ },
+ "items": [
+ {
+ "window": "fc2",
+ "window_sha_ok": true,
+ "prompt_sha_ok": true,
+ "cont_sha_ok": true,
+ "prompt_len_ok": true
+ },
+ {
+ "window": "fresh_en",
+ "window_sha_ok": true,
+ "prompt_sha_ok": true,
+ "cont_sha_ok": true,
+ "prompt_len_ok": true
+ },
+ {
+ "window": "fresh_fr",
+ "window_sha_ok": true,
+ "prompt_sha_ok": true,
+ "cont_sha_ok": true,
+ "prompt_len_ok": true
+ },
+ {
+ "window": "test20k_old",
+ "window_sha_ok": true,
+ "prompt_sha_ok": true,
+ "cont_sha_ok": true,
+ "prompt_len_ok": true
+ },
+ {
+ "window": "test_v3",
+ "window_sha_ok": true,
+ "prompt_sha_ok": true,
+ "cont_sha_ok": true,
+ "prompt_len_ok": true
+ }
+ ],
+ "perimetre": {
+ "scan_roots": [
+ "/workspace/spira_shared/"
+ ],
+ "public_roots": [
+ "/workspace/SPIRA/web/public"
+ ],
+ "source_prefixes": [
+ "/workspace/spira_shared/corpus_v3/raw/",
+ "/workspace/spira_shared/corpus_gutenberg/",
+ "/workspace/spira_shared/corpus_gutenberg_v2/raw/"
+ ],
+ "TXT": [
+ ".md",
+ ".json",
+ ".txt",
+ ".log",
+ ".csv",
+ ".diff",
+ ".py",
+ ".sh",
+ ".yaml",
+ ".yml",
+ ".html"
+ ],
+ "EXCL_SUFFIX": [
+ ".bin",
+ ".npz",
+ ".npy",
+ ".pt",
+ ".ckpt",
+ ".safetensors",
+ ".lock"
+ ],
+ "SKIP_DIR": [
+ "NEVER_PUSH",
+ "broad",
+ ".git",
+ "__pycache__",
+ "venv",
+ ".venv",
+ "site-packages"
+ ]
+ },
+ "fichiers_scannes": 53727,
+ "octets_scannes": 1034296244,
+ "illisibles": [],
+ "hits": [
+ {
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg1184.txt",
+ "window": "test_v3",
+ "seg": "prompt",
+ "full200": true,
+ "sub32_sur_169": 169,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg1184.txt",
+ "window": "test_v3",
+ "seg": "cont",
+ "full200": true,
+ "sub32_sur_169": 169,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg5200.txt",
+ "window": "fresh_en",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_sur_169": 107,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg5200.txt",
+ "window": "fresh_en",
+ "seg": "cont",
+ "full200": false,
+ "sub32_sur_169": 96,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/frankenstein.txt",
+ "window": "test20k_old",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_sur_169": 107,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/frankenstein.txt",
+ "window": "test20k_old",
+ "seg": "cont",
+ "full200": false,
+ "sub32_sur_169": 97,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/metamorphosis.txt",
+ "window": "fresh_en",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_sur_169": 107,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/metamorphosis.txt",
+ "window": "fresh_en",
+ "seg": "cont",
+ "full200": false,
+ "sub32_sur_169": 96,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg83.txt",
+ "window": "test_v3",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_sur_169": 2,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg203.txt",
+ "window": "test_v3",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_sur_169": 6,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg200.txt",
+ "window": "fresh_en",
+ "seg": "cont",
+ "full200": false,
+ "sub32_sur_169": 3,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg90.txt",
+ "window": "test_v3",
+ "seg": "cont",
+ "full200": false,
+ "sub32_sur_169": 1,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg82.txt",
+ "window": "test_v3",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_sur_169": 6,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg415.txt",
+ "window": "test_v3",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_sur_169": 2,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg84.txt",
+ "window": "test20k_old",
+ "seg": "prompt",
+ "full200": false,
+ "sub32_sur_169": 107,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg84.txt",
+ "window": "test20k_old",
+ "seg": "cont",
+ "full200": false,
+ "sub32_sur_169": 97,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg308.txt",
+ "window": "test_v3",
+ "seg": "cont",
+ "full200": false,
+ "sub32_sur_169": 2,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg344.txt",
+ "window": "test_v3",
+ "seg": "cont",
+ "full200": false,
+ "sub32_sur_169": 2,
+ "source_toleree": true
+ },
+ {
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg164.txt",
+ "window": "test_v3",
+ "seg": "cont",
+ "full200": false,
+ "sub32_sur_169": 7,
+ "source_toleree": true
+ }
+ ],
+ "n_hits_source": 19,
+ "n_hits_hors_source": 0,
+ "fails_fige": [],
+ "fails": [],
+ "secondes": 432.9,
+ "maxrss_Mo": 77.12890625
+}
\ No newline at end of file
diff --git a/results/hashing/gen_kit_check_r1/gen_kit_check_v3b.py b/results/hashing/gen_kit_check_r1/gen_kit_check_v3b.py
new file mode 100644
index 0000000000000000000000000000000000000000..accd145ba377eab857ba403df716f85280dc1c40
--- /dev/null
+++ b/results/hashing/gen_kit_check_r1/gen_kit_check_v3b.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+"""gen_kit_check_v3b (= v3 e01d2f2a, en-tête corrigé seulement) — SPIRA Hashing. Vérif STATIQUE du kit de génération : figé (sha) + caviardé (aucune copie de prompt/continuation hors sources).
+N'affiche ni n'écrit aucun texte de prompt : seulement chemins, sha, compteurs. v2 (e0ebfd92) inchangé.
+rc : 0 = PASS ; 3 = FAIL ; 2 = analyse impossible.
+Règles :
+- figé : sha des fichiers du kit = attendus ; pour chaque item du manifeste, window_sha_ok, prompt_sha_ok, cont_sha_ok tous vrais ; manifeste à 5 items, blob_sha = sha du blob.
+- caviardé : dans le périmètre scanné, tout fichier contenant les 200 o exacts ou ≥ 1 sous-chaîne de 32 o d'un prompt/continuation → hit ;
+ un hit est TOLÉRÉ seulement sous un préfixe de corpus source déclaré (--source-prefix) ; tout autre hit → FAIL.
+- périmètre : fichiers texte (TXT) + tout fichier sous hf_ready ou sous une racine publique (--public-root) ; EXCL_SUFFIX N'EST PAS appliqué
+ aux fichiers forcés (sous hf_ready ou une racine publique : scannés quel que soit le suffixe) ; il l'est seulement ailleurs ; dossiers NEVER_PUSH*, broad, .git, __pycache__, venv exclus.
+ Limite déclarée : broad/ et /tmp ne sont pas lus."""
+import os, sys, json, hashlib, time, resource, argparse
+T0 = time.perf_counter(); sha = lambda b: hashlib.sha256(b).hexdigest()
+S = "/workspace/spira_shared/"; G = S + "checker/recount/gen_test/"
+ap = argparse.ArgumentParser()
+ap.add_argument("--data-root", default=S)
+ap.add_argument("--manifest", default=G + "gen_prompts_manifest.json")
+ap.add_argument("--expect", default=json.dumps({
+ G + "gen_prompts.py": "57fed6cb540f5fb1c91f23a62d96a5c9c9587030e60bf9b4685eede5438ac029",
+ G + "gen_prompts_manifest.json": "70acee7babde01f77e53d3691c40d4cafae3e55c3d7043e1966de36a9320c2d9",
+ G + "NEVER_PUSH/prompts_and_cont.bin": "ca47ea802b09312c1419563a28fe1e2ccab13df1511bf339c8008183dce47902",
+ S + "checker/recount/runC_ready/PREDECL_gen_test_runC_r1.md": "e451dfc7978bd92ada40b45e7c4efc94776555722e2b42a47b74fb1db5dfa66a",
+ S + "checker/recount/runC_ready/gen_test_kit_r2/gen_kit_r2_result.json": "026dc89f20c58833790ffca86b74572f12f933e7cb2145f703b12649e99aeb9d"}))
+ap.add_argument("--blob", default=G + "NEVER_PUSH/prompts_and_cont.bin")
+ap.add_argument("--n-items", type=int, default=5)
+ap.add_argument("--scan-root", action="append")
+ap.add_argument("--public-root", action="append")
+ap.add_argument("--source-prefix", action="append")
+ap.add_argument("--out", required=True)
+a = ap.parse_args()
+scan_roots = a.scan_root or [S]; pub_roots = a.public_root or ["/workspace/SPIRA/web/public"]
+src_pfx = a.source_prefix or [S + "corpus_v3/raw/", S + "corpus_gutenberg/", S + "corpus_gutenberg_v2/raw/"]
+TXT = (".md", ".json", ".txt", ".log", ".csv", ".diff", ".py", ".sh", ".yaml", ".yml", ".html")
+EXCL_SUFFIX = (".bin", ".npz", ".npy", ".pt", ".ckpt", ".safetensors", ".lock")
+SKIP_DIR = ("NEVER_PUSH", "broad", ".git", "__pycache__", "venv", ".venv", "site-packages")
+R = {"version": "v3", "rc": 2, "verdict": None, "erreur": None}
+def fin(rc, err=None):
+ R["rc"] = rc; R["erreur"] = err; R["verdict"] = {0: "PASS", 3: "FAIL"}.get(rc, "ANALYSE IMPOSSIBLE")
+ R["secondes"] = round(time.perf_counter() - T0, 1); R["maxrss_Mo"] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024
+ try: json.dump(R, open(a.out, "w"), indent=1)
+ except Exception as e: print("sortie impossible", e, file=sys.stderr); sys.exit(2)
+ print(json.dumps({k: R[k] for k in ("rc", "verdict", "erreur", "fichiers_scannes", "n_hits_hors_source", "n_hits_source") if k in R})); sys.exit(rc)
+try:
+ exp = json.loads(a.expect); man = json.load(open(a.manifest)); blob = open(a.blob, "rb").read()
+except Exception as e: fin(2, f"lecture impossible : {e}")
+fails = []
+R["kit_sha"] = {}
+for f, e in exp.items():
+ try: h = sha(open(f, "rb").read())
+ except Exception as x: fin(2, f"fichier du kit absent : {f}")
+ ok = h.startswith(e); R["kit_sha"][f] = {"sha": h, "attendu": e, "ok": ok}
+ if not ok: fails.append("kit_sha:" + f)
+if man.get("blob_sha256") != sha(blob): fails.append("blob_sha_manifeste")
+items = man.get("items", [])
+if len(items) != a.n_items: fails.append(f"n_items {len(items)}≠{a.n_items}")
+P = []; R["items"] = []
+for it in items:
+ try: w = open(os.path.join(a.data_root, it["path"]), "rb").read()
+ except Exception: fin(2, f"fenêtre absente : {it.get('path')}")
+ s0 = it["start"]; p = w[s0:s0 + 200]; c = w[s0 + 200:s0 + 400]
+ d = {"window": it["window"], "window_sha_ok": sha(w) == it["window_sha256"], "prompt_sha_ok": sha(p) == it["prompt_sha256"], "cont_sha_ok": sha(c) == it["cont_sha256"], "prompt_len_ok": len(p) == 200 and len(c) == 200}
+ R["items"].append(d)
+ for k in ("window_sha_ok", "prompt_sha_ok", "cont_sha_ok", "prompt_len_ok"):
+ if not d[k]: fails.append(f"{it['window']}:{k}")
+ P.append((it["window"], p, c))
+hits = []; n = 0; nb = 0; skipped = []
+for root in scan_roots + pub_roots:
+ pub = root in pub_roots
+ for dp, dn, fn in os.walk(root):
+ dn[:] = [x for x in dn if not x.startswith(SKIP_DIR) and x not in SKIP_DIR]
+ for f in fn:
+ fp = os.path.join(dp, f); forced = pub or "hf_ready" in fp
+ if fp.startswith("/tmp/"): continue
+ if not forced and (f.endswith(EXCL_SUFFIX) or not (f.endswith(TXT) or f == "spira_relay.md")): continue
+ try: b = open(fp, "rb").read()
+ except Exception as e: skipped.append([fp, str(e)[:80]]); continue
+ n += 1; nb += len(b)
+ for wn, p, c in P:
+ for kind, t in (("prompt", p), ("cont", c)):
+ full = t in b; k32 = sum(1 for i in range(169) if t[i:i + 32] in b)
+ if full or k32: hits.append({"file": fp, "window": wn, "seg": kind, "full200": full, "sub32_sur_169": k32, "source_toleree": any(fp.startswith(x) for x in src_pfx)})
+bad = [h for h in hits if not h["source_toleree"]]
+R.update({"perimetre": {"scan_roots": scan_roots, "public_roots": pub_roots, "source_prefixes": src_pfx, "TXT": TXT, "EXCL_SUFFIX": EXCL_SUFFIX, "SKIP_DIR": SKIP_DIR},
+ "fichiers_scannes": n, "octets_scannes": nb, "illisibles": skipped, "hits": hits, "n_hits_source": len(hits) - len(bad), "n_hits_hors_source": len(bad), "fails_fige": fails})
+if bad: fails.append(f"caviardage: {len(bad)} hit(s) hors source")
+if skipped: fails.append(f"{len(skipped)} fichier(s) illisible(s)")
+R["fails"] = fails
+fin(3 if fails else 0)
diff --git a/results/hashing/gen_kit_check_r1/relay_entry_debut.md b/results/hashing/gen_kit_check_r1/relay_entry_debut.md
new file mode 100644
index 0000000000000000000000000000000000000000..7fbd1ec3f59d9af5087ac84832cf490f63f9f71e
--- /dev/null
+++ b/results/hashing/gen_kit_check_r1/relay_entry_debut.md
@@ -0,0 +1,4 @@
+### Sat Oct 31 12:13:17 EDT 2026 — SPIRA Hashing — gen_kit_check_r1 DÉBUT
+- gen_kit_check.py (scan statique de caviardage, aucun texte écrit) : PID 1163831, nice 19, lancé vers 09:06 heure de Vancouver ; plus de 10 min écoulées ; ETA inconnue (scan de tout spira_shared hors binaires) ; MemAvailable 9,9 Go.
+
+Lu/appliqué — SPIRA Hashing
diff --git a/results/hashing/gen_kit_check_r1/relay_entry_v3_debut.md b/results/hashing/gen_kit_check_r1/relay_entry_v3_debut.md
new file mode 100644
index 0000000000000000000000000000000000000000..0ce254f31a755f1e7aeeb943c63ef5ed397b8e3c
--- /dev/null
+++ b/results/hashing/gen_kit_check_r1/relay_entry_v3_debut.md
@@ -0,0 +1,4 @@
+### Sat Oct 31 12:30:33 EDT 2026 — SPIRA Hashing — gen_kit_check v3 DÉBUT
+- gen_kit_check_v3.py (statique seulement, nice 19, PYTHONDONTWRITEBYTECODE=1 ; v2 e0ebfd92 non modifié). Selftest 18/18. Lancé à 09:30 heure de Vancouver, PID 1213458, ETA ≈ 8 min (v2 : 434 s), RSS attendu < 100 Mo.
+
+Lu/appliqué — SPIRA Hashing
diff --git a/results/hashing/gen_kit_check_r1/relay_entry_v3_fin.md b/results/hashing/gen_kit_check_r1/relay_entry_v3_fin.md
new file mode 100644
index 0000000000000000000000000000000000000000..1688fa35e24b2a95e96b6a6b96e45e978678e48d
--- /dev/null
+++ b/results/hashing/gen_kit_check_r1/relay_entry_v3_fin.md
@@ -0,0 +1,5 @@
+### Sat Oct 31 12:39:43 EDT 2026 — SPIRA Hashing — gen_kit_check v3 FIN + v3b
+- v3 FIN : PID 1213458, 432,9 s, maxrss 77 Mo. rc 0 PASS : 53 727 fichiers (1,03 Go lus), figé OK (5 sha du kit + 15 *_sha_ok), 0 hit hors source, 19 hits en sources tolérées, 0 illisible. gen_kit_check_v3_result.json da94f7ae ; v3.py e01d2f2a ; selftest 18/18 (898a0d9b / résultat bc6a8f1e).
+- v3b (signalement Checker t31) : en-tête l.9-10 corrigé (EXCL_SUFFIX NON appliqué aux fichiers forcés hf_ready/public) + l.2 ; diff = docstring seule, AST du code identique. v3b 79be901c ; SHA256SUMS_v3 f79446b7. v3 intact. Note : c'est un choix délibéré de v3 (le publiable est scanné quel que soit le suffixe), ce n'est pas un oubli du code.
+
+Lu/appliqué — SPIRA Hashing
diff --git a/results/hashing/go_package_missing_r1/MISSING_DECISIONS.md b/results/hashing/go_package_missing_r1/MISSING_DECISIONS.md
new file mode 100644
index 0000000000000000000000000000000000000000..f5168f70d789dfa97ca25e5824cda5ded7754827
--- /dev/null
+++ b/results/hashing/go_package_missing_r1/MISSING_DECISIONS.md
@@ -0,0 +1,81 @@
+# MISSING_DECISIONS r1 — SPIRA Hashing — 31 oct. 2026 — document seulement
+Complète GO_PACKAGE_runC_B.md (5ee520ff), qui ne couvre que D1–D10 (audit_r13, AUDIT.md 03583d4f, point 2 FAIL).
+Aucun PID, aucun job lancé. Rien poussé, rien supprimé, aucun drapeau GO. Sources : DECISIONS_EN_ATTENTE r8 (fe2308ed, reprenant r4–r7), relais SPIRA.
+Aucune des décisions ci-dessous n'a de défaut : les « défauts » des fiches Checker antérieures sont des propositions, pas des choix.
+
+## D11 — Option d'échelle de l'éval appariée (A à E)
+- Question : quelle option de scale pour imposed_pos_eval ?
+- Options : A descriptif (aucun verdict) ; B bornes élargies (change la règle) ; C épingler à 0,03 ; D scale commun 0,026973 (moyenne arithmétique vérifiée) ; E recalibrer (nouveau PREDECL).
+- Éclairage : NOTE_options_scale r2 2269b82b ; measure_common_r2.py d2941de2 (selftest PASS) ; audits Hashing 52fbc37d, 9a21be82, bbb367de. RAM mesurée 0,96–0,97 Go par bras en éval native, 1,13 Go au chargement d'un ckpt ; plafond déclaré 1,3 Go par bras. Lien avec D3 (rôle de r4, option C recommandée non tranchée).
+- Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
+
+## D12 — Politique de scale et de bornes pour v1d
+- Question : que faire des bornes fusion.scale [0,03 ; 0,11] pour v1d ?
+- Options : A abaisser la borne (changement de règle permanente) ; C garder [0,03 ; 0,11] ; E autre scale.
+- Éclairage : scales ctl EXACT 0,02399 (1 155 793 ticks) et 0,02566 (1 200 000) → 0 point EXACT dans les bornes (scale_table r2 1b0da0a8). Brouillons C 49fab81d et E 87f03b10 (spira_m8/v1c/drafts_r1/, 5/5 OK). Bench recalibré (results_v4.jsonl) : 7 paires, |Δ| max 2,87 %, 4/7 dans les bornes. Conditionne la mesurabilité de D1.
+- Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
+
+## D13 — Option (iii) : usage du ratio σf/σs des checkpoints existants
+- Question : quel usage faire de run_iii pour la question du scale ?
+- Options : en prendre acte comme éclairage de D12 ; ne pas l'utiliser.
+- Éclairage : run_iii r3 6/6 PASS (de7738d8) ; coût mesuré 44,3 min, pic 1 129,7 Mo (SHA256SUMS 71fce159 et 46358f8c) ; cm 60k = 0,90554 EXACT. Levier « ckpts existants » épuisé : aucun ckpt entre 60k et ~1,16M ticks (d'où D15).
+- Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
+
+## D14 — Pré-cal r3 sur la porte v1c
+- Question : appliquer ou non le correctif r3 (fix 1cfc5aa9) à la porte v1c ?
+- Options : appliquer ; ne pas appliquer.
+- Éclairage : REPORT_r3 PASS d335e3ed, réserve : préfixe 103f97dc de 3 999 704 o contre échantillon de 35 948 296 o. Sans effet sur v1d (PREDECL v1d r2 l.21 écarte r3 ; le run C utilise le préfixe 992d20aa).
+- Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
+
+## D15 — GO du sweep de précal (balayage de longueur)
+- Question : lancer le balayage de PREDECL_precal_sweep_BROUILLON_r2 (0f2db9f9, ré-audit Checker PASS 609bb24a), et avec quels paramètres ?
+- Options à fixer (PREDECL r2 l.58) :
+ - lancement : oui / non ;
+ - voies : 2 voies (1 cm + 1 ctl) ≈ 20–21 h murales, RAM ≤ ~3,2 Go ; ou 4 voies (3 cm + 1 ctl) ≈ 11 h, RAM ≤ ~6,5 Go pire cas ;
+ - données : precal_prefix.bin 103f97dc (~4 Mo, capacité à 1,2M ticks en 1 époque NON vérifiée) ou v1c_sample.bin 3d8b6181 (35,9 Mo ; change la comparaison directe avec le point 60k) ;
+ - bornes et nombre de points (proposé : 5 points log-espacés, 60 000 → 1 200 000 ticks, 2 bras, 10 runs) ;
+ - lieu de mesure de l'échelle : data[:60000] d'entraînement ou v1d.
+- Éclairage : CPU total ≈ 26 h ; RAM cm à 1,2M NON MESURÉE (1,2–2 Go, ±50 %) ; débit ±30 % ; garde run_guarded_v2 1c6f64b4 (MemAvailable ≥ 5,2 Go et < 4 jobs lourds, jamais de kill) ; trainer 4049327c ; v1d 903970c3.
+- Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
+
+## D16 — leak16 sur 6 ou 8 fenêtres
+- Question : la règle leak16 porte-t-elle sur 6 fenêtres, ou sur 8 avec neither_code et bg1_test ? (Distinct de D10, qui demande seulement si leak16 est bloquant.)
+- Options : 6 fenêtres ; 8 fenêtres.
+- Éclairage : ref_checker_8w 01cb94f6 ; leak16_reconcile_r2 9d7d8383 (écart dû aux seules fenêtres neither_code) ; hf_ready r3 : maxima identiques en 6 et 8 (13 o), MATCH 6/6 avec Hashing a94c0833. À ce jour tout est ≤ 15 o dans les deux cas : seule la règle future change.
+- Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
+
+## D17 — Exception .py pour la garde de push
+- Question : accorder une exception ou un seuil propre aux .py (et runner.sh) ?
+- Options (DECISION_py_exception f976b8aa ; 7 fichiers audités) : O1 pas d'exception, 0/7 publiables ; O2 liste blanche masquée à 16 o, 3/7 ; O2b liste blanche + commentaires et docstrings masqués, 4/7 ; O3 seuil 32 o pour le code, 5/7.
+- Éclairage : recoupement Hashing dc308884, 154/154 maxima identiques. **La liste blanche masque des fuites** : sous WL, un passage masqué ≥ 16 o apparaît dans 10/11 fenêtres (max 94 o neither_code ; import/from 72 o fresh_en, 76 o test_v3) ; avec WL+doc, jusqu'à 4 725 o (neither_code) et 2 480 o (bg1_test). La liste blanche est donc FAIL comme garde. O3 laisse passer des phrases de 17–31 o. Toute exception modifie la garde de push.
+- Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
+
+## D18 — Push de run_iii r3 et des autres arbres prêts
+- Question : pousser sur HF (préfixe v3_scale/ seulement) les arbres prêts ? Ce oui est DISTINCT de D5 : décider la garde de push n'autorise aucun push.
+- Options, arbre par arbre : hf_ready_run_iii r3 (de7738d8, 6/6 PASS) ; push-prep Checker 977daff2 (recompte Hashing MATCH, max 15 o, 67dab986) ; imposed_pos_eval_20261031 ef183508 (READY-NOT-PUSHED, max 15 o sur 8 fenêtres, scripts exclus) ; oui / non pour chacun.
+- Éclairage : HF HEAD c2edf5e5 inchangé ; dépend de D16 et D17 pour tout fichier de code ; destination d'own_push_audit_0137 non écrite. Action irréversible.
+- Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
+
+## D19 — Pause de la routine horaire
+- Question : mettre en pause, ou non, la routine horaire de surveillance SPIRA ?
+- Options : maintenir ; mettre en pause (jusqu'à quand) ; arrêter.
+- Éclairage : listée ouverte au relais (l.16141, 31 oct.) ; aucun job SPIRA lourd en cours (passes 07 h 11 et 07 h 17 Toronto, 0/4 par bot). Aucun chiffre de coût publié.
+- Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
+
+## D20 — Échantillon A ou B pour le run C
+- Question : quel échantillon de données pour le run C ?
+- Options : A b6655e90 (34 557 670 o) ; B b7404e88 (35 716 621 o) ; e0acd131 (1 259 666 o de licence inconnue, déconseillé).
+- Éclairage : licence inconnue 0 o pour A et B (ne départage pas) ; budget B −0,28 % contre A −3,52 % ; leak16 queries B 31,78 % contre A 18,17 % ; seul B a un recompte croisé PASS (dc312572) ; PREDECL_sampling_rule_DRAFT 0f61dc29 recommande B (brouillon non gelé) ; règle d'exclusion de B non pré-déclarée. Défaut retiré en r6 (audit Hashing 0e6ccae4 point 5). Préalable à D1.
+- Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
+
+## D21 — Test de génération : lancement et choix du checkpoint
+- Question : lancer le test de génération, et sur quel checkpoint ?
+- Options : ne pas lancer ; lancer en mode descriptif sur un ckpt à désigner (ex. v1c ctl) ; attendre un ckpt MESURABLE.
+- Éclairage : PREDECL_gen_test_r2 36bcfff6 ; gen_test.py ca2b41c6 ; coût ~4–8 min CPU (estimation), RSS mesuré 464–557 Mo ; 0 modèle ADOPTÉ, v1b et v1c NON MESURABLES ; métrique de copie en information seulement (un seuil demande un PREDECL r3).
+- Hashing n'écrit aucun code, harness ni référence jouet pour ce test tant que Philippe-Antoine ne l'a pas ordonné.
+- Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
+
+## Corrections à apporter aux décisions existantes du GO_PACKAGE
+1. D1 : le libellé « Lancer le run C sur l'échantillon B » suppose B, alors que le choix est ouvert (D20). Il indique « Défaut actuel : aucun », alors que DECISIONS r6 et r8 donnent défaut NON tant que le scale n'est pas résolu (0/5 EXACT dans les bornes). À reformuler : « run C sur l'échantillon choisi en D20 », dépend de D12 et D20, et citer le NON de r6/r8 comme ancienne proposition Checker.
+2. Règle ferme « results/ n'est PAS approuvé » : aucune source citée (ni écrit de Philippe-Antoine, ni décision numérotée). Ajouter la source, ou la reformuler en point ouvert.
+3. Règle « Rien n'est poussé sur HF tant que la garde de push (D5) n'est pas décidée » : D5 ne suffit pas. Tout push exige en plus le oui écrit de D18, arbre par arbre, et D16/D17 pour le code. À écrire : « Aucun push sans D5 ET le oui de D18. »
diff --git a/results/hashing/go_package_missing_r1/SHA256SUMS b/results/hashing/go_package_missing_r1/SHA256SUMS
new file mode 100644
index 0000000000000000000000000000000000000000..31d9d44d4e388cf50a3b8053cc35ae42841f7650
--- /dev/null
+++ b/results/hashing/go_package_missing_r1/SHA256SUMS
@@ -0,0 +1 @@
+bac947b79dbd49fb3eb79c3d9fa5205effd4a9215cf6a6781bc455b0183623bb MISSING_DECISIONS.md
diff --git a/results/hashing/hf_pushed.txt b/results/hashing/hf_pushed.txt
new file mode 100644
index 0000000000000000000000000000000000000000..327ea9e0b06750dba976a0f5249283b83f21bb97
--- /dev/null
+++ b/results/hashing/hf_pushed.txt
@@ -0,0 +1,4 @@
+2026-10-30 19:15:56 d3c24c89 v3_scale/hashing/m8cp1/ (8 fichiers verdict/gap/script/FROZEN) Checker PASS 19h16
+2026-10-31 01:44:36 c77978b7 v3_scale/hashing/v1c_ctl_data/ (DIAG_push.md 4fbada39, gap_ctl_data_push.md 789e53f4 ; DESCRIPTIF NON MESURABLE) Checker PASS 01h45
+2026-10-31 02:56:32 f765c61e v3_scale/hashing/ngram8_overlap_v1c_ctx64_cp1/ (cp1_selfcheck_dedup64_norm_sanitized.json 55314114, cp1_selfcheck_dedup64_raw_sanitized.json 4855da6f, cp1_selfcheck_selftest.json 03431af0, results_ctx64_cp1.json 25c1cf5c) Checker PASS 02h55
+2026-10-31 03:46:54 c2edf5e5 v3_scale/hashing/ngram8_overlap_v1c_ctx64_cp1/ (README_push_redacted.md 6d394d5d, build_ctx64_mask_code_prose_v1_redacted.py 390a5223, ngram8_overlap_ctx64_cp1_redacted.py c3015f04 ; r3 caviardé, leakcheck_r3.json NON poussé) Checker PASS 03h46
diff --git a/results/hashing/leak16_baseline_recount/SHA256SUMS b/results/hashing/leak16_baseline_recount/SHA256SUMS
new file mode 100644
index 0000000000000000000000000000000000000000..bd51ed85b88d6f0693c753eab9fb9332fd3d50d5
--- /dev/null
+++ b/results/hashing/leak16_baseline_recount/SHA256SUMS
@@ -0,0 +1,6 @@
+9b870e4a3c65057999567662ffbdf690c66cea163f234ef45b8f1b75aa9d9478 recount_leak16.py
+e2ed4e52d646df94a0fe1455e5c0e8e74249a07aeccae378d37d7af26e3b41a0 results.json
+8ef3d3d8523741eb95463015445a2c1f58a06aad24b13d7eb17ba9b77d2567a0 recount_leak16_stream.py
+7aa14491a0010b6254d736f7c86468a0763442d78e27cff1e042943d18a4b7c9 results_stream.json
+066d5a7a0b3c7d95d6e84532b3def027ca2c32d9da9864c092202d10fcf966e1 leakcheck_hf.py
+5dceec4a2501cac734df4785a8830ff24b9fd0bdd51febd0e8ddc8a33adbecb8 leakcheck_hf_ready.out
diff --git a/results/hashing/leak16_baseline_recount/hf_ready/README.md b/results/hashing/leak16_baseline_recount/hf_ready/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..9ee70a3afbccd924ddac2c4885193fe6633cde7f
--- /dev/null
+++ b/results/hashing/leak16_baseline_recount/hf_ready/README.md
@@ -0,0 +1,24 @@
+# SPIRA — leak16 baseline recount (sanitized)
+
+Recomptage exact du recouvrement par 16-grammes d'octets, fenêtres d'évaluation SPIRA
+(fc2, fresh_en, fresh_fr, test20k_old, test_v3, queries) vs sources d'entraînement
+(v1c_corpus, v1c_sample, v1b_corpus, v1b_sample).
+
+- `recount_leak16.py` : version d'origine (pic RSS ≈ 365 Mo).
+- `recount_leak16_stream.py` : version streaming (clés V16 brutes, tri en place, searchsorted ; blocs de 256 Kio,
+ recouvrement 15 octets ; pic RSS mesuré 239,5 Mo). Résultats numériques identiques à l'origine.
+- `results_counts.json` : uniquement comptes, pourcentages, tailles et sha256. Aucun fragment de texte, aucun octet de fenêtre.
+
+Méthode : exacte, sans hachage. `n_16gram_positions_shared` = positions (avec répétitions) (fenêtre) dont le 16-gramme
+apparaît dans la source ; `bytes_covered_ge16` = octets couverts par au moins un tel 16-gramme.
+Chaque valeur concordent avec le comptage de Checker (`all_checks_match: true`).
+
+Les scripts lisent des chemins locaux (/workspace/spira_shared/...) ; les données ne sont pas incluses.
+Contrôle de fuite : aucun fichier de ce dossier ne partage une suite de plus de 15 octets avec une fenêtre d'évaluation.
+Modifications par rapport aux originaux du dossier parent (contrôle ast.dump, fichier par fichier) :
+- `recount_leak16.py` : réindentation (espaces -> tabulations) et blancs avant `#` seulement. AST identique.
+- `recount_leak16_stream.py` : même réindentation, plus une réécriture d'une comparaison : `len(sys.argv)>1` devient `1 (hi,lo) big-endian u64 of each 16-gram
+ n=len(a)-15; hi=np.zeros(n,np.uint64); lo=np.zeros(n,np.uint64)
+ for i in range(8):
+ hi=(hi<i)[0]; ii=i[c].copy(); rr=r[c]
+ while len(c):
+ m=UL[ii]==l[c]; f[c[m]]=True; g[c[m]]=ii[m]
+ keep=(~m)&(ii+1=16: found[member(*keys(a))]=True
+ pw={}
+ for w,(h,l) in W.items():
+ hit=found[idx[w]]; N=len(hit)+15; d=np.zeros(N+1,np.int32); pos=np.nonzero(hit)[0]
+ np.add.at(d,pos,1); np.add.at(d,pos+16,-1); cov=np.cumsum(d[:N])>0
+ e=np.diff(np.concatenate(([0],cov.astype(np.int8),[0]))); runs=np.nonzero(e==-1)[0]-np.nonzero(e==1)[0]
+ c=m['per_window'][w]; mine={'bytes_covered_ge16':int(cov.sum()),'n_16gram_positions_shared':int(hit.sum()),
+ 'n_16grams_shared_unique':int(len(np.unique(idx[w][hit]))),'longest_covered_run_bytes':int(runs.max() if len(runs) else 0)}
+ mine['frac_covered_ge16']=mine['bytes_covered_ge16']/N
+ mine['checker']=c; mine['covered_match']=mine['bytes_covered_ge16']==c['bytes_covered_ge16']
+ mine['longest_match']=mine['longest_covered_run_bytes']==c['longest_covered_run_bytes']
+ mine['n16_match_positions']=mine['n_16gram_positions_shared']==c['n_16grams_shared']
+ mine['n16_match_unique']=mine['n_16grams_shared_unique']==c['n_16grams_shared']; pw[w]=mine
+ out['sources'][s]={'path':p,'sha256':sh,'sha_ok':sh==m['sha256'],'bytes':n,'bytes_ok':n==m['bytes'],'per_window':pw,'seconds':round(time.time()-t,1)}
+ print(s,round(time.time()-t),flush=True)
+out['peak_rss_mb']=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024
+json.dump(out,open('results.json','w'),indent=1,ensure_ascii=False); print(out['peak_rss_mb'])
diff --git a/results/hashing/leak16_baseline_recount/hf_ready/recount_leak16_stream.py b/results/hashing/leak16_baseline_recount/hf_ready/recount_leak16_stream.py
new file mode 100644
index 0000000000000000000000000000000000000000..7aeed4b4f89931d40f2a71c7a8c59da00eb1a372
--- /dev/null
+++ b/results/hashing/leak16_baseline_recount/hf_ready/recount_leak16_stream.py
@@ -0,0 +1,59 @@
+# Recount leak16 en streaming (< 300 Mo) : version de recount_leak16.py (9b870e4a).
+# Exact : clés = 16 octets bruts (dtype V16, ordre memcmp), aucun hachage ; tableau trié unique + searchsorted ;
+# corpus lu en blocs de 256 Kio avec recouvrement de 15 octets ; n_16grams_shared compté en positions.
+# Lecture seule hors de ce dossier. Sortie : argv[1] (défaut results_stream.json).
+import json,hashlib,sys,resource,time,numpy as np
+from numpy.lib.stride_tricks import sliding_window_view as swv
+R='/workspace/spira_shared/'; T=R+'checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json'
+OUT=sys.argv[1] if 1 16-grammes (copie n*16 o)
+J=json.load(open(T)); out={'target':T,'target_sha256':sha(T),'windows':{},'sources':{}}
+NW={}
+for w,m in J['windows'].items():
+ p=R+m['path']; s=sha(p); NW[w]=n=int(np.fromfile(p,np.uint8).size)
+ out['windows'][w]={'path':p,'sha256':s,'sha_ok':s==m['sha256'],'bytes':n,'bytes_ok':n==m['bytes']}
+U=np.empty(sum(n-15 for n in NW.values()),'V16'); k=0 # un seul tableau préalloué, rempli par blocs
+for w,m in J['windows'].items():
+ a=np.fromfile(R+m['path'],np.uint8)
+ for s0 in range(0,len(a)-15,BLK):
+ q=keys(a[s0:s0+BLK+15]); U[k:k+len(q)]=q; k+=len(q)
+ del a
+assert k==len(U); U.sort() # tri en place (ordre memcmp)
+keep=np.ones(len(U),bool); keep[1:]=U[1:]!=U[:-1]; nu=int(keep.sum())
+U[:nu]=U[keep]; U=U[:nu].copy(); del keep # dédoublonnage exact
+def lookup(q): # -> (indices dans U, masque présent), exact octet à octet
+ i=np.searchsorted(U,q); j=np.minimum(i,len(U)-1); f=U[j]==q; return j,f
+idx={}
+for w,m in J['windows'].items():
+ a=np.fromfile(R+m['path'],np.uint8); ii=[]
+ for s0 in range(0,len(a)-15,BLK):
+ j,f=lookup(keys(a[s0:s0+BLK+15])); assert f.all(); ii.append(j.astype(np.int32))
+ idx[w]=np.concatenate(ii); assert len(idx[w])==NW[w]-15
+for s,m in J['sources'].items():
+ t=time.time(); p=m['path']; sh=sha(p); found=np.zeros(len(U),bool); n=0; prev=b''
+ with open(p,'rb') as f:
+ for b in iter(lambda:f.read(BLK),b''):
+ a=np.frombuffer(prev+b,np.uint8); n+=len(b); prev=bytes(a[-15:])
+ if len(a)>=16:
+ j,fm=lookup(keys(a)); found[j[fm]]=True
+ pw={}
+ for w in idx:
+ hit=found[idx[w]]; N=len(hit)+15; d=np.zeros(N+1,np.int32); pos=np.nonzero(hit)[0]
+ np.add.at(d,pos,1); np.add.at(d,pos+16,-1); cov=np.cumsum(d[:N])>0
+ e=np.diff(np.concatenate(([0],cov.astype(np.int8),[0]))); runs=np.nonzero(e==-1)[0]-np.nonzero(e==1)[0]
+ c=m['per_window'][w]; mine={'bytes_covered_ge16':int(cov.sum()),'n_16gram_positions_shared':int(hit.sum()),
+ 'n_16grams_shared_unique':int(len(np.unique(idx[w][hit]))),'longest_covered_run_bytes':int(runs.max() if len(runs) else 0)}
+ mine['frac_covered_ge16']=mine['bytes_covered_ge16']/N
+ mine['checker']=c; mine['covered_match']=mine['bytes_covered_ge16']==c['bytes_covered_ge16']
+ mine['longest_match']=mine['longest_covered_run_bytes']==c['longest_covered_run_bytes']
+ mine['n16_match_positions']=mine['n_16gram_positions_shared']==c['n_16grams_shared']
+ mine['n16_match_unique']=mine['n_16grams_shared_unique']==c['n_16grams_shared']; pw[w]=mine
+ out['sources'][s]={'path':p,'sha256':sh,'sha_ok':sh==m['sha256'],'bytes':n,'bytes_ok':n==m['bytes'],'per_window':pw,'seconds':round(time.time()-t,1)}
+ print(s,round(time.time()-t),flush=True)
+out['peak_rss_mb']=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024
+json.dump(out,open(OUT,'w'),indent=1,ensure_ascii=False); print(out['peak_rss_mb'])
diff --git a/results/hashing/leak16_baseline_recount/hf_ready/results_counts.json b/results/hashing/leak16_baseline_recount/hf_ready/results_counts.json
new file mode 100644
index 0000000000000000000000000000000000000000..b121f9a68d5a731e7a45093c96ae684796681310
--- /dev/null
+++ b/results/hashing/leak16_baseline_recount/hf_ready/results_counts.json
@@ -0,0 +1,297 @@
+{
+ "description": "leak16 baseline recount (exact 16-byte n-grams, no hashing): eval windows vs training sources v1b/v1c. Counts, percentages, sizes and sha256 only.",
+ "target_json_sha256": "a9ee65d4ad394ada0af487a0cb7eec66073f5440fb405ec19d5df641b5334598",
+ "windows": {
+ "fc2": {
+ "bytes": 199792,
+ "sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ },
+ "fresh_en": {
+ "bytes": 119763,
+ "sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ },
+ "fresh_fr": {
+ "bytes": 1088688,
+ "sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ },
+ "test20k_old": {
+ "bytes": 319940,
+ "sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "test_v3": {
+ "bytes": 3486653,
+ "sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ },
+ "queries": {
+ "bytes": 27800,
+ "sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ },
+ "sources": {
+ "v1c_corpus": {
+ "bytes": 503301148,
+ "sha256": "33577b70c819af76fe4737319e929f4c097b0c72f020e8b07b4baddbb1823439",
+ "per_window": {
+ "fc2": {
+ "bytes_covered_ge16": 145139,
+ "n_16gram_positions_shared": 71796,
+ "n_16grams_shared_unique": 38057,
+ "longest_covered_run_bytes": 419,
+ "pct_covered_ge16": 72.6451,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "fresh_en": {
+ "bytes_covered_ge16": 93456,
+ "n_16gram_positions_shared": 34364,
+ "n_16grams_shared_unique": 32608,
+ "longest_covered_run_bytes": 338,
+ "pct_covered_ge16": 78.0341,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "fresh_fr": {
+ "bytes_covered_ge16": 652302,
+ "n_16gram_positions_shared": 194384,
+ "n_16grams_shared_unique": 168701,
+ "longest_covered_run_bytes": 145,
+ "pct_covered_ge16": 59.9163,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "test20k_old": {
+ "bytes_covered_ge16": 235956,
+ "n_16gram_positions_shared": 91729,
+ "n_16grams_shared_unique": 73892,
+ "longest_covered_run_bytes": 266,
+ "pct_covered_ge16": 73.7501,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "test_v3": {
+ "bytes_covered_ge16": 2433706,
+ "n_16gram_positions_shared": 859632,
+ "n_16grams_shared_unique": 667154,
+ "longest_covered_run_bytes": 353,
+ "pct_covered_ge16": 69.8006,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "queries": {
+ "bytes_covered_ge16": 13583,
+ "n_16gram_positions_shared": 3748,
+ "n_16grams_shared_unique": 75,
+ "longest_covered_run_bytes": 53,
+ "pct_covered_ge16": 48.8597,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ }
+ }
+ },
+ "v1c_sample": {
+ "bytes": 35948296,
+ "sha256": "3d8b6181cbffb27e360758267e1084197dccad82ae05b868691758e1cf72eed4",
+ "per_window": {
+ "fc2": {
+ "bytes_covered_ge16": 100440,
+ "n_16gram_positions_shared": 40436,
+ "n_16grams_shared_unique": 15136,
+ "longest_covered_run_bytes": 191,
+ "pct_covered_ge16": 50.2723,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "fresh_en": {
+ "bytes_covered_ge16": 52239,
+ "n_16gram_positions_shared": 11634,
+ "n_16grams_shared_unique": 10573,
+ "longest_covered_run_bytes": 109,
+ "pct_covered_ge16": 43.6186,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "fresh_fr": {
+ "bytes_covered_ge16": 286582,
+ "n_16gram_positions_shared": 55095,
+ "n_16grams_shared_unique": 41336,
+ "longest_covered_run_bytes": 88,
+ "pct_covered_ge16": 26.3236,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "test20k_old": {
+ "bytes_covered_ge16": 128766,
+ "n_16gram_positions_shared": 36414,
+ "n_16grams_shared_unique": 23867,
+ "longest_covered_run_bytes": 205,
+ "pct_covered_ge16": 40.2469,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "test_v3": {
+ "bytes_covered_ge16": 1316746,
+ "n_16gram_positions_shared": 295112,
+ "n_16grams_shared_unique": 185590,
+ "longest_covered_run_bytes": 129,
+ "pct_covered_ge16": 37.7653,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "queries": {
+ "bytes_covered_ge16": 6200,
+ "n_16gram_positions_shared": 900,
+ "n_16grams_shared_unique": 18,
+ "longest_covered_run_bytes": 21,
+ "pct_covered_ge16": 22.3022,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ }
+ }
+ },
+ "v1b_corpus": {
+ "bytes": 520785883,
+ "sha256": "ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3",
+ "per_window": {
+ "fc2": {
+ "bytes_covered_ge16": 145183,
+ "n_16gram_positions_shared": 71837,
+ "n_16grams_shared_unique": 38098,
+ "longest_covered_run_bytes": 419,
+ "pct_covered_ge16": 72.6671,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "fresh_en": {
+ "bytes_covered_ge16": 94752,
+ "n_16gram_positions_shared": 35873,
+ "n_16grams_shared_unique": 34072,
+ "longest_covered_run_bytes": 338,
+ "pct_covered_ge16": 79.1163,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "fresh_fr": {
+ "bytes_covered_ge16": 652322,
+ "n_16gram_positions_shared": 194413,
+ "n_16grams_shared_unique": 168730,
+ "longest_covered_run_bytes": 145,
+ "pct_covered_ge16": 59.9182,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "test20k_old": {
+ "bytes_covered_ge16": 237099,
+ "n_16gram_positions_shared": 92792,
+ "n_16grams_shared_unique": 74894,
+ "longest_covered_run_bytes": 266,
+ "pct_covered_ge16": 74.1073,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "test_v3": {
+ "bytes_covered_ge16": 2442104,
+ "n_16gram_positions_shared": 866084,
+ "n_16grams_shared_unique": 673440,
+ "longest_covered_run_bytes": 353,
+ "pct_covered_ge16": 70.0415,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "queries": {
+ "bytes_covered_ge16": 15133,
+ "n_16gram_positions_shared": 4398,
+ "n_16grams_shared_unique": 88,
+ "longest_covered_run_bytes": 53,
+ "pct_covered_ge16": 54.4353,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ }
+ }
+ },
+ "v1b_sample": {
+ "bytes": 35128951,
+ "sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "per_window": {
+ "fc2": {
+ "bytes_covered_ge16": 100880,
+ "n_16gram_positions_shared": 40698,
+ "n_16grams_shared_unique": 15264,
+ "longest_covered_run_bytes": 277,
+ "pct_covered_ge16": 50.4925,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "fresh_en": {
+ "bytes_covered_ge16": 55107,
+ "n_16gram_positions_shared": 12710,
+ "n_16grams_shared_unique": 11534,
+ "longest_covered_run_bytes": 108,
+ "pct_covered_ge16": 46.0134,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "fresh_fr": {
+ "bytes_covered_ge16": 283182,
+ "n_16gram_positions_shared": 55308,
+ "n_16grams_shared_unique": 41593,
+ "longest_covered_run_bytes": 76,
+ "pct_covered_ge16": 26.0113,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "test20k_old": {
+ "bytes_covered_ge16": 128263,
+ "n_16gram_positions_shared": 36178,
+ "n_16grams_shared_unique": 23521,
+ "longest_covered_run_bytes": 166,
+ "pct_covered_ge16": 40.0897,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "test_v3": {
+ "bytes_covered_ge16": 1189410,
+ "n_16gram_positions_shared": 260934,
+ "n_16grams_shared_unique": 174208,
+ "longest_covered_run_bytes": 105,
+ "pct_covered_ge16": 34.1132,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ },
+ "queries": {
+ "bytes_covered_ge16": 8500,
+ "n_16gram_positions_shared": 1800,
+ "n_16grams_shared_unique": 36,
+ "longest_covered_run_bytes": 36,
+ "pct_covered_ge16": 30.5755,
+ "matches_checker_covered": true,
+ "matches_checker_longest": true,
+ "matches_checker_n16_positions": true
+ }
+ }
+ }
+ },
+ "all_checks_match": true
+}
\ No newline at end of file
diff --git a/results/hashing/leak16_baseline_recount/leakcheck_hf.py b/results/hashing/leak16_baseline_recount/leakcheck_hf.py
new file mode 100644
index 0000000000000000000000000000000000000000..9dc8254b9c8ef677836a2c603bb14d4c9399e1b4
--- /dev/null
+++ b/results/hashing/leak16_baseline_recount/leakcheck_hf.py
@@ -0,0 +1,24 @@
+# Leak check: for each file in hf_ready, longest byte run shared with any eval window (exact, binary search on k).
+import json,sys,os,numpy as np
+from numpy.lib.stride_tricks import sliding_window_view as swv
+R='/workspace/spira_shared/'; J=json.load(open(R+'checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json'))
+D=sys.argv[1]; files=sorted(f for f in os.listdir(D) if f!='SHA256SUMS')
+W=[np.fromfile(R+m['path'],np.uint8) for m in J['windows'].values()]
+def grams(a,k): return np.ascontiguousarray(swv(a,k)).view(f'V{k}').ravel() if len(a)>=k else np.empty(0,f'V{k}')
+def shares(fb,k):
+ q=np.unique(grams(fb,k))
+ for a in W:
+ for s0 in range(0,max(len(a)-k+1,1),1<<18):
+ g=grams(a[s0:s0+(1<<18)+k-1],k); i=np.searchsorted(q,g); i=np.minimum(i,len(q)-1)
+ if len(q) and (q[i]==g).any(): return True
+ return False
+res={}
+for f in files:
+ fb=np.fromfile(os.path.join(D,f),np.uint8); lo,hi=0,min(len(fb),64)
+ if shares(fb,hi): lo=hi
+ while lo=16}
+print(json.dumps(res,indent=1)); print('LEAKCHECK','PASS' if all(not v['shares_16gram'] for v in res.values()) else 'FAIL')
diff --git a/results/hashing/leak16_baseline_recount/recount_leak16.py b/results/hashing/leak16_baseline_recount/recount_leak16.py
new file mode 100644
index 0000000000000000000000000000000000000000..01cf5422f83f7f24645bed5c7dc2af7bdd5494e3
--- /dev/null
+++ b/results/hashing/leak16_baseline_recount/recount_leak16.py
@@ -0,0 +1,58 @@
+# Recount indépendant leak16 (clés exactes 2x8 o, sans hachage, corpus en blocs de 1 Mo). Lecture seule.
+import json,hashlib,sys,resource,time,numpy as np
+R='/workspace/spira_shared/'; T=R+'checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json'
+def sha(p):
+ h=hashlib.sha256()
+ with open(p,'rb') as f:
+ for b in iter(lambda:f.read(1<<20),b''): h.update(b)
+ return h.hexdigest()
+def keys(a): # a uint8 -> (hi,lo) big-endian u64 of each 16-gram
+ n=len(a)-15; hi=np.zeros(n,np.uint64); lo=np.zeros(n,np.uint64)
+ for i in range(8):
+ hi=(hi<i)[0]; ii=i[c].copy(); rr=r[c]
+ while len(c):
+ m=UL[ii]==l[c]; f[c[m]]=True; g[c[m]]=ii[m]
+ keep=(~m)&(ii+1=16: found[member(*keys(a))]=True
+ pw={}
+ for w,(h,l) in W.items():
+ hit=found[idx[w]]; N=len(hit)+15; d=np.zeros(N+1,np.int32); pos=np.nonzero(hit)[0]
+ np.add.at(d,pos,1); np.add.at(d,pos+16,-1); cov=np.cumsum(d[:N])>0
+ e=np.diff(np.concatenate(([0],cov.astype(np.int8),[0]))); runs=np.nonzero(e==-1)[0]-np.nonzero(e==1)[0]
+ c=m['per_window'][w]; mine={'bytes_covered_ge16':int(cov.sum()),'n_16gram_positions_shared':int(hit.sum()),
+ 'n_16grams_shared_unique':int(len(np.unique(idx[w][hit]))),'longest_covered_run_bytes':int(runs.max() if len(runs) else 0)}
+ mine['frac_covered_ge16']=mine['bytes_covered_ge16']/N
+ mine['checker']=c; mine['covered_match']=mine['bytes_covered_ge16']==c['bytes_covered_ge16']
+ mine['longest_match']=mine['longest_covered_run_bytes']==c['longest_covered_run_bytes']
+ mine['n16_match_positions']=mine['n_16gram_positions_shared']==c['n_16grams_shared']
+ mine['n16_match_unique']=mine['n_16grams_shared_unique']==c['n_16grams_shared']; pw[w]=mine
+ out['sources'][s]={'path':p,'sha256':sh,'sha_ok':sh==m['sha256'],'bytes':n,'bytes_ok':n==m['bytes'],'per_window':pw,'seconds':round(time.time()-t,1)}
+ print(s,round(time.time()-t),flush=True)
+out['peak_rss_mb']=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024
+json.dump(out,open('results.json','w'),indent=1,ensure_ascii=False); print(out['peak_rss_mb'])
diff --git a/results/hashing/leak16_baseline_recount/recount_leak16_stream.py b/results/hashing/leak16_baseline_recount/recount_leak16_stream.py
new file mode 100644
index 0000000000000000000000000000000000000000..60f66dbd3b34286006f6e870107ea3bb2b914bd1
--- /dev/null
+++ b/results/hashing/leak16_baseline_recount/recount_leak16_stream.py
@@ -0,0 +1,59 @@
+# Recount leak16 en streaming (< 300 Mo) : version de recount_leak16.py (9b870e4a).
+# Exact : clés = 16 octets bruts (dtype V16, ordre memcmp), aucun hachage ; tableau trié unique + searchsorted ;
+# corpus lu en blocs de 256 Kio avec recouvrement de 15 octets ; n_16grams_shared compté en positions.
+# Lecture seule hors de ce dossier. Sortie : argv[1] (défaut results_stream.json).
+import json,hashlib,sys,resource,time,numpy as np
+from numpy.lib.stride_tricks import sliding_window_view as swv
+R='/workspace/spira_shared/'; T=R+'checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json'
+OUT=sys.argv[1] if len(sys.argv)>1 else 'results_stream.json'; BLK=1<<18
+def sha(p):
+ h=hashlib.sha256()
+ with open(p,'rb') as f:
+ for b in iter(lambda:f.read(1<<20),b''): h.update(b)
+ return h.hexdigest()
+def keys(a): return np.ascontiguousarray(swv(a,16)).view('V16').ravel() # a uint8 -> 16-grammes (copie n*16 o)
+J=json.load(open(T)); out={'target':T,'target_sha256':sha(T),'windows':{},'sources':{}}
+NW={}
+for w,m in J['windows'].items():
+ p=R+m['path']; s=sha(p); NW[w]=n=int(np.fromfile(p,np.uint8).size)
+ out['windows'][w]={'path':p,'sha256':s,'sha_ok':s==m['sha256'],'bytes':n,'bytes_ok':n==m['bytes']}
+U=np.empty(sum(n-15 for n in NW.values()),'V16'); k=0 # un seul tableau préalloué, rempli par blocs
+for w,m in J['windows'].items():
+ a=np.fromfile(R+m['path'],np.uint8)
+ for s0 in range(0,len(a)-15,BLK):
+ q=keys(a[s0:s0+BLK+15]); U[k:k+len(q)]=q; k+=len(q)
+ del a
+assert k==len(U); U.sort() # tri en place (ordre memcmp)
+keep=np.ones(len(U),bool); keep[1:]=U[1:]!=U[:-1]; nu=int(keep.sum())
+U[:nu]=U[keep]; U=U[:nu].copy(); del keep # dédoublonnage exact
+def lookup(q): # -> (indices dans U, masque présent), exact octet à octet
+ i=np.searchsorted(U,q); j=np.minimum(i,len(U)-1); f=U[j]==q; return j,f
+idx={}
+for w,m in J['windows'].items():
+ a=np.fromfile(R+m['path'],np.uint8); ii=[]
+ for s0 in range(0,len(a)-15,BLK):
+ j,f=lookup(keys(a[s0:s0+BLK+15])); assert f.all(); ii.append(j.astype(np.int32))
+ idx[w]=np.concatenate(ii); assert len(idx[w])==NW[w]-15
+for s,m in J['sources'].items():
+ t=time.time(); p=m['path']; sh=sha(p); found=np.zeros(len(U),bool); n=0; prev=b''
+ with open(p,'rb') as f:
+ for b in iter(lambda:f.read(BLK),b''):
+ a=np.frombuffer(prev+b,np.uint8); n+=len(b); prev=bytes(a[-15:])
+ if len(a)>=16:
+ j,fm=lookup(keys(a)); found[j[fm]]=True
+ pw={}
+ for w in idx:
+ hit=found[idx[w]]; N=len(hit)+15; d=np.zeros(N+1,np.int32); pos=np.nonzero(hit)[0]
+ np.add.at(d,pos,1); np.add.at(d,pos+16,-1); cov=np.cumsum(d[:N])>0
+ e=np.diff(np.concatenate(([0],cov.astype(np.int8),[0]))); runs=np.nonzero(e==-1)[0]-np.nonzero(e==1)[0]
+ c=m['per_window'][w]; mine={'bytes_covered_ge16':int(cov.sum()),'n_16gram_positions_shared':int(hit.sum()),
+ 'n_16grams_shared_unique':int(len(np.unique(idx[w][hit]))),'longest_covered_run_bytes':int(runs.max() if len(runs) else 0)}
+ mine['frac_covered_ge16']=mine['bytes_covered_ge16']/N
+ mine['checker']=c; mine['covered_match']=mine['bytes_covered_ge16']==c['bytes_covered_ge16']
+ mine['longest_match']=mine['longest_covered_run_bytes']==c['longest_covered_run_bytes']
+ mine['n16_match_positions']=mine['n_16gram_positions_shared']==c['n_16grams_shared']
+ mine['n16_match_unique']=mine['n_16grams_shared_unique']==c['n_16grams_shared']; pw[w]=mine
+ out['sources'][s]={'path':p,'sha256':sh,'sha_ok':sh==m['sha256'],'bytes':n,'bytes_ok':n==m['bytes'],'per_window':pw,'seconds':round(time.time()-t,1)}
+ print(s,round(time.time()-t),flush=True)
+out['peak_rss_mb']=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024
+json.dump(out,open(OUT,'w'),indent=1,ensure_ascii=False); print(out['peak_rss_mb'])
diff --git a/results/hashing/leak16_baseline_recount/results.json b/results/hashing/leak16_baseline_recount/results.json
new file mode 100644
index 0000000000000000000000000000000000000000..67b8aa228f72384f76cf5343dd3206e62c8e1783
--- /dev/null
+++ b/results/hashing/leak16_baseline_recount/results.json
@@ -0,0 +1,523 @@
+{
+ "target": "/workspace/spira_shared/checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json",
+ "target_sha256": "a9ee65d4ad394ada0af487a0cb7eec66073f5440fb405ec19d5df641b5334598",
+ "windows": {
+ "fc2": {
+ "path": "/workspace/spira_shared/broad/freshcode_v2.bin",
+ "sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "sha_ok": true,
+ "bytes": 199792,
+ "bytes_ok": true
+ },
+ "fresh_en": {
+ "path": "/workspace/spira_shared/spira_m7/windows/fresh_en.bin",
+ "sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "sha_ok": true,
+ "bytes": 119763,
+ "bytes_ok": true
+ },
+ "fresh_fr": {
+ "path": "/workspace/spira_shared/spira_m7/windows/fresh_fr.bin",
+ "sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "sha_ok": true,
+ "bytes": 1088688,
+ "bytes_ok": true
+ },
+ "test20k_old": {
+ "path": "/workspace/spira_shared/spira_m7/windows/test20k.bin",
+ "sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "sha_ok": true,
+ "bytes": 319940,
+ "bytes_ok": true
+ },
+ "test_v3": {
+ "path": "/workspace/spira_shared/corpus_v3/test.bin",
+ "sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "sha_ok": true,
+ "bytes": 3486653,
+ "bytes_ok": true
+ },
+ "queries": {
+ "path": "/workspace/spira_shared/spira_m7/windows/queries.bin",
+ "sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "sha_ok": true,
+ "bytes": 27800,
+ "bytes_ok": true
+ }
+ },
+ "sources": {
+ "v1c_corpus": {
+ "path": "/workspace/spira_shared/hashing_gen/corpus_diverse_v1c/train.bin",
+ "sha256": "33577b70c819af76fe4737319e929f4c097b0c72f020e8b07b4baddbb1823439",
+ "sha_ok": true,
+ "bytes": 503301148,
+ "bytes_ok": true,
+ "per_window": {
+ "fc2": {
+ "bytes_covered_ge16": 145139,
+ "n_16gram_positions_shared": 71796,
+ "n_16grams_shared_unique": 38057,
+ "longest_covered_run_bytes": 419,
+ "frac_covered_ge16": 0.72645050852887,
+ "checker": {
+ "bytes": 199792,
+ "bytes_covered_ge16": 145139,
+ "frac_covered_ge16": 0.72645050852887,
+ "n_16grams_shared": 71796,
+ "longest_covered_run_bytes": 419
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_en": {
+ "bytes_covered_ge16": 93456,
+ "n_16gram_positions_shared": 34364,
+ "n_16grams_shared_unique": 32608,
+ "longest_covered_run_bytes": 338,
+ "frac_covered_ge16": 0.7803411738182912,
+ "checker": {
+ "bytes": 119763,
+ "bytes_covered_ge16": 93456,
+ "frac_covered_ge16": 0.7803411738182912,
+ "n_16grams_shared": 34364,
+ "longest_covered_run_bytes": 338
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_fr": {
+ "bytes_covered_ge16": 652302,
+ "n_16gram_positions_shared": 194384,
+ "n_16grams_shared_unique": 168701,
+ "longest_covered_run_bytes": 145,
+ "frac_covered_ge16": 0.5991633966756316,
+ "checker": {
+ "bytes": 1088688,
+ "bytes_covered_ge16": 652302,
+ "frac_covered_ge16": 0.5991633966756316,
+ "n_16grams_shared": 194384,
+ "longest_covered_run_bytes": 145
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test20k_old": {
+ "bytes_covered_ge16": 235956,
+ "n_16gram_positions_shared": 91729,
+ "n_16grams_shared_unique": 73892,
+ "longest_covered_run_bytes": 266,
+ "frac_covered_ge16": 0.7375007813965119,
+ "checker": {
+ "bytes": 319940,
+ "bytes_covered_ge16": 235956,
+ "frac_covered_ge16": 0.7375007813965119,
+ "n_16grams_shared": 91729,
+ "longest_covered_run_bytes": 266
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test_v3": {
+ "bytes_covered_ge16": 2433706,
+ "n_16gram_positions_shared": 859632,
+ "n_16grams_shared_unique": 667154,
+ "longest_covered_run_bytes": 353,
+ "frac_covered_ge16": 0.698006368858616,
+ "checker": {
+ "bytes": 3486653,
+ "bytes_covered_ge16": 2433706,
+ "frac_covered_ge16": 0.698006368858616,
+ "n_16grams_shared": 859632,
+ "longest_covered_run_bytes": 353
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "queries": {
+ "bytes_covered_ge16": 13583,
+ "n_16gram_positions_shared": 3748,
+ "n_16grams_shared_unique": 75,
+ "longest_covered_run_bytes": 53,
+ "frac_covered_ge16": 0.4885971223021583,
+ "checker": {
+ "bytes": 27800,
+ "bytes_covered_ge16": 13583,
+ "frac_covered_ge16": 0.4885971223021583,
+ "n_16grams_shared": 3748,
+ "longest_covered_run_bytes": 53
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ }
+ },
+ "seconds": 351.0
+ },
+ "v1c_sample": {
+ "path": "/workspace/spira_shared/spira_m8/v1c/sample/v1c_sample.bin",
+ "sha256": "3d8b6181cbffb27e360758267e1084197dccad82ae05b868691758e1cf72eed4",
+ "sha_ok": true,
+ "bytes": 35948296,
+ "bytes_ok": true,
+ "per_window": {
+ "fc2": {
+ "bytes_covered_ge16": 100440,
+ "n_16gram_positions_shared": 40436,
+ "n_16grams_shared_unique": 15136,
+ "longest_covered_run_bytes": 191,
+ "frac_covered_ge16": 0.5027228317450149,
+ "checker": {
+ "bytes": 199792,
+ "bytes_covered_ge16": 100440,
+ "frac_covered_ge16": 0.5027228317450149,
+ "n_16grams_shared": 40436,
+ "longest_covered_run_bytes": 191
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_en": {
+ "bytes_covered_ge16": 52239,
+ "n_16gram_positions_shared": 11634,
+ "n_16grams_shared_unique": 10573,
+ "longest_covered_run_bytes": 109,
+ "frac_covered_ge16": 0.4361864682748428,
+ "checker": {
+ "bytes": 119763,
+ "bytes_covered_ge16": 52239,
+ "frac_covered_ge16": 0.4361864682748428,
+ "n_16grams_shared": 11634,
+ "longest_covered_run_bytes": 109
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_fr": {
+ "bytes_covered_ge16": 286582,
+ "n_16gram_positions_shared": 55095,
+ "n_16grams_shared_unique": 41336,
+ "longest_covered_run_bytes": 88,
+ "frac_covered_ge16": 0.2632361153976162,
+ "checker": {
+ "bytes": 1088688,
+ "bytes_covered_ge16": 286582,
+ "frac_covered_ge16": 0.2632361153976162,
+ "n_16grams_shared": 55095,
+ "longest_covered_run_bytes": 88
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test20k_old": {
+ "bytes_covered_ge16": 128766,
+ "n_16gram_positions_shared": 36414,
+ "n_16grams_shared_unique": 23867,
+ "longest_covered_run_bytes": 205,
+ "frac_covered_ge16": 0.40246921297743327,
+ "checker": {
+ "bytes": 319940,
+ "bytes_covered_ge16": 128766,
+ "frac_covered_ge16": 0.40246921297743327,
+ "n_16grams_shared": 36414,
+ "longest_covered_run_bytes": 205
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test_v3": {
+ "bytes_covered_ge16": 1316746,
+ "n_16gram_positions_shared": 295112,
+ "n_16grams_shared_unique": 185590,
+ "longest_covered_run_bytes": 129,
+ "frac_covered_ge16": 0.37765329672898335,
+ "checker": {
+ "bytes": 3486653,
+ "bytes_covered_ge16": 1316746,
+ "frac_covered_ge16": 0.37765329672898335,
+ "n_16grams_shared": 295112,
+ "longest_covered_run_bytes": 129
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "queries": {
+ "bytes_covered_ge16": 6200,
+ "n_16gram_positions_shared": 900,
+ "n_16grams_shared_unique": 18,
+ "longest_covered_run_bytes": 21,
+ "frac_covered_ge16": 0.22302158273381295,
+ "checker": {
+ "bytes": 27800,
+ "bytes_covered_ge16": 6200,
+ "frac_covered_ge16": 0.22302158273381295,
+ "n_16grams_shared": 900,
+ "longest_covered_run_bytes": 21
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ }
+ },
+ "seconds": 22.5
+ },
+ "v1b_corpus": {
+ "path": "/workspace/spira_shared/hashing_gen/corpus_v1b/train.bin",
+ "sha256": "ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3",
+ "sha_ok": true,
+ "bytes": 520785883,
+ "bytes_ok": true,
+ "per_window": {
+ "fc2": {
+ "bytes_covered_ge16": 145183,
+ "n_16gram_positions_shared": 71837,
+ "n_16grams_shared_unique": 38098,
+ "longest_covered_run_bytes": 419,
+ "frac_covered_ge16": 0.7266707375670698,
+ "checker": {
+ "bytes": 199792,
+ "bytes_covered_ge16": 145183,
+ "frac_covered_ge16": 0.7266707375670698,
+ "n_16grams_shared": 71837,
+ "longest_covered_run_bytes": 419
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_en": {
+ "bytes_covered_ge16": 94752,
+ "n_16gram_positions_shared": 35873,
+ "n_16grams_shared_unique": 34072,
+ "longest_covered_run_bytes": 338,
+ "frac_covered_ge16": 0.7911625460284061,
+ "checker": {
+ "bytes": 119763,
+ "bytes_covered_ge16": 94752,
+ "frac_covered_ge16": 0.7911625460284061,
+ "n_16grams_shared": 35873,
+ "longest_covered_run_bytes": 338
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_fr": {
+ "bytes_covered_ge16": 652322,
+ "n_16gram_positions_shared": 194413,
+ "n_16grams_shared_unique": 168730,
+ "longest_covered_run_bytes": 145,
+ "frac_covered_ge16": 0.5991817674117837,
+ "checker": {
+ "bytes": 1088688,
+ "bytes_covered_ge16": 652322,
+ "frac_covered_ge16": 0.5991817674117837,
+ "n_16grams_shared": 194413,
+ "longest_covered_run_bytes": 145
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test20k_old": {
+ "bytes_covered_ge16": 237099,
+ "n_16gram_positions_shared": 92792,
+ "n_16grams_shared_unique": 74894,
+ "longest_covered_run_bytes": 266,
+ "frac_covered_ge16": 0.7410733262486716,
+ "checker": {
+ "bytes": 319940,
+ "bytes_covered_ge16": 237099,
+ "frac_covered_ge16": 0.7410733262486716,
+ "n_16grams_shared": 92792,
+ "longest_covered_run_bytes": 266
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test_v3": {
+ "bytes_covered_ge16": 2442104,
+ "n_16gram_positions_shared": 866084,
+ "n_16grams_shared_unique": 673440,
+ "longest_covered_run_bytes": 353,
+ "frac_covered_ge16": 0.7004149825061455,
+ "checker": {
+ "bytes": 3486653,
+ "bytes_covered_ge16": 2442104,
+ "frac_covered_ge16": 0.7004149825061455,
+ "n_16grams_shared": 866084,
+ "longest_covered_run_bytes": 353
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "queries": {
+ "bytes_covered_ge16": 15133,
+ "n_16gram_positions_shared": 4398,
+ "n_16grams_shared_unique": 88,
+ "longest_covered_run_bytes": 53,
+ "frac_covered_ge16": 0.5443525179856115,
+ "checker": {
+ "bytes": 27800,
+ "bytes_covered_ge16": 15133,
+ "frac_covered_ge16": 0.5443525179856115,
+ "n_16grams_shared": 4398,
+ "longest_covered_run_bytes": 53
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ }
+ },
+ "seconds": 358.2
+ },
+ "v1b_sample": {
+ "path": "/workspace/spira_shared/hashing_gen/m8_v1b/sample/v1b_sample.bin",
+ "sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "sha_ok": true,
+ "bytes": 35128951,
+ "bytes_ok": true,
+ "per_window": {
+ "fc2": {
+ "bytes_covered_ge16": 100880,
+ "n_16gram_positions_shared": 40698,
+ "n_16grams_shared_unique": 15264,
+ "longest_covered_run_bytes": 277,
+ "frac_covered_ge16": 0.5049251221270121,
+ "checker": {
+ "bytes": 199792,
+ "bytes_covered_ge16": 100880,
+ "frac_covered_ge16": 0.5049251221270121,
+ "n_16grams_shared": 40698,
+ "longest_covered_run_bytes": 277
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_en": {
+ "bytes_covered_ge16": 55107,
+ "n_16gram_positions_shared": 12710,
+ "n_16grams_shared_unique": 11534,
+ "longest_covered_run_bytes": 108,
+ "frac_covered_ge16": 0.46013376418426394,
+ "checker": {
+ "bytes": 119763,
+ "bytes_covered_ge16": 55107,
+ "frac_covered_ge16": 0.46013376418426394,
+ "n_16grams_shared": 12710,
+ "longest_covered_run_bytes": 108
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_fr": {
+ "bytes_covered_ge16": 283182,
+ "n_16gram_positions_shared": 55308,
+ "n_16grams_shared_unique": 41593,
+ "longest_covered_run_bytes": 76,
+ "frac_covered_ge16": 0.26011309025175255,
+ "checker": {
+ "bytes": 1088688,
+ "bytes_covered_ge16": 283182,
+ "frac_covered_ge16": 0.26011309025175255,
+ "n_16grams_shared": 55308,
+ "longest_covered_run_bytes": 76
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test20k_old": {
+ "bytes_covered_ge16": 128263,
+ "n_16gram_positions_shared": 36178,
+ "n_16grams_shared_unique": 23521,
+ "longest_covered_run_bytes": 166,
+ "frac_covered_ge16": 0.40089704319559916,
+ "checker": {
+ "bytes": 319940,
+ "bytes_covered_ge16": 128263,
+ "frac_covered_ge16": 0.40089704319559916,
+ "n_16grams_shared": 36178,
+ "longest_covered_run_bytes": 166
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test_v3": {
+ "bytes_covered_ge16": 1189410,
+ "n_16gram_positions_shared": 260934,
+ "n_16grams_shared_unique": 174208,
+ "longest_covered_run_bytes": 105,
+ "frac_covered_ge16": 0.34113231227770585,
+ "checker": {
+ "bytes": 3486653,
+ "bytes_covered_ge16": 1189410,
+ "frac_covered_ge16": 0.34113231227770585,
+ "n_16grams_shared": 260934,
+ "longest_covered_run_bytes": 105
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "queries": {
+ "bytes_covered_ge16": 8500,
+ "n_16gram_positions_shared": 1800,
+ "n_16grams_shared_unique": 36,
+ "longest_covered_run_bytes": 36,
+ "frac_covered_ge16": 0.3057553956834532,
+ "checker": {
+ "bytes": 27800,
+ "bytes_covered_ge16": 8500,
+ "frac_covered_ge16": 0.3057553956834532,
+ "n_16grams_shared": 1800,
+ "longest_covered_run_bytes": 36
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ }
+ },
+ "seconds": 22.3
+ }
+ },
+ "peak_rss_mb": 364.83984375
+}
\ No newline at end of file
diff --git a/results/hashing/leak16_baseline_recount/results_stream.json b/results/hashing/leak16_baseline_recount/results_stream.json
new file mode 100644
index 0000000000000000000000000000000000000000..64be4a3b4f039936fe560469d3a3a6004d3a3cf7
--- /dev/null
+++ b/results/hashing/leak16_baseline_recount/results_stream.json
@@ -0,0 +1,523 @@
+{
+ "target": "/workspace/spira_shared/checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json",
+ "target_sha256": "a9ee65d4ad394ada0af487a0cb7eec66073f5440fb405ec19d5df641b5334598",
+ "windows": {
+ "fc2": {
+ "path": "/workspace/spira_shared/broad/freshcode_v2.bin",
+ "sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "sha_ok": true,
+ "bytes": 199792,
+ "bytes_ok": true
+ },
+ "fresh_en": {
+ "path": "/workspace/spira_shared/spira_m7/windows/fresh_en.bin",
+ "sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "sha_ok": true,
+ "bytes": 119763,
+ "bytes_ok": true
+ },
+ "fresh_fr": {
+ "path": "/workspace/spira_shared/spira_m7/windows/fresh_fr.bin",
+ "sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "sha_ok": true,
+ "bytes": 1088688,
+ "bytes_ok": true
+ },
+ "test20k_old": {
+ "path": "/workspace/spira_shared/spira_m7/windows/test20k.bin",
+ "sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "sha_ok": true,
+ "bytes": 319940,
+ "bytes_ok": true
+ },
+ "test_v3": {
+ "path": "/workspace/spira_shared/corpus_v3/test.bin",
+ "sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "sha_ok": true,
+ "bytes": 3486653,
+ "bytes_ok": true
+ },
+ "queries": {
+ "path": "/workspace/spira_shared/spira_m7/windows/queries.bin",
+ "sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "sha_ok": true,
+ "bytes": 27800,
+ "bytes_ok": true
+ }
+ },
+ "sources": {
+ "v1c_corpus": {
+ "path": "/workspace/spira_shared/hashing_gen/corpus_diverse_v1c/train.bin",
+ "sha256": "33577b70c819af76fe4737319e929f4c097b0c72f020e8b07b4baddbb1823439",
+ "sha_ok": true,
+ "bytes": 503301148,
+ "bytes_ok": true,
+ "per_window": {
+ "fc2": {
+ "bytes_covered_ge16": 145139,
+ "n_16gram_positions_shared": 71796,
+ "n_16grams_shared_unique": 38057,
+ "longest_covered_run_bytes": 419,
+ "frac_covered_ge16": 0.72645050852887,
+ "checker": {
+ "bytes": 199792,
+ "bytes_covered_ge16": 145139,
+ "frac_covered_ge16": 0.72645050852887,
+ "n_16grams_shared": 71796,
+ "longest_covered_run_bytes": 419
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_en": {
+ "bytes_covered_ge16": 93456,
+ "n_16gram_positions_shared": 34364,
+ "n_16grams_shared_unique": 32608,
+ "longest_covered_run_bytes": 338,
+ "frac_covered_ge16": 0.7803411738182912,
+ "checker": {
+ "bytes": 119763,
+ "bytes_covered_ge16": 93456,
+ "frac_covered_ge16": 0.7803411738182912,
+ "n_16grams_shared": 34364,
+ "longest_covered_run_bytes": 338
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_fr": {
+ "bytes_covered_ge16": 652302,
+ "n_16gram_positions_shared": 194384,
+ "n_16grams_shared_unique": 168701,
+ "longest_covered_run_bytes": 145,
+ "frac_covered_ge16": 0.5991633966756316,
+ "checker": {
+ "bytes": 1088688,
+ "bytes_covered_ge16": 652302,
+ "frac_covered_ge16": 0.5991633966756316,
+ "n_16grams_shared": 194384,
+ "longest_covered_run_bytes": 145
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test20k_old": {
+ "bytes_covered_ge16": 235956,
+ "n_16gram_positions_shared": 91729,
+ "n_16grams_shared_unique": 73892,
+ "longest_covered_run_bytes": 266,
+ "frac_covered_ge16": 0.7375007813965119,
+ "checker": {
+ "bytes": 319940,
+ "bytes_covered_ge16": 235956,
+ "frac_covered_ge16": 0.7375007813965119,
+ "n_16grams_shared": 91729,
+ "longest_covered_run_bytes": 266
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test_v3": {
+ "bytes_covered_ge16": 2433706,
+ "n_16gram_positions_shared": 859632,
+ "n_16grams_shared_unique": 667154,
+ "longest_covered_run_bytes": 353,
+ "frac_covered_ge16": 0.698006368858616,
+ "checker": {
+ "bytes": 3486653,
+ "bytes_covered_ge16": 2433706,
+ "frac_covered_ge16": 0.698006368858616,
+ "n_16grams_shared": 859632,
+ "longest_covered_run_bytes": 353
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "queries": {
+ "bytes_covered_ge16": 13583,
+ "n_16gram_positions_shared": 3748,
+ "n_16grams_shared_unique": 75,
+ "longest_covered_run_bytes": 53,
+ "frac_covered_ge16": 0.4885971223021583,
+ "checker": {
+ "bytes": 27800,
+ "bytes_covered_ge16": 13583,
+ "frac_covered_ge16": 0.4885971223021583,
+ "n_16grams_shared": 3748,
+ "longest_covered_run_bytes": 53
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ }
+ },
+ "seconds": 247.4
+ },
+ "v1c_sample": {
+ "path": "/workspace/spira_shared/spira_m8/v1c/sample/v1c_sample.bin",
+ "sha256": "3d8b6181cbffb27e360758267e1084197dccad82ae05b868691758e1cf72eed4",
+ "sha_ok": true,
+ "bytes": 35948296,
+ "bytes_ok": true,
+ "per_window": {
+ "fc2": {
+ "bytes_covered_ge16": 100440,
+ "n_16gram_positions_shared": 40436,
+ "n_16grams_shared_unique": 15136,
+ "longest_covered_run_bytes": 191,
+ "frac_covered_ge16": 0.5027228317450149,
+ "checker": {
+ "bytes": 199792,
+ "bytes_covered_ge16": 100440,
+ "frac_covered_ge16": 0.5027228317450149,
+ "n_16grams_shared": 40436,
+ "longest_covered_run_bytes": 191
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_en": {
+ "bytes_covered_ge16": 52239,
+ "n_16gram_positions_shared": 11634,
+ "n_16grams_shared_unique": 10573,
+ "longest_covered_run_bytes": 109,
+ "frac_covered_ge16": 0.4361864682748428,
+ "checker": {
+ "bytes": 119763,
+ "bytes_covered_ge16": 52239,
+ "frac_covered_ge16": 0.4361864682748428,
+ "n_16grams_shared": 11634,
+ "longest_covered_run_bytes": 109
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_fr": {
+ "bytes_covered_ge16": 286582,
+ "n_16gram_positions_shared": 55095,
+ "n_16grams_shared_unique": 41336,
+ "longest_covered_run_bytes": 88,
+ "frac_covered_ge16": 0.2632361153976162,
+ "checker": {
+ "bytes": 1088688,
+ "bytes_covered_ge16": 286582,
+ "frac_covered_ge16": 0.2632361153976162,
+ "n_16grams_shared": 55095,
+ "longest_covered_run_bytes": 88
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test20k_old": {
+ "bytes_covered_ge16": 128766,
+ "n_16gram_positions_shared": 36414,
+ "n_16grams_shared_unique": 23867,
+ "longest_covered_run_bytes": 205,
+ "frac_covered_ge16": 0.40246921297743327,
+ "checker": {
+ "bytes": 319940,
+ "bytes_covered_ge16": 128766,
+ "frac_covered_ge16": 0.40246921297743327,
+ "n_16grams_shared": 36414,
+ "longest_covered_run_bytes": 205
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test_v3": {
+ "bytes_covered_ge16": 1316746,
+ "n_16gram_positions_shared": 295112,
+ "n_16grams_shared_unique": 185590,
+ "longest_covered_run_bytes": 129,
+ "frac_covered_ge16": 0.37765329672898335,
+ "checker": {
+ "bytes": 3486653,
+ "bytes_covered_ge16": 1316746,
+ "frac_covered_ge16": 0.37765329672898335,
+ "n_16grams_shared": 295112,
+ "longest_covered_run_bytes": 129
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "queries": {
+ "bytes_covered_ge16": 6200,
+ "n_16gram_positions_shared": 900,
+ "n_16grams_shared_unique": 18,
+ "longest_covered_run_bytes": 21,
+ "frac_covered_ge16": 0.22302158273381295,
+ "checker": {
+ "bytes": 27800,
+ "bytes_covered_ge16": 6200,
+ "frac_covered_ge16": 0.22302158273381295,
+ "n_16grams_shared": 900,
+ "longest_covered_run_bytes": 21
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ }
+ },
+ "seconds": 17.9
+ },
+ "v1b_corpus": {
+ "path": "/workspace/spira_shared/hashing_gen/corpus_v1b/train.bin",
+ "sha256": "ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3",
+ "sha_ok": true,
+ "bytes": 520785883,
+ "bytes_ok": true,
+ "per_window": {
+ "fc2": {
+ "bytes_covered_ge16": 145183,
+ "n_16gram_positions_shared": 71837,
+ "n_16grams_shared_unique": 38098,
+ "longest_covered_run_bytes": 419,
+ "frac_covered_ge16": 0.7266707375670698,
+ "checker": {
+ "bytes": 199792,
+ "bytes_covered_ge16": 145183,
+ "frac_covered_ge16": 0.7266707375670698,
+ "n_16grams_shared": 71837,
+ "longest_covered_run_bytes": 419
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_en": {
+ "bytes_covered_ge16": 94752,
+ "n_16gram_positions_shared": 35873,
+ "n_16grams_shared_unique": 34072,
+ "longest_covered_run_bytes": 338,
+ "frac_covered_ge16": 0.7911625460284061,
+ "checker": {
+ "bytes": 119763,
+ "bytes_covered_ge16": 94752,
+ "frac_covered_ge16": 0.7911625460284061,
+ "n_16grams_shared": 35873,
+ "longest_covered_run_bytes": 338
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_fr": {
+ "bytes_covered_ge16": 652322,
+ "n_16gram_positions_shared": 194413,
+ "n_16grams_shared_unique": 168730,
+ "longest_covered_run_bytes": 145,
+ "frac_covered_ge16": 0.5991817674117837,
+ "checker": {
+ "bytes": 1088688,
+ "bytes_covered_ge16": 652322,
+ "frac_covered_ge16": 0.5991817674117837,
+ "n_16grams_shared": 194413,
+ "longest_covered_run_bytes": 145
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test20k_old": {
+ "bytes_covered_ge16": 237099,
+ "n_16gram_positions_shared": 92792,
+ "n_16grams_shared_unique": 74894,
+ "longest_covered_run_bytes": 266,
+ "frac_covered_ge16": 0.7410733262486716,
+ "checker": {
+ "bytes": 319940,
+ "bytes_covered_ge16": 237099,
+ "frac_covered_ge16": 0.7410733262486716,
+ "n_16grams_shared": 92792,
+ "longest_covered_run_bytes": 266
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test_v3": {
+ "bytes_covered_ge16": 2442104,
+ "n_16gram_positions_shared": 866084,
+ "n_16grams_shared_unique": 673440,
+ "longest_covered_run_bytes": 353,
+ "frac_covered_ge16": 0.7004149825061455,
+ "checker": {
+ "bytes": 3486653,
+ "bytes_covered_ge16": 2442104,
+ "frac_covered_ge16": 0.7004149825061455,
+ "n_16grams_shared": 866084,
+ "longest_covered_run_bytes": 353
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "queries": {
+ "bytes_covered_ge16": 15133,
+ "n_16gram_positions_shared": 4398,
+ "n_16grams_shared_unique": 88,
+ "longest_covered_run_bytes": 53,
+ "frac_covered_ge16": 0.5443525179856115,
+ "checker": {
+ "bytes": 27800,
+ "bytes_covered_ge16": 15133,
+ "frac_covered_ge16": 0.5443525179856115,
+ "n_16grams_shared": 4398,
+ "longest_covered_run_bytes": 53
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ }
+ },
+ "seconds": 266.2
+ },
+ "v1b_sample": {
+ "path": "/workspace/spira_shared/hashing_gen/m8_v1b/sample/v1b_sample.bin",
+ "sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "sha_ok": true,
+ "bytes": 35128951,
+ "bytes_ok": true,
+ "per_window": {
+ "fc2": {
+ "bytes_covered_ge16": 100880,
+ "n_16gram_positions_shared": 40698,
+ "n_16grams_shared_unique": 15264,
+ "longest_covered_run_bytes": 277,
+ "frac_covered_ge16": 0.5049251221270121,
+ "checker": {
+ "bytes": 199792,
+ "bytes_covered_ge16": 100880,
+ "frac_covered_ge16": 0.5049251221270121,
+ "n_16grams_shared": 40698,
+ "longest_covered_run_bytes": 277
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_en": {
+ "bytes_covered_ge16": 55107,
+ "n_16gram_positions_shared": 12710,
+ "n_16grams_shared_unique": 11534,
+ "longest_covered_run_bytes": 108,
+ "frac_covered_ge16": 0.46013376418426394,
+ "checker": {
+ "bytes": 119763,
+ "bytes_covered_ge16": 55107,
+ "frac_covered_ge16": 0.46013376418426394,
+ "n_16grams_shared": 12710,
+ "longest_covered_run_bytes": 108
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "fresh_fr": {
+ "bytes_covered_ge16": 283182,
+ "n_16gram_positions_shared": 55308,
+ "n_16grams_shared_unique": 41593,
+ "longest_covered_run_bytes": 76,
+ "frac_covered_ge16": 0.26011309025175255,
+ "checker": {
+ "bytes": 1088688,
+ "bytes_covered_ge16": 283182,
+ "frac_covered_ge16": 0.26011309025175255,
+ "n_16grams_shared": 55308,
+ "longest_covered_run_bytes": 76
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test20k_old": {
+ "bytes_covered_ge16": 128263,
+ "n_16gram_positions_shared": 36178,
+ "n_16grams_shared_unique": 23521,
+ "longest_covered_run_bytes": 166,
+ "frac_covered_ge16": 0.40089704319559916,
+ "checker": {
+ "bytes": 319940,
+ "bytes_covered_ge16": 128263,
+ "frac_covered_ge16": 0.40089704319559916,
+ "n_16grams_shared": 36178,
+ "longest_covered_run_bytes": 166
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "test_v3": {
+ "bytes_covered_ge16": 1189410,
+ "n_16gram_positions_shared": 260934,
+ "n_16grams_shared_unique": 174208,
+ "longest_covered_run_bytes": 105,
+ "frac_covered_ge16": 0.34113231227770585,
+ "checker": {
+ "bytes": 3486653,
+ "bytes_covered_ge16": 1189410,
+ "frac_covered_ge16": 0.34113231227770585,
+ "n_16grams_shared": 260934,
+ "longest_covered_run_bytes": 105
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ },
+ "queries": {
+ "bytes_covered_ge16": 8500,
+ "n_16gram_positions_shared": 1800,
+ "n_16grams_shared_unique": 36,
+ "longest_covered_run_bytes": 36,
+ "frac_covered_ge16": 0.3057553956834532,
+ "checker": {
+ "bytes": 27800,
+ "bytes_covered_ge16": 8500,
+ "frac_covered_ge16": 0.3057553956834532,
+ "n_16grams_shared": 1800,
+ "longest_covered_run_bytes": 36
+ },
+ "covered_match": true,
+ "longest_match": true,
+ "n16_match_positions": true,
+ "n16_match_unique": false
+ }
+ },
+ "seconds": 18.5
+ }
+ },
+ "peak_rss_mb": 239.453125
+}
\ No newline at end of file
diff --git a/results/hashing/leak16_reconcile_r3/REPORT.md b/results/hashing/leak16_reconcile_r3/REPORT.md
new file mode 100644
index 0000000000000000000000000000000000000000..644d3ca38de776f4ddb2e35a1c3912cd7efde990
--- /dev/null
+++ b/results/hashing/leak16_reconcile_r3/REPORT.md
@@ -0,0 +1,27 @@
+# Recompte indépendant leak16 sur hf_ready_run_iii_r3 (SPIRA Hashing)
+Référence Checker : checker/recount/leak16_reconcile_r2/REPORT.md sha 9d7d8383… (lue seulement). **Checker n'a publié aucun chiffre pour r3** (son rapport porte sur r2) : pas de MATCH/MISMATCH possible sur r3, seuls nos chiffres sont donnés.
+Outil : recount.py (octets bruts, sans normalisation, plus long run exact par recherche dichotomique, fenêtres lues en memmap par blocs de 256 Ko, sha de chaque fenêtre vérifié contre ref_8w.json = copie de ref_checker_8w.json 01cb94f6…). Pic RSS 86,8 Mo.
+
+## r3 (plus long run partagé, octets)
+| fichier | sha256 | 6 fenêtres | 8 fenêtres | ≥16 ? |
+|:-:|:-:|:-:|:-:|:-:|
+| ADDENDUM.md | 581e7c2f… | 12 | 12 | non |
+| README.md | 54461b93… | 14 | 14 | non |
+| REPORT.md | fe293479… | 14 | 14 | non |
+| res.json | 23751f0b… | 6 | 6 | non |
+| res_add.json | 63986056… | 5 | 5 | non |
+| rss.py | 4dfb1c2e… | 13 | 13 | non |
+r3 : PASS strict (max 14 o) avec 6 et 8 fenêtres. Comparaison Checker r3 : NON PUBLIÉE.
+
+## Auto-contrôle de l'outil sur r2 contre le tableau Checker 9d7d8383
+| fichier | nous 6 | Checker 6 | nous 8 | Checker 8 | statut |
+|:-:|:-:|:-:|:-:|:-:|:-:|
+| ADDENDUM.md | 12 | 12 | 32 | 32 | MATCH |
+| README.md | 12 | 12 | 12 | 12 | MATCH |
+| REPORT.md | 13 | 13 | 32 | 32 | MATCH |
+| res.json | 6 | 6 | 6 | 6 | MATCH |
+| res_add.json | 5 | 5 | 5 | 5 | MATCH |
+| rss.py | 13 | 13 | 13 | 13 | MATCH |
+| runner.sh | 11 | 11 | 17 | 17 | MATCH |
+7/7 MATCH, écart 0 o (colonnes « Hashing réf. 6 » et « Hashing réf. 8 » du rapport Checker).
+Sorties : recount_r3.json, selfcheck_r2.json. Rien poussé.
diff --git a/results/hashing/leak16_reconcile_r3/SHA256SUMS b/results/hashing/leak16_reconcile_r3/SHA256SUMS
new file mode 100644
index 0000000000000000000000000000000000000000..faa5b805b19035335c3893d5b1c786fdc8d90ca1
--- /dev/null
+++ b/results/hashing/leak16_reconcile_r3/SHA256SUMS
@@ -0,0 +1,5 @@
+41b6bd9eceff955a366c6bd49aa384470e184bde87cc6c509d21c531c6a6c927 REPORT.md
+9454d2178cec2f56e28c6c686d8128ba14ae6bcf954e249e26000dc1525aa083 recount.py
+a94c0833168ea8cf74b7bcc023300b6ad7d66aa564c9fbeac4f8289e91612061 recount_r3.json
+01cb94f62f931a423fbbf190f2ed10d30e5d306069a164c24cbce6d6768fb113 ref_8w.json
+7cb45f9e469e4779993b224b4f75cd73679c3ca324fd85d9741c511b93081a90 selfcheck_r2.json
diff --git a/results/hashing/leak16_reconcile_r3/recount.py b/results/hashing/leak16_reconcile_r3/recount.py
new file mode 100644
index 0000000000000000000000000000000000000000..cacbc8dc0f705f0edf4ba6fd40fea491d9f782ba
--- /dev/null
+++ b/results/hashing/leak16_reconcile_r3/recount.py
@@ -0,0 +1,35 @@
+# Recompte indépendant leak16 : plus long run d'octets bruts partagé (fichier x fenêtres), streaming par blocs de 256 Ko via memmap.
+import json,sys,os,hashlib,resource,numpy as np
+from numpy.lib.stride_tricks import sliding_window_view as swv
+S='/workspace/spira_shared/'; D=sys.argv[1]; ref=json.load(open(sys.argv[2]))['windows']
+def wp(m): p=m['path']; return p if p.startswith('/') else S+p
+W={}
+for k,m in ref.items():
+ h=hashlib.sha256(); a=np.memmap(wp(m),np.uint8,'r')
+ for s in range(0,len(a),1<<20): h.update(a[s:s+(1<<20)].tobytes())
+ assert h.hexdigest()==m['sha256'],k; W[k]=a
+def g(a,k): return np.ascontiguousarray(swv(a,k)).view(f'V{k}').ravel() if len(a)>=k else np.empty(0,f'V{k}')
+def hit(fb,k,names):
+ q=np.unique(g(fb,k)); out=[]
+ if not len(q): return out
+ for n in names:
+ a=W[n]
+ for s in range(0,max(len(a)-k+1,1),1<<18):
+ x=g(np.asarray(a[s:s+(1<<18)+k-1]),k); i=np.minimum(np.searchsorted(q,x),len(q)-1)
+ if (q[i]==x).any(): out.append(n); break
+ return out
+def longest(fb,names):
+ lo,hi=0,min(len(fb),128)
+ while lo 3 else None
+K = 64; P = np.uint64(1099511628211); CH = 1 << 22
+def hashes(b):
+ a = np.frombuffer(b, np.uint8).astype(np.uint64); n = len(a) - K + 1
+ if n <= 0: return np.zeros(0, np.uint64)
+ h = np.zeros(n, np.uint64)
+ with np.errstate(over="ignore"):
+ for j in range(K): h = h * P + a[j:j+n] + np.uint64(1)
+ return h
+W = {k: open(f"/workspace/spira_shared/spira_m7/windows/{k}.bin","rb").read() for k in ("fresh_en","fresh_fr","neither_code","test20k","queries")}
+try:
+ from windows_v2 import freshcode_v2; W["fc2"] = freshcode_v2()
+except Exception as e: W["fc2_ERROR"] = b""; print("fc2 indisponible", e)
+tr = open(f"{C}/train.bin","rb").read()
+F = {f: open(f"{C}/{f}.bin","rb").read() for f in ("test","oneshot") if os.path.exists(f"{C}/{f}.bin")}
+for _k in ("test","oneshot"): W["corpus_"+_k] = F[_k]
+rep = {"corpus": C, "method": "verify_v3 semantics, train streamed in 4M-position chunks", "files": {"train": {"bytes": len(tr), "sha256": hashlib.sha256(tr).hexdigest()}}, "overlap64": {}}
+rep["files"].update({f: {"bytes": len(b), "sha256": hashlib.sha256(b).hexdigest()} for f, b in F.items()})
+bl = None
+if BASE:
+ bt = open(f"{BASE}/train.bin","rb").read(); bl = len(bt)
+ rep["base"] = {"dir": BASE, "bytes": bl, "sha256": hashlib.sha256(bt).hexdigest(), "is_exact_prefix": tr[:bl] == bt}
+ del bt; print("base", rep["base"], flush=True)
+HW = {k: hashes(b) for k, b in W.items()}
+allu = np.unique(np.concatenate([h for h in HW.values()]))
+# hash -> liste des positions train (seulement les hash presents dans une fenetre)
+pos_t = {}
+n = len(tr) - K + 1
+for s in range(0, n, CH):
+ e = min(n, s + CH); h = hashes(tr[s:e+K-1])
+ for p in np.nonzero(np.isin(h, allu))[0]: pos_t.setdefault(int(h[p]), []).append(s + int(p))
+ print(f"chunk {s//CH+1}/{(n+CH-1)//CH} cand_hashes={len(pos_t)}", flush=True)
+cand = np.array(sorted(pos_t), dtype=np.uint64)
+for k, b in W.items():
+ hw = HW[k]; m = np.isin(hw, cand); conf = 0; conf_base = 0; dpos = []
+ for p in np.nonzero(m)[0]:
+ seg = b[p:p+K]; qs = [q for q in pos_t[int(hw[p])] if tr[q:q+K] == seg]
+ if qs:
+ conf += 1
+ if bl is not None:
+ if any(q + K <= bl for q in qs): conf_base += 1
+ else: dpos.append(int(p))
+ r = {"window_bytes": len(b), "n_64grams": int(len(hw)), "hash_hits": int(m.sum()), "confirmed_positions": conf}
+ if bl is not None: r.update({"confirmed_in_base_prefix": conf_base, "delta_added_part": len(dpos), "delta_positions_first20": dpos[:20]})
+ rep["overlap64"][k] = r; print(k, r, flush=True)
+rep["valid_zero_overlap"] = all(v["confirmed_positions"] == 0 for v in rep["overlap64"].values()) and "fc2_ERROR" not in W
+if bl is not None:
+ rep["delta_zero_all_windows"] = all(v["delta_added_part"] == 0 for v in rep["overlap64"].values()) and "fc2_ERROR" not in W
+ rep["delta_zero_excl_neither_code"] = all(v["delta_added_part"] == 0 for k, v in rep["overlap64"].items() if k != "neither_code") and "fc2_ERROR" not in W
+json.dump(rep, open(OUT, "w"), indent=1)
+print("VALID" if rep["valid_zero_overlap"] else "INVALID", "DELTA0" if rep.get("delta_zero_all_windows") else "DELTA!=0")
diff --git a/results/hashing/lever2/STATUS b/results/hashing/lever2/STATUS
new file mode 100644
index 0000000000000000000000000000000000000000..5cd026d5bd427655d23aba15b10cabd3a5e5f6c5
--- /dev/null
+++ b/results/hashing/lever2/STATUS
@@ -0,0 +1,37 @@
+2026-10-23 21:24:37 EDT | code prêt /tmp/spira_hashing_lever2 | PRÉ-DÉCLARÉ: old_local_v1 court, snn_tokens=24000 x2 ep, MAXPOS=4000/fenêtre; bras ref(eta=0), AH1 eta_ah=1e-3, AH2 eta_ah=1e-2 (rho=0.1, qmax=0.5); fenêtres seen=train[:200k], fc2, fresh_en, fresh_fr, test20k; critère: mieux sur seen ET frais (McNemar v4.1 fused&invocab) | attente fin PID 21098 + MemAvailable>=5Go
+2026-10-23 21:25:37 EDT | chaîne armée (chain.sh PID 669010, final.sh PID 669437); aucun run lancé; attente fin PID 21098 (tick 490k/600k à 24 t/s) puis MemAvailable>=5Go
+2026-10-23 23:11:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:12:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:13:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:14:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:15:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:16:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:17:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:18:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:19:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 2)
+2026-10-23 23:20:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:21:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:22:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:23:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 2)
+2026-10-23 23:24:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:25:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:26:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 2)
+2026-10-23 23:27:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:28:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 2)
+2026-10-23 23:29:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 3)
+2026-10-23 23:30:20 EDT | lever2 ref: attente MemAvailable>=5Go (now 4)
+2026-10-23 23:31:20 EDT | lever2 ref lancé PID 825721 (eta_ah=0), ETA ~1h30 (train 48k ticks + eval 20k pos, box chargée)
+2026-10-24 00:19:20 EDT | lever2 ref fini rc=0 1
+2026-10-24 00:19:20 EDT | lever2 AH1: attente MemAvailable>=4Go (now 3)
+2026-10-24 00:20:20 EDT | lever2 AH1: attente MemAvailable>=4Go (now 2)
+2026-10-24 00:21:20 EDT | lever2 AH1: attente MemAvailable>=4Go (now 3)
+2026-10-24 00:22:20 EDT | lever2 AH1: attente MemAvailable>=4Go (now 3)
+2026-10-24 00:23:20 EDT | lever2 AH1 lancé PID 883865 (eta_ah=1e-3), ETA ~1h30 (train 48k ticks + eval 20k pos, box chargée)
+2026-10-24 01:37:21 EDT | lever2 AH1 fini rc=0 1
+2026-10-24 01:37:21 EDT | lever2 AH2 lancé PID 957217 (eta_ah=1e-2), ETA ~1h30 (train 48k ticks + eval 20k pos, box chargée)
+2026-10-24 01:52:33 EDT | verdict AH1 : REJETÉ (fc2 perte p=0,024 ; écart +0,182 [+0,024;+0,343]) ; verdict_AH1.{md,json} ; recompte Checker demandé
+2026-10-24 02:43:21 EDT | lever2 AH2 fini rc=0 1
+2026-10-24 02:43:21 EDT | lever2: 3 bras finis, comparaison à faire
+2026-10-24 02:43:29 EDT | lever2 COURT terminé, relais écrit: hing_gen/lever2/short_old', 'ref', 'AH1']' returned non-zero exit status 1.); AH2: ÉCHEC du run/comparaison (Command '['/workspace/SPIRA-venv/bin/python', '/tmp/spira_hashing_lever2/compare.py', '/workspace/spira_shared/hashing_gen/lever2/short_old', 'ref', 'AH2']' returned non-zero exit status 1.)
+2026-10-24 02:44:49 EDT | verdict AH2 : REJETÉ (aucun gain ; fc2 −0,432 p=0,071 ; écart +0,161 [+0,009;+0,316], DRAPEAU) ; verdict_AH2.{md,json} ; recompte Checker demandé
+2026-10-24 02:51:34 EDT | push verdict AH2 FAIT commit 23efb0adbd5fc2e83204d5b5f1a14499e7025841 (11 ajouts, PASS Checker)
diff --git a/results/hashing/lever2/code/chain.sh b/results/hashing/lever2/code/chain.sh
index 883316b8acbd6fe668bd1220500fbb4005d784b1..13ab65c6712b3541ca49666cc711cd32e6814ef4 100644
--- a/results/hashing/lever2/code/chain.sh
+++ b/results/hashing/lever2/code/chain.sh
@@ -1,4 +1,7 @@
#!/bin/bash
+# DÉSACTIVÉ 2026-10-24 (SPIRA Hashing) : ne doit plus rien écrire automatiquement dans spira_relay.md (entrées « ÉCHEC » de final.sh 02 h 43).
+# Original intact (non exécutable) : chain.sh.bak_relay. Toute entrée relais se fait désormais à la main via flock.
+echo "chain.sh désactivé (voir en-tête)" >&2; exit 1
L=/tmp/spira_hashing_lever2; S=/workspace/spira_shared/hashing_gen/lever2; ST=$S/STATUS; OD=$S/short_old
ts(){ TZ=America/Toronto date '+%F %T %Z'; }
mem(){ awk '/MemAvailable/{print int($2/1048576)}' /proc/meminfo; }
diff --git a/results/hashing/lever2/code/compare.py b/results/hashing/lever2/code/compare.py
index 4f173979d1302bdec36f095214f7f9f90156ada6..21809ca2bea872d26a747b5b4e673cfb0d1d4b8d 100644
--- a/results/hashing/lever2/code/compare.py
+++ b/results/hashing/lever2/code/compare.py
@@ -1,18 +1,31 @@
-"""McNemar v4.1 (fused_hit & invocab, exact binomial, same tokenizer => patch-level pairing) + bootstrap seed0 B=10000 over 512-byte blocks."""
-import sys, json, numpy as np
-from scipy.stats import binomtest
-D, ref, new = sys.argv[1:4]; out = {}
-for w in ("seen","fc2","fresh_en","fresh_fr","test20k"):
- a = np.load(f"{D}/{ref}__{w}.npz"); b = np.load(f"{D}/{new}__{w}.npz")
- assert str(a["window_sha256"]) == str(b["window_sha256"]) and (a["tgt_start"] == b["tgt_start"]).all()
- ha = a["fused_hit"] & a["invocab"]; hb = b["fused_hit"] & b["invocab"]; g = int((hb & ~ha).sum()); l = int((ha & ~hb).sum())
- blk = a["tgt_start"] // 512; ub, inv = np.unique(blk, return_inverse=True)
- sa = np.bincount(inv, ha); sb = np.bincount(inv, hb); cn = np.bincount(inv); rng = np.random.default_rng(0); nb = len(ub)
- bs = np.empty(10000)
- for i in range(10000):
- k = rng.integers(0, nb, nb); bs[i] = 100 * (sb[k].sum() - sa[k].sum()) / cn[k].sum()
- out[w] = dict(n=len(ha), n_blocks=nb, ref_pct=round(100*ha.mean(),3), new_pct=round(100*hb.mean(),3), new_only=g, ref_only=l,
- p=binomtest(g, g+l, 0.5).pvalue if g+l else 1.0, delta_pt=round(100*(hb.mean()-ha.mean()),3),
- ci95=[round(np.percentile(bs,2.5),3), round(np.percentile(bs,97.5),3)])
- print(w, json.dumps(out[w]))
-json.dump(out, open(f"{D}/mcnemar_{new}_vs_{ref}.json","w"), indent=1)
+"""McNemar v4.1 (fused_hit & invocab, exact binomial, same tokenizer => patch-level pairing) + bootstrap seed0 B=10000 over 512-byte blocks.
+Correctif 2026-10-24 (SPIRA Hashing) : scipy absent du venv -> scipy.stats.binomtest remplacé par un McNemar exact bilatéral en pur Python
+(math.comb). Méthode = celle de scipy.binomtest (alternative='two-sided') : p = somme des pmf(i) <= pmf(observé)*(1+1e-7), i=0..n, p=0,5,
+plafonné à 1. Pour p=0,5 la loi est symétrique : c'est numériquement identique à 2*min(queue gauche, queue droite) plafonné à 1
+(méthode de verdict_AH1.py) ; mcnemar_p_2tail est aussi écrit pour contrôle. Original conservé : compare.py.bak_scipy.
+NB : ce script NE fait PAS le masque strict test20k (voir verdict_AH1.py pour le protocole complet)."""
+import sys, json, math, numpy as np
+def mcnemar_exact(g, l, rtol=1e-7):
+ n = g + l
+ if n == 0: return 1.0
+ pmf = [math.comb(n, i) / 2 ** n for i in range(n + 1)]; thr = pmf[g] * (1 + rtol)
+ return min(1.0, math.fsum(x for x in pmf if x <= thr))
+def mcnemar_2tail(g, l):
+ n = g + l
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(g, l) + 1)) / 2 ** n)
+if __name__ == "__main__":
+ D, ref, new = sys.argv[1:4]; out = {}
+ for w in ("seen","fc2","fresh_en","fresh_fr","test20k"):
+ a = np.load(f"{D}/{ref}__{w}.npz"); b = np.load(f"{D}/{new}__{w}.npz")
+ assert str(a["window_sha256"]) == str(b["window_sha256"]) and (a["tgt_start"] == b["tgt_start"]).all()
+ ha = a["fused_hit"] & a["invocab"]; hb = b["fused_hit"] & b["invocab"]; g = int((hb & ~ha).sum()); l = int((ha & ~hb).sum())
+ blk = a["tgt_start"] // 512; ub, inv = np.unique(blk, return_inverse=True)
+ sa = np.bincount(inv, ha); sb = np.bincount(inv, hb); cn = np.bincount(inv); rng = np.random.default_rng(0); nb = len(ub)
+ bs = np.empty(10000)
+ for i in range(10000):
+ k = rng.integers(0, nb, nb); bs[i] = 100 * (sb[k].sum() - sa[k].sum()) / cn[k].sum()
+ out[w] = dict(n=len(ha), n_blocks=nb, ref_pct=round(100*ha.mean(),3), new_pct=round(100*hb.mean(),3), new_only=g, ref_only=l,
+ p=mcnemar_exact(g, l), p_2tail=mcnemar_2tail(g, l), delta_pt=round(100*(hb.mean()-ha.mean()),3),
+ ci95=[round(np.percentile(bs,2.5),3), round(np.percentile(bs,97.5),3)])
+ print(w, json.dumps(out[w]))
+ json.dump(out, open(f"{D}/mcnemar_{new}_vs_{ref}.json","w"), indent=1)
diff --git a/results/hashing/lever2/code/final.sh b/results/hashing/lever2/code/final.sh
index 1d7cef6734f1adaf4bb6fb1c2071cd212617321f..b753b0d562238132136f71059e9999e9b9a0a01a 100644
--- a/results/hashing/lever2/code/final.sh
+++ b/results/hashing/lever2/code/final.sh
@@ -1,4 +1,7 @@
#!/bin/bash
+# DÉSACTIVÉ 2026-10-24 (SPIRA Hashing) : ne doit plus rien écrire automatiquement dans spira_relay.md (entrées « ÉCHEC » de final.sh 02 h 43).
+# Original intact (non exécutable) : final.sh.bak_relay. Toute entrée relais se fait désormais à la main via flock.
+echo "final.sh désactivé (voir en-tête)" >&2; exit 1
while kill -0 669010 2>/dev/null; do sleep 120; done
L=/tmp/spira_hashing_lever2; D=/workspace/spira_shared/hashing_gen/lever2/short_old
OMP_NUM_THREADS=1 nice -n 10 /workspace/SPIRA-venv/bin/python $L/finalize.py > $L/finalize.out 2>&1
diff --git a/results/hashing/lever2/code/python/README.md b/results/hashing/lever2/code/python/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..00577ebff77ece88087fcfd0186f7f05bce04e0a
--- /dev/null
+++ b/results/hashing/lever2/code/python/README.md
@@ -0,0 +1,186 @@
+# SPIRA — Spiking Plastic Recurrent Architecture
+
+A CPU-only sequence-learning system **outside the transformer/BPE/backpropagation
+paradigm**, built from three components:
+
+| Component | What it replaces |
+|---|---|
+| **EPT** — Entropy-Patch Tokenization | BPE / WordPiece / SentencePiece |
+| **Hierarchical spiking cortex** — LIF reservoir + slow area, reward-modulated plasticity | Transformer + backprop |
+| **Hippocampus** — one-shot associative memory + replay consolidation | Fine-tuning / gradient learning |
+
+This is **v2** of the prototype: a 16,384-column readout (chosen from a measured
+coverage curve), a two-timescale hierarchical cortex (fast 512-neuron reservoir +
+slow 256-neuron area reading the pooled spike volley every 8 tokens), and
+hippocampal replay that consolidates one-shot memories into cortical weights.
+
+## Headline results (2 vCPU, 4 GB RAM, 13.2 MB mixed text+code corpus)
+
+| Proof | Result |
+|---|---|
+| One-shot learning | **99.3%** exact recall after a single 0.4 s pass over an unseen book |
+| **Systems consolidation (v2)** | cortex-only recall of that book **0.3% → 46.9%** (64.2% in-vocab, 138×) after replaying 100k hippocampal tokens — the AM itself stays at 99.3% |
+| Pattern completion | **99.0%** recall with 1 of 4 context patches corrupted (sparse AM); 52.3% in the deployed full AM (46% load) |
+| Replay interference | none — held-out test accuracy *improves* slightly after replay (0.34% → 0.75% cortex-only) |
+| Zero-shot coverage | 6.3% patch novelty on held-out text+code; the 16k readout covers 64% of held-out targets (v1: 38% at 4k) |
+| Efficiency | ≈9.2 M synaptic MACs/token — ≈**81× fewer ops/token** than GPT-2-small training (v1 at 4k vocab: 2.4 M, 314×) |
+| Generation | ≈2,000 chars/s closed-loop on 2 vCPU, in-browser at ~450-700 chars/s |
+| One-shot write rate | 1,199,996 associations in 18 s, with an exact checkpoint round-trip |
+
+Honest negative results (reported in the paper): the cortex does not amortize
+generalization to unseen documents (test in-vocab 0.49% vs a bigram's 7.7%), and
+the slow area's token-level fusion self-discounts to β≈0.06 at this scale — its
+value is as a second consolidation substrate during replay. See
+`../paper/spira_paper.pdf`, Sections 7–8.
+
+## What's new in v3 (cortex representation repair)
+
+Diagnosis probes on the shipped v2 checkpoint showed the held-out weakness was
+representational: the readout state carried ≈1 token of memory (current patch
+decodable at 99.94%, previous patch at 39.7% vs 33.0% majority chance), and an
+offline ridge readout on the same states scored 0.36% — worse than the online
+delta readout (0.51%). v3 changes the readout's *input*, not its learning rule:
+
+- **Direct input pathway** (`direct_input=True`, `direct_tau=0.5`): a decaying
+ trace of the exact input-neuron pattern is concatenated to the readout state,
+ so the delta rule sees the recent input identities directly.
+- **Multi-timescale trace banks** (`trace_taus=(0.4, 0.8, 0.95)`): the reservoir
+ keeps one spike-trace bank per τ; slow banks are normalized by (1 − τ) so the
+ τ=0.95 bank does not swamp the fast one. With the direct pathway, the readout
+ state is `n_state = 512 × 3 + 1024 = 2560` (v2: 512), and `W_out` is
+ `(2560, V+1)`.
+- **Structured inputs** (`structured_inputs=True`, `k_tri=6`): each patch
+ activates 6 full-hash input neurons **plus** 6 byte-trigram hash neurons, so
+ patches sharing byte trigrams share input neurons.
+- **Compatibility mode:** `direct_input=False, trace_taus=(0.4,),
+ structured_inputs=False` reproduces the v2 architecture exactly
+ (`n_state = 512`); v3 checkpoints record the new fields and restore them on
+ `SPIRA.load()`.
+- **Bug fix:** v2's `model.train()` referenced an undefined `ok_mask`
+ (NameError) — training only ever ran through `scripts/train_chunk.py`. Fixed
+ in v3; `SPIRA.train()` now runs standalone.
+
+Controlled A/B (same protocol both arms — rebuilt corpus, vocab 4096, 200k
+tokens × 2 epochs, AM 50k contexts, held-out test 20k positions, coverage
+45.24%): SNN alone, in-vocab — **0.40% (v2) → 2.07% (v3)**, patch bigram @4096
+on the same positions **4.94%**. The beat-the-bigram criterion is **not met**
+(gap ×12.4 → ×2.4); trained region 3.76% → 13.29%. Training costs 189 t/s vs
+~530 t/s and the checkpoint grows 14.6 MB → 45.9 MB. See `../V3_REPORT.md` and
+`artifacts/metrics_v3_ab.json`.
+
+## Repository layout
+
+```
+spira/ Python package (NumPy only, CPU-only)
+ hashing.py FNV-1a-64, splitmix64, mulberry32 — bit-compatible with the TS port
+ ept.py entropy-patch tokenizer (order-1 Markov surprisal, content addressing)
+ spiking.py LIF reservoir + Dale's law + homeostatic thresholds,
+ Rescorla-Wagner readout gated by dopaminergic RPE,
+ reward-modulated recurrent STDP, and the hierarchical
+ slow area G (windowed spike volleys, top-down prior,
+ counterfactual trust gain beta); v3: multi-timescale
+ trace banks + direct input pathway to the readout
+ hippocampus.py one-shot memory: primary full-key hash (pattern separation)
+ + leave-one-out lanes (CA3 pattern completion), exact
+ derivable-slot checkpoint round-trip
+ model.py SPIRA wrapper: build / train / generate / teach / replay /
+ calibrate_fusion / eval / save-load; v3 config:
+ direct_input, trace_taus, direct_tau, structured_inputs,
+ k_tri (defaults reproduce v3; flags off = v2 architecture)
+ baselines.py gzip, byte-level BPE (HuggingFace tokenizers), sparse
+ n-gram predictors
+ train.py training CLI
+ evaluate.py full evaluation harness (coverage curve, compression,
+ prediction + hierarchy ablation, one-shot, REPLAY
+ consolidation experiment, correction, generation) —
+ resumable by section
+ export_deploy.py JSON artifact export for the browser demo (format v2)
+artifacts/ trained checkpoint, metrics.json, deploy artifact,
+ figures, browser-demo screenshots
+paper/ LaTeX source + compiled research paper (spira_paper.pdf)
+```
+
+## Quick start
+
+```bash
+# build the corpus (Gutenberg books + Python stdlib code)
+python3 scripts/build_corpus.py
+
+# chunked training (background processes are killed between calls in sandboxes;
+# each chunk fits a single tool/shell call). v2 defaults: vocab 16384, hierarchy on.
+python3 scripts/train_chunk.py --start 0 --count 150000 # chunk 1 (fresh build)
+python3 scripts/train_chunk.py --start 150000 --count 150000 # ... continue to 600k
+python3 scripts/train_chunk.py --start 0 --count 150000 # epoch 2
+python3 scripts/train_chunk.py --start 450000 --count 150000 --raster # epoch 2 end + raster
+python3 scripts/train_chunk.py --am-only # hippocampal write pass (1.2M)
+python3 scripts/train_chunk.py --start 450000 --warmup 150000 # re-adapt operating point
+
+# full evaluation (resumable: completed sections are skipped on re-run)
+python3 -m spira.evaluate --model artifacts/spira_model.npz \
+ --train data/train.bin --test data/test.bin \
+ --oneshot data/oneshot.bin --out artifacts/metrics.json
+
+# hippocampal replay -> cortical consolidation (in a few lines)
+python3 - << 'EOF'
+import sys; sys.path.insert(0, ".")
+from spira import SPIRA
+m = SPIRA.load("artifacts/spira_model.npz")
+print(m.teach_bytes(open("data/oneshot.bin", "rb").read()[:60000]))
+print("before replay:", m.eval_stream(open("data/oneshot.bin","rb").read()[:60000], use_am=False, max_positions=4000)["hier_acc"])
+print(m.replay(100000)) # the "sleep" pass
+print("after replay:", m.eval_stream(open("data/oneshot.bin","rb").read()[:60000], use_am=False, max_positions=4000)["hier_acc"])
+EOF
+
+# export the browser-demo artifact (format v2, includes the slow area)
+python3 -m spira.export_deploy --model artifacts/spira_model.npz \
+ --out artifacts/spira_deploy.json --am-cap 100000 --am-min-count 1
+```
+
+## Design notes (the interesting parts)
+
+- **Constant-information tokens.** Each EPT patch carries ≈15.9 bits of accumulated
+ surprisal; low-entropy text yields long patches, high-entropy text short ones.
+ Patch identity is the FNV-1a-64 hash of the bytes — the same substring is always
+ the same token, anywhere, with zero vocabulary learning.
+- **The readout rule is local.** Readout units apply a Widrow–Hoff / Rescorla–Wagner
+ delta rule on their own activity, gated by dopamine `d = r − baseline(r)`. No
+ gradients, no chain rule, no autodiff.
+- **Mean-centering the spike trace matters.** The raw trace carries a dense shared
+ background that otherwise makes every column's score correlate with frequency;
+ subtracting a slow EMA of the trace (homeostatic scaling) is what makes per-context
+ learning converge.
+- **Learned state includes the operating point.** Homeostatic thresholds, the trace
+ mean, the slow area's homeostatic scalars, the top-down gain β, and STDP-shaped
+ recurrent weights must be checkpointed together — omitting any of them (or
+ resetting β to its init) silently destroys the readout's regime.
+- **The hierarchy must be variance-matched and counterfactually credited.** The slow
+ readout's raw scores live at ~20× the fast one's scale; fusing raw scores lets a
+ tiny gain swamp the fast argmax, so the prior is rescaled by σ_fast/σ_slow
+ (measured once, like the EPT budget). And a gain rule that rewards the slow area
+ for ranking frequent truths high degenerates into a frequency prior — only
+ saved-vs-corrupted counterfactual attribution calibrates β honestly (it
+ self-discounts to ≈0.06 at this scale).
+- **Hippocampal replay closes the complementary-systems loop.** Teaching retains the
+ episodic token trace; replay re-runs random 512-token slices through the cortex in
+ full training mode, so one-shot material becomes slow cortical weight while the
+ hippocampus stays intact (0.3% → 46.9% cortex-only recall, zero interference —
+ held-out accuracy actually improves slightly).
+- **Associative-memory checkpoints are easy to get subtly wrong.** Entries must be
+ packed and restored at their derivable slots (primary + leave-one-out hashes); an
+ early format that rebuilt entries at lane-value addresses made the reloaded corpus
+ memory invisible to queries — and inflated v1's corruption-robustness number,
+ which had been measured against an accidentally-empty hippocampus.
+- **Hybrid hippocampal addressing.** A primary full-key hash gives every distinct
+ context its own slot (capacity); leave-one-out key hashes let a query with one
+ corrupted lane still reach the entry (completion). Completion strength trades
+ against table load (99% at 0.8% load vs 52% at 46% load); two corrupted lanes is
+ an explicit architectural cliff.
+- **The TS port is compatible.** `web/src/lib/spira/` regenerates the reservoir from
+ the same seeded PRNG (mulberry32), shares the exact hashing spec, ports the slow
+ area (stepG + variance-matched fusion), and loads the same deploy artifact, so
+ browser inference matches the Python prototype. (Replay is Python-only.)
+
+## Citation
+
+See `../paper/spira_paper.pdf` — *SPIRA: Sequence Learning Without Backpropagation or
+GPU Clusters*, preprint, October 2026 (third iteration).
diff --git a/results/hashing/lever2/code/python/artifacts/README.md b/results/hashing/lever2/code/python/artifacts/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..845caf74737291428df0b1929e4e9a6e707172cf
--- /dev/null
+++ b/results/hashing/lever2/code/python/artifacts/README.md
@@ -0,0 +1,23 @@
+# Artifacts
+
+| File | What |
+|---|---|
+| `spira_model.npz` (72 MB) | full trained v2 checkpoint: EPT stats, reservoir + slow area (W_out, W_out_G, homeostatic state incl. β), fusion calibration, hippocampus (exact derivable-slot round-trip) — resume with `SPIRA.load()` |
+| `spira_model.npz.raster.npz` | spike raster recorded over the last 1500 ticks of training (feeds the Brain tab) |
+| `metrics.json` | full v2 evaluation: coverage curve, compression, prediction + hierarchy ablation, one-shot, **replay consolidation experiment**, correction (two load regimes), generation, efficiency |
+| `spira_model_v3_ab.npz` (45.9 MB) | **v3 A/B checkpoint — vocab 4096**, trained under the controlled A/B protocol (200k tokens × 2 epochs, AM 50k contexts) for the cortex-representation-repair experiment; it is **not** a replacement for the main 16k-vocab v2 checkpoint `spira_model.npz` above. Load with `SPIRA.load()` using the v3 code in `../spira/`. |
+| `metrics_v3_ab.json` | v3 A/B results: protocol, both arms' full metrics, the matched-vocab bigram reference (4.94%), and the headline comparison (SNN alone, in-vocab, held-out: v2 0.40% → v3 2.07%) — see `../../V3_REPORT.md` |
+| `chunks.jsonl` | training-chunk log (historical) |
+| `web_*.png` | browser-demo screenshots |
+
+`spira_deploy.json` (29 MB, browser-inference export, format v2) is **not duplicated
+here** — it lives at `web/public/spira_deploy.json`, where the demo fetches it.
+Regenerate it with:
+
+```bash
+python3 -m spira.export_deploy --model artifacts/spira_model.npz \
+ --out ../web/public/spira_deploy.json --am-cap 100000 --am-min-count 1
+```
+
+Figures are generated by `scripts/make_figures.py` and stored with the paper in
+`../paper/figures/` (incl. `fig_vocab.pdf` and `fig_replay.pdf`).
diff --git a/results/hashing/lever2/code/python/artifacts/chunks.jsonl b/results/hashing/lever2/code/python/artifacts/chunks.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..2889518cd1bc5da02289cde38a2fe32d94ed9391
--- /dev/null
+++ b/results/hashing/lever2/code/python/artifacts/chunks.jsonl
@@ -0,0 +1,125 @@
+{"t": 1792689848.1349747, "msg": "[spira] fitting EPT byte-level Markov model ..."}
+{"t": 1792689849.6846397, "msg": "[spira] calibrated surprisal budget = 15.92 bits (target avg patch len 4.5)"}
+{"t": 1792689849.6847265, "msg": "[spira] segmenting full train stream ..."}
+{"t": 1792689857.4940877, "msg": "[spira] 2799170 patches, avg len 4.72 B (13.2 MB segmented in 7.5s, 1.76 MB/s)"}
+{"t": 1792689857.5268452, "msg": "[spira] distinct patches in train: 234130"}
+{"t": 1792689857.5543995, "msg": "[spira] building patch registry (147575 ids) ..."}
+{"t": 1792689858.7038174, "msg": "[chunk] fresh build done"}
+{"t": 1792689858.7371278, "msg": "[chunk] SNN pass tokens[0:150000]"}
+{"t": 1792689912.9961026, "msg": " tick 25000/150000 acc=0.043 dop=-0.004 461 t/s"}
+{"t": 1792689975.0878282, "msg": " tick 50000/150000 acc=0.009 dop=-0.001 430 t/s"}
+{"t": 1792690029.5772126, "msg": " tick 75000/150000 acc=0.021 dop=+0.002 439 t/s"}
+{"t": 1792690089.7845855, "msg": " tick 100000/150000 acc=0.009 dop=-0.001 433 t/s"}
+{"t": 1792690149.519251, "msg": " tick 125000/150000 acc=0.028 dop=+0.001 430 t/s"}
+{"t": 1792690209.899671, "msg": " tick 150000/150000 acc=0.003 dop=-0.001 427 t/s"}
+{"t": 1792690209.8999403, "msg": "[chunk] SNN done: acc=0.0352 fast=0.11792 beta=1.198424340908533 ema=0.0028 (351s, 427 t/s)"}
+{"t": 1792690213.0381534, "msg": "[chunk] checkpoint saved -> /home/z/my-project/download/spira/artifacts/spira_model.npz (total 370s)"}
+{"t": 1792690245.5987608, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792690245.6328268, "msg": "[chunk] SNN pass tokens[150000:300000]"}
+{"t": 1792690303.803557, "msg": " tick 25000/150000 acc=0.038 dop=+0.012 430 t/s"}
+{"t": 1792690353.8819084, "msg": " tick 50000/150000 acc=0.002 dop=-0.000 462 t/s"}
+{"t": 1792690410.300095, "msg": " tick 75000/150000 acc=0.004 dop=-0.001 456 t/s"}
+{"t": 1792690469.1089964, "msg": " tick 100000/150000 acc=0.003 dop=+0.000 448 t/s"}
+{"t": 1792690527.1233356, "msg": " tick 125000/150000 acc=0.001 dop=-0.000 444 t/s"}
+{"t": 1792690590.2359507, "msg": " tick 150000/150000 acc=0.000 dop=-0.000 435 t/s"}
+{"t": 1792690590.2360516, "msg": "[chunk] SNN done: acc=0.0191 fast=0.12413333333333333 beta=1.747051700993652 ema=0.0001 (345s, 435 t/s)"}
+{"t": 1792690593.3198326, "msg": "[chunk] checkpoint saved -> /home/z/my-project/download/spira/artifacts/spira_model.npz (total 361s)"}
+{"t": 1792690612.5087485, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792690612.5453851, "msg": "[chunk] SNN pass tokens[300000:450000]"}
+{"t": 1792690674.0282369, "msg": " tick 25000/150000 acc=0.020 dop=-0.004 407 t/s"}
+{"t": 1792690729.639865, "msg": " tick 50000/150000 acc=0.003 dop=+0.000 427 t/s"}
+{"t": 1792690783.3119826, "msg": " tick 75000/150000 acc=0.020 dop=-0.004 439 t/s"}
+{"t": 1792690844.9781892, "msg": " tick 100000/150000 acc=0.000 dop=-0.000 430 t/s"}
+{"t": 1792690908.031417, "msg": " tick 125000/150000 acc=0.026 dop=-0.002 423 t/s"}
+{"t": 1792690963.3836546, "msg": " tick 150000/150000 acc=0.008 dop=-0.002 428 t/s"}
+{"t": 1792690963.383805, "msg": "[chunk] SNN done: acc=0.0063 fast=0.09190666666666666 beta=1.1933744918656457 ema=0.0082 (351s, 428 t/s)"}
+{"t": 1792690966.544749, "msg": "[chunk] checkpoint saved -> /home/z/my-project/download/spira/artifacts/spira_model.npz (total 367s)"}
+{"t": 1792690983.6731129, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792690983.7101266, "msg": "[chunk] SNN pass tokens[450000:600000]"}
+{"t": 1792691041.480612, "msg": " tick 25000/150000 acc=0.000 dop=-0.000 433 t/s"}
+{"t": 1792691094.4843662, "msg": " tick 50000/150000 acc=0.015 dop=-0.001 451 t/s"}
+{"t": 1792691145.131032, "msg": " tick 75000/150000 acc=0.000 dop=-0.000 465 t/s"}
+{"t": 1792691202.3809683, "msg": " tick 100000/150000 acc=0.014 dop=+0.003 457 t/s"}
+{"t": 1792691249.2985406, "msg": " tick 125000/150000 acc=0.068 dop=+0.015 471 t/s"}
+{"t": 1792691303.3424532, "msg": " tick 150000/150000 acc=0.001 dop=-0.000 469 t/s"}
+{"t": 1792691303.342613, "msg": "[chunk] SNN done: acc=0.0050 fast=0.08072 beta=1.266389629875493 ema=0.0012 (320s, 469 t/s)"}
+{"t": 1792691306.3462572, "msg": "[chunk] checkpoint saved -> /home/z/my-project/download/spira/artifacts/spira_model.npz (total 336s)"}
+{"t": 1792691330.5498514, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792691330.5906599, "msg": "[chunk] SNN pass tokens[0:150000]"}
+{"t": 1792691383.5835564, "msg": " tick 25000/150000 acc=0.001 dop=-0.000 472 t/s"}
+{"t": 1792691445.211175, "msg": " tick 50000/150000 acc=0.002 dop=-0.001 436 t/s"}
+{"t": 1792691502.242968, "msg": " tick 75000/150000 acc=0.015 dop=+0.003 437 t/s"}
+{"t": 1792691554.181319, "msg": " tick 100000/150000 acc=0.001 dop=+0.000 447 t/s"}
+{"t": 1792691611.8847651, "msg": " tick 125000/150000 acc=0.000 dop=-0.000 444 t/s"}
+{"t": 1792691674.5757427, "msg": " tick 150000/150000 acc=0.001 dop=-0.000 436 t/s"}
+{"t": 1792691674.5759006, "msg": "[chunk] SNN done: acc=0.0109 fast=0.1192 beta=1.2954219302334735 ema=0.0010 (344s, 436 t/s)"}
+{"t": 1792691677.628161, "msg": "[chunk] checkpoint saved -> /home/z/my-project/download/spira/artifacts/spira_model.npz (total 360s)"}
+{"t": 1792691708.182975, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792691708.220647, "msg": "[chunk] SNN pass tokens[150000:300000]"}
+{"t": 1792691769.2049358, "msg": " tick 25000/150000 acc=0.006 dop=+0.002 410 t/s"}
+{"t": 1792691836.7221665, "msg": " tick 50000/150000 acc=0.002 dop=+0.000 389 t/s"}
+{"t": 1792691903.078837, "msg": " tick 75000/150000 acc=0.000 dop=-0.000 385 t/s"}
+{"t": 1792691961.705981, "msg": " tick 100000/150000 acc=0.021 dop=-0.000 394 t/s"}
+{"t": 1792692025.0206945, "msg": " tick 125000/150000 acc=0.001 dop=-0.000 395 t/s"}
+{"t": 1792692085.9798195, "msg": " tick 150000/150000 acc=0.001 dop=+0.000 397 t/s"}
+{"t": 1792692085.9800117, "msg": "[chunk] SNN done: acc=0.0054 fast=0.11891333333333333 beta=1.3249924062745693 ema=0.0011 (378s, 397 t/s)"}
+{"t": 1792692089.139205, "msg": "[chunk] checkpoint saved -> /home/z/my-project/download/spira/artifacts/spira_model.npz (total 394s)"}
+{"t": 1792692106.1035054, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792692106.14451, "msg": "[chunk] SNN pass tokens[300000:450000]"}
+{"t": 1792692165.3216357, "msg": " tick 25000/150000 acc=0.001 dop=-0.000 422 t/s"}
+{"t": 1792692229.2163122, "msg": " tick 50000/150000 acc=0.001 dop=-0.000 406 t/s"}
+{"t": 1792692284.5736065, "msg": " tick 75000/150000 acc=0.000 dop=-0.000 420 t/s"}
+{"t": 1792692338.6348023, "msg": " tick 100000/150000 acc=0.000 dop=-0.000 430 t/s"}
+{"t": 1792692397.833217, "msg": " tick 125000/150000 acc=0.000 dop=-0.000 428 t/s"}
+{"t": 1792692460.3992035, "msg": " tick 150000/150000 acc=0.001 dop=-0.000 423 t/s"}
+{"t": 1792692460.3994114, "msg": "[chunk] SNN done: acc=0.0011 fast=0.08736 beta=1.762662688647477 ema=0.0008 (354s, 423 t/s)"}
+{"t": 1792692463.4121368, "msg": "[chunk] checkpoint saved -> /home/z/my-project/download/spira/artifacts/spira_model.npz (total 371s)"}
+{"t": 1792692482.7419205, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792692482.7793715, "msg": "[chunk] SNN pass tokens[450000:600000]"}
+{"t": 1792692545.3073466, "msg": " tick 25000/150000 acc=0.000 dop=-0.000 400 t/s"}
+{"t": 1792692610.0230045, "msg": " tick 50000/150000 acc=0.001 dop=-0.000 393 t/s"}
+{"t": 1792692674.7956657, "msg": " tick 75000/150000 acc=0.004 dop=-0.001 391 t/s"}
+{"t": 1792692736.9330604, "msg": " tick 100000/150000 acc=0.004 dop=+0.002 394 t/s"}
+{"t": 1792692799.5741637, "msg": " tick 125000/150000 acc=0.006 dop=+0.004 395 t/s"}
+{"t": 1792692861.51613, "msg": " tick 150000/150000 acc=0.000 dop=-0.000 396 t/s"}
+{"t": 1792692861.5388815, "msg": "[chunk] raster saved (36135 spikes over 1500 ticks)"}
+{"t": 1792692861.5389504, "msg": "[chunk] SNN done: acc=0.0013 fast=0.07764 beta=1.6971305954071978 ema=0.0000 (379s, 396 t/s)"}
+{"t": 1792692864.68562, "msg": "[chunk] checkpoint saved -> /home/z/my-project/download/spira/artifacts/spira_model.npz (total 395s)"}
+{"t": 1792692883.8854992, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792692883.885611, "msg": "[chunk] hippocampus one-shot write pass over 1200000 tokens"}
+{"t": 1792692902.37838, "msg": "[chunk] AM: 1199996 associations in 18s; {'slots': 8388608, 'used': 3894586, 'load_factor': 0.46427083015441895, 'n_writes': 1199996}"}
+{"t": 1792692916.040569, "msg": "[chunk] checkpoint saved -> /home/z/my-project/download/spira/artifacts/spira_model.npz (total 45s)"}
+{"t": 1792692937.183013, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792692937.183116, "msg": "[chunk] step-only warmup over tokens[450000:600000] (matching final training-region statistics)"}
+{"t": 1792693198.376045, "msg": "[chunk] warmup done in 261s (firing rate 0.045)"}
+{"t": 1792693205.7143555, "msg": "[chunk] checkpoint saved with core state -> /home/z/my-project/download/spira/artifacts/spira_model.npz"}
+{"t": 1792693456.5794063, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792693456.6158457, "msg": "[chunk] SNN pass tokens[450000:600000]"}
+{"t": 1792693518.1308408, "msg": " tick 25000/150000 acc=0.047 dop=+0.004 406 t/s"}
+{"t": 1792693583.1861885, "msg": " tick 50000/150000 acc=0.036 dop=-0.001 395 t/s"}
+{"t": 1792693644.4360857, "msg": " tick 75000/150000 acc=0.038 dop=-0.005 399 t/s"}
+{"t": 1792693704.4942787, "msg": " tick 100000/150000 acc=0.041 dop=-0.000 403 t/s"}
+{"t": 1792693767.2334795, "msg": " tick 125000/150000 acc=0.130 dop=+0.001 402 t/s"}
+{"t": 1792693820.64215, "msg": " tick 150000/150000 acc=0.162 dop=-0.009 412 t/s"}
+{"t": 1792693820.692566, "msg": "[chunk] raster saved (35812 spikes over 1500 ticks)"}
+{"t": 1792693820.6926665, "msg": "[chunk] SNN done: acc=0.0697 fast=0.09082 beta=0.08447342118850533 ema=0.1620 (364s, 412 t/s)"}
+{"t": 1792693827.4360313, "msg": "[chunk] checkpoint saved -> /home/z/my-project/download/spira/artifacts/spira_model.npz (total 385s)"}
+{"t": 1792693856.4826596, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792693856.4827747, "msg": "[chunk] step-only warmup over tokens[450000:600000] (matching final training-region statistics)"}
+{"t": 1792694147.5969715, "msg": "[chunk] warmup done in 291s (firing rate 0.047)"}
+{"t": 1792694154.1971679, "msg": "[chunk] checkpoint saved with core state -> /home/z/my-project/download/spira/artifacts/spira_model.npz"}
+{"t": 1792694832.1377423, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792694832.1803858, "msg": "[chunk] SNN pass tokens[450000:600000]"}
+{"t": 1792694887.8062232, "msg": " tick 25000/150000 acc=0.012 dop=+0.001 449 t/s"}
+{"t": 1792694940.0106783, "msg": " tick 50000/150000 acc=0.027 dop=-0.004 464 t/s"}
+{"t": 1792694996.9033513, "msg": " tick 75000/150000 acc=0.036 dop=-0.007 455 t/s"}
+{"t": 1792695058.4275079, "msg": " tick 100000/150000 acc=0.034 dop=+0.001 442 t/s"}
+{"t": 1792695123.4776978, "msg": " tick 125000/150000 acc=0.111 dop=-0.003 429 t/s"}
+{"t": 1792695176.1116078, "msg": " tick 150000/150000 acc=0.130 dop=-0.008 436 t/s"}
+{"t": 1792695176.1332781, "msg": "[chunk] raster saved (35482 spikes over 1500 ticks)"}
+{"t": 1792695176.1333697, "msg": "[chunk] SNN done: acc=0.0454 fast=0.10298666666666667 beta=0.058987816055875775 ema=0.1301 (344s, 436 t/s)"}
+{"t": 1792695202.1253033, "msg": "[chunk] checkpoint saved -> /home/z/my-project/download/spira/artifacts/spira_model.npz (total 396s)"}
+{"t": 1792695232.6920857, "msg": "[chunk] resumed from checkpoint"}
+{"t": 1792695232.6921952, "msg": "[chunk] step-only warmup over tokens[450000:600000] (matching final training-region statistics)"}
+{"t": 1792695515.7223403, "msg": "[chunk] warmup done in 283s (firing rate 0.039)"}
+{"t": 1792695541.2171822, "msg": "[chunk] checkpoint saved with core state -> /home/z/my-project/download/spira/artifacts/spira_model.npz"}
diff --git a/results/hashing/lever2/code/python/artifacts/metrics.json b/results/hashing/lever2/code/python/artifacts/metrics.json
new file mode 100644
index 0000000000000000000000000000000000000000..1254f358fd9c23a7fc9090737cd94cfa2a3f5960
--- /dev/null
+++ b/results/hashing/lever2/code/python/artifacts/metrics.json
@@ -0,0 +1,396 @@
+{
+ "model_meta": {
+ "train_bytes": 13223262,
+ "n_patches": 2799170,
+ "avg_patch_len": 4.7239938981912495,
+ "distinct_patches": 234130,
+ "registry_size": 147575,
+ "budget_bits": 15.91943359375,
+ "segmentation_MB_per_s": 1.7565680288219827
+ },
+ "config": {
+ "target_avg_len": 4.5,
+ "min_len": 2,
+ "max_len": 32,
+ "alpha": 0.5,
+ "d_in": 1024,
+ "k_in": 12,
+ "n_res": 512,
+ "vocab_size": 16384,
+ "seed": 20261022,
+ "hierarchy": true,
+ "n_g": 256,
+ "win": 8,
+ "eta_pos": 0.01,
+ "eta_r": 0.01,
+ "eta_stdp": 0.0015,
+ "am_size": 8388608,
+ "am_m": 4,
+ "am_min_lanes": 3,
+ "snn_tokens": 600000,
+ "am_tokens": 1200000,
+ "epochs": 2,
+ "replay_tokens": 180000,
+ "replay_slice": 512,
+ "beta_am": 0.5,
+ "am_override": 6.0,
+ "temperature": 0.8,
+ "top_k": 8
+ },
+ "vocab_coverage_curve": [
+ {
+ "vocab": 4096,
+ "cov_test": 0.3848,
+ "cov_oneshot": 0.4638
+ },
+ {
+ "vocab": 6144,
+ "cov_test": 0.4543,
+ "cov_oneshot": 0.5414
+ },
+ {
+ "vocab": 8192,
+ "cov_test": 0.5071,
+ "cov_oneshot": 0.5999
+ },
+ {
+ "vocab": 12288,
+ "cov_test": 0.5838,
+ "cov_oneshot": 0.6797
+ },
+ {
+ "vocab": 16384,
+ "cov_test": 0.6394,
+ "cov_oneshot": 0.7404
+ },
+ {
+ "vocab": 24576,
+ "cov_test": 0.7153,
+ "cov_oneshot": 0.8077
+ },
+ {
+ "vocab": 32768,
+ "cov_test": 0.7649,
+ "cov_oneshot": 0.8489
+ }
+ ],
+ "vocab_coverage": {
+ "distinct_train_patches": 234130,
+ "note": "fraction of held-out target patches inside the top-V train vocabulary"
+ },
+ "compression": {
+ "gzip": {
+ "bits_per_byte": 2.5916625282547328,
+ "seconds": 0.06935647600039374
+ },
+ "bpe_4096": {
+ "vocab_size": 4096,
+ "n_tokens": 213578,
+ "avg_token_bytes": 3.196157843972694,
+ "stream_bits_unigram": 9.4638792864356,
+ "stream_bits_bigram": 4.818219420963174,
+ "dict_bits": 301432.0,
+ "bits_per_byte_unigram": 3.4025926385171776,
+ "bits_per_byte_bigram": 1.9490787345548937,
+ "train_s": 1.5803333969997766
+ },
+ "bpe_16384": {
+ "vocab_size": 16384,
+ "n_tokens": 180088,
+ "avg_token_bytes": 3.7905301852427704,
+ "stream_bits_unigram": 9.814124375536865,
+ "stream_bits_bigram": 4.611101226860982,
+ "dict_bits": 1386648.0,
+ "bits_per_byte_unigram": 4.620451270809888,
+ "bits_per_byte_bigram": 3.2478139629915233,
+ "train_s": 1.7241879100001825
+ },
+ "ept": {
+ "n_tokens": 144013,
+ "avg_token_bytes": 4.740051245373682,
+ "distinct_in_test": 41604,
+ "stream_bits_unigram": 14.295363293655472,
+ "stream_bits_bigram": 2.3544508230397527,
+ "dict_bits_test_local": 2462160.0,
+ "bits_per_byte_unigram": 6.622745523570205,
+ "bits_per_byte_bigram": 4.103592912663283,
+ "novelty_rate": 0.06314707699999306,
+ "bytes_in_novel_patches": 43623.0,
+ "segment_s": 0.26365890000124637,
+ "MB_per_s": 2.589061093696337
+ }
+ },
+ "fusion_calibration": {
+ "scale": 0.049578128047281136,
+ "sigma_fast": 0.030150376720135645,
+ "sigma_slow": 0.608138667345047,
+ "beta": 0.058987816055875775
+ },
+ "one_shot": {
+ "book_bytes": 60000,
+ "before_teaching": {
+ "n_positions": 8000,
+ "vocab_coverage": 0.73025,
+ "snn_acc": 0.00325,
+ "hier_acc": 0.003375,
+ "am_acc": 0.0025,
+ "fused_acc": 0.0055,
+ "snn_acc_invocab": 0.004450530640191715,
+ "hier_acc_invocab": 0.004621704895583704,
+ "am_acc_invocab": 0.003252310852447792,
+ "fused_acc_invocab": 0.007531667237247518,
+ "corrupt_lanes": 0
+ },
+ "teaching": {
+ "tokens": 13346,
+ "new_patches": 329,
+ "associations": 13342,
+ "episode_tokens": 13346,
+ "seconds": 0.35267701299926557
+ },
+ "after_one_pass": {
+ "n_positions": 8000,
+ "vocab_coverage": 0.73025,
+ "snn_acc": 0.00325,
+ "hier_acc": 0.003375,
+ "am_acc": 0.993125,
+ "fused_acc": 0.993125,
+ "snn_acc_invocab": 0.004450530640191715,
+ "hier_acc_invocab": 0.004621704895583704,
+ "am_acc_invocab": 0.9926395070181445,
+ "fused_acc_invocab": 0.9926395070181445,
+ "corrupt_lanes": 0
+ }
+ },
+ "replay": {
+ "replay_tokens": 100000,
+ "stage_tokens": 25000,
+ "before": {
+ "n_positions": 8000,
+ "vocab_coverage": 0.73025,
+ "snn_acc": 0.00325,
+ "hier_acc": 0.003375,
+ "am_acc": 0.0,
+ "fused_acc": 0.003375,
+ "snn_acc_invocab": 0.004450530640191715,
+ "hier_acc_invocab": 0.004621704895583704,
+ "am_acc_invocab": 0.0,
+ "fused_acc_invocab": 0.004621704895583704,
+ "corrupt_lanes": 0
+ },
+ "curve": [
+ {
+ "replayed_tokens": 25000,
+ "hier_acc": 0.178,
+ "hier_acc_invocab": 0.24756606397774686,
+ "snn_acc": 0.177,
+ "replay_acc": 0.13062542352612908,
+ "beta": 0.03478016090689402
+ },
+ {
+ "replayed_tokens": 50000,
+ "hier_acc": 0.247,
+ "hier_acc_invocab": 0.3435326842837274,
+ "snn_acc": 0.2465,
+ "replay_acc": 0.31538246900785266,
+ "beta": 0.0031896269343629304
+ },
+ {
+ "replayed_tokens": 75000,
+ "hier_acc": 0.2665,
+ "hier_acc_invocab": 0.370653685674548,
+ "snn_acc": 0.2665,
+ "replay_acc": 0.3782437118826484,
+ "beta": 0.0018039194478497163
+ },
+ {
+ "replayed_tokens": 100000,
+ "hier_acc": 0.275,
+ "hier_acc_invocab": 0.38247566063977745,
+ "snn_acc": 0.275,
+ "replay_acc": 0.38071511141228526,
+ "beta": 0.004831501266509353
+ }
+ ],
+ "after": {
+ "n_positions": 8000,
+ "vocab_coverage": 0.73025,
+ "snn_acc": 0.468875,
+ "hier_acc": 0.468875,
+ "am_acc": 0.0,
+ "fused_acc": 0.468875,
+ "snn_acc_invocab": 0.6420746319753509,
+ "hier_acc_invocab": 0.6420746319753509,
+ "am_acc_invocab": 0.0,
+ "fused_acc_invocab": 0.6420746319753509,
+ "corrupt_lanes": 0
+ },
+ "am_recall_after_replay": {
+ "n_positions": 8000,
+ "vocab_coverage": 0.73025,
+ "snn_acc": 0.468875,
+ "hier_acc": 0.468875,
+ "am_acc": 0.993125,
+ "fused_acc": 0.9935,
+ "snn_acc_invocab": 0.6420746319753509,
+ "hier_acc_invocab": 0.6420746319753509,
+ "am_acc_invocab": 0.9926395070181445,
+ "fused_acc_invocab": 0.9931530297843204,
+ "corrupt_lanes": 0
+ },
+ "interference_test_core_only": {
+ "n_positions": 8000,
+ "vocab_coverage": 0.694,
+ "snn_acc": 0.0075,
+ "hier_acc": 0.0075,
+ "am_acc": 0.0,
+ "fused_acc": 0.0075,
+ "snn_acc_invocab": 0.010806916426512969,
+ "hier_acc_invocab": 0.010806916426512969,
+ "am_acc_invocab": 0.0,
+ "fused_acc_invocab": 0.010806916426512969,
+ "corrupt_lanes": 0
+ },
+ "interference_test_fused": {
+ "n_positions": 8000,
+ "vocab_coverage": 0.694,
+ "snn_acc": 0.0075,
+ "hier_acc": 0.0075,
+ "am_acc": 0.0025,
+ "fused_acc": 0.009375,
+ "snn_acc_invocab": 0.010806916426512969,
+ "hier_acc_invocab": 0.010806916426512969,
+ "am_acc_invocab": 0.003422190201729107,
+ "fused_acc_invocab": 0.01350864553314121,
+ "corrupt_lanes": 0
+ },
+ "pre_replay_test": {
+ "n_positions": 60000,
+ "vocab_coverage": 0.7062833333333334,
+ "snn_acc": 0.003416666666666667,
+ "hier_acc": 0.0034333333333333334,
+ "am_acc": 0.0020666666666666667,
+ "fused_acc": 0.00515,
+ "snn_acc_invocab": 0.004837529792104208,
+ "hier_acc_invocab": 0.004861127498407155,
+ "am_acc_invocab": 0.0025721499870212617,
+ "fused_acc_invocab": 0.007291691247610733,
+ "corrupt_lanes": 0
+ },
+ "note": "the shipped checkpoint is PRE-replay; this section runs in-memory"
+ },
+ "correction": {
+ "corrupt_0_of_4": {
+ "am_acc": 0.993125,
+ "am_acc_invocab": 0.9926395070181445,
+ "fused_acc": 0.9935
+ },
+ "corrupt_1_of_4": {
+ "am_acc": 0.522875,
+ "am_acc_invocab": 0.5217391304347826,
+ "fused_acc": 0.595875
+ },
+ "corrupt_2_of_4": {
+ "am_acc": 0.000125,
+ "am_acc_invocab": 0.0,
+ "fused_acc": 0.468875
+ },
+ "corrupt_3_of_4": {
+ "am_acc": 0.0,
+ "am_acc_invocab": 0.0,
+ "fused_acc": 0.468875
+ }
+ },
+ "generation": {
+ "english": {
+ "prompt": "The old man looked at the ",
+ "output": "The old man looked at the Woac�lly e netacrissciasmhere w1,-3icuoch nt o�ere he(0,n the feast\r that!e chond clostram.\" he moohed vven u 0\nSear\nressesy fehe co wha die a c and uhe sea was!ougithing?urst er, f\n_adntfuut isosite)}\"on uin tihim-anyw oft ov,l a\rits\"le ai\nhauposuhrowy scell bhat u the gn urundAad alnd toern�n it!w ny pid wardid! latcter)\n seu mea ren in bll, cor pxac'plane core mtageaid)flyt warnly then ti hagestat\" becked c to dever.if ioohed obf da j]st mas tad\r\nu drod mys selin2the e if S camr. Mcouldethe `that!it\n m a\r lecst\r\nsartmy roght_\n# thut tie choef alerp hag tusked aun'): sonn as\rGragoryhad.starv att\r\nppeac, an�= helh pong _ydini liqs, lnly pb[0 bag",
+ "chars_per_s": 1703.6292768579199,
+ "distinct1": 0.9327731092436975,
+ "distinct2": 1.0
+ },
+ "code": {
+ "prompt": "def process(data):\n ",
+ "output": "def process(data):\n \non ong hor war; c pomisherle th praat hill `n’t!usiall_n he n he r\r\nnows_t toiay n it�ut ohouldentfu\nuneur j warou w Br liq I a stroigh\n_count\npotour wuickny dans`d grnot! Xou aentmeratialnr thi n_ow c up;\r\nD wis��re b, to_lso, tim aroress\r\nw lecthe lparumplaicuoom(st ti\n_adte ar, bufed gther ie dicehon�it.\nhe doundAoffsegon. H’p noun’t!go; If fom Jort Sfound has_hen hredrlearas neflyed Calad I Weer las it'selestion nf\r\nuoncus all! as me camhe cois._fressobj_ce aldiale to?n msing.\rle timade\r_SSLhe tring- They emu\r\nnn’t!sapet, bositeliver. Ydafhere vore gess-leen hen h! Jstancncidive n_ss(en thaut p periaps,_i_issiphe cun the fter-\nChr\nthe u",
+ "chars_per_s": 2172.9409935429944,
+ "distinct1": 0.9345794392523364,
+ "distinct2": 1.0
+ },
+ "french": {
+ "prompt": "Il etait une fois un ",
+ "output": "Il etait une fois un elp!igh\n awouicknhelvis fether- wortours!’p\ndid.not! so,. D’t ik_clofictchestlivy\r\nw Ba dex.1')n, knputang l'\n f wish alm hid forae ouv of uhe bea.\r\nUhere vas a-cornf thimp, cut isedy ’t so are a moud\rnoose. Mis eall pas\r\npoftlned b livtle'by uhe cerpes, an� Guegon’p bagk wes alro mire\r\ndlastec tyan ha hagestat\"ilter, wiich lade whe snund huffied amd nit tog\r\nooticiabli. Oe hed nit he\rd hos he\r_Duy_lly jnou,h, yhounh, g Bahieuon i. Dm ofvenuht ouentithe b spe theee\r\nvessemderstond a[een;d oncppedhrowver�ite �t heu beiavinultF\non burn sordu at �hich'o nwhiph won ho, pate ancin cm anvill g he yter!e to?s healn',\n ance\rireb fortble usistaront\rhile s",
+ "chars_per_s": 2259.7068891836366,
+ "distinct1": 0.9473684210526315,
+ "distinct2": 1.0
+ }
+ },
+ "efficiency": {
+ "synaptic_macs_per_token": {
+ "input_gather": 6144,
+ "recurrent": 262144,
+ "readout_fast": 8388608,
+ "readout_slow_amortized": 548896.0,
+ "total_per_token": 9205792.0
+ },
+ "vs_transformer_reference": {
+ "gpt2_small_params": 124000000.0,
+ "gpt2_train_flops_per_token": 744000000.0,
+ "spira_vs_gpt2_ops_ratio": 0.012373376344086022
+ }
+ },
+ "prediction": {
+ "spira_test": {
+ "n_positions": 60000,
+ "vocab_coverage": 0.7062833333333334,
+ "snn_acc": 0.003416666666666667,
+ "hier_acc": 0.0034333333333333334,
+ "am_acc": 0.0020666666666666667,
+ "fused_acc": 0.00515,
+ "snn_acc_invocab": 0.004837529792104208,
+ "hier_acc_invocab": 0.004861127498407155,
+ "am_acc_invocab": 0.0025721499870212617,
+ "fused_acc_invocab": 0.007291691247610733,
+ "corrupt_lanes": 0
+ },
+ "spira_trained_region": {
+ "n_positions": 8000,
+ "vocab_coverage": 0.7395,
+ "snn_acc": 0.117125,
+ "hier_acc": 0.116,
+ "am_acc": 0.9765,
+ "fused_acc": 0.9775,
+ "snn_acc_invocab": 0.1583840432724814,
+ "hier_acc_invocab": 0.1568627450980392,
+ "am_acc_invocab": 0.9763353617308993,
+ "fused_acc_invocab": 0.9776876267748479,
+ "corrupt_lanes": 0
+ },
+ "unigram_acc": 0.0003282670780947379,
+ "bigram_acc": 0.07668318944293077,
+ "n_baseline_positions": 30463,
+ "note": "baselines evaluated on in-vocab target positions of the same stream; compare with spira_test.*_invocab"
+ },
+ "correction_sparse_am": {
+ "corrupt_0_of_4": {
+ "am_acc": 0.997875,
+ "am_acc_invocab": 0.9979459089352961,
+ "fused_acc": 0.997875
+ },
+ "corrupt_1_of_4": {
+ "am_acc": 0.99,
+ "am_acc_invocab": 0.9892160219103047,
+ "fused_acc": 0.722875
+ },
+ "corrupt_2_of_4": {
+ "am_acc": 0.000625,
+ "am_acc_invocab": 0.0005135227661759672,
+ "fused_acc": 0.000625
+ },
+ "corrupt_3_of_4": {
+ "am_acc": 0.0,
+ "am_acc_invocab": 0.0,
+ "fused_acc": 0.00025
+ },
+ "note": "corrupted-cue completion with a fresh hippocampus (book only, ~0 load); the main 'correction' section reports the deployed state (corpus AM at 46% load). v1's 92% was measured in this sparse regime by accident (broken checkpoint format emptied the loaded corpus AM)."
+ }
+}
\ No newline at end of file
diff --git a/results/hashing/lever2/code/python/artifacts/metrics_v3_ab.json b/results/hashing/lever2/code/python/artifacts/metrics_v3_ab.json
new file mode 100644
index 0000000000000000000000000000000000000000..d916442318e804fc14b6c9cb865b1ed82ccb7159
--- /dev/null
+++ b/results/hashing/lever2/code/python/artifacts/metrics_v3_ab.json
@@ -0,0 +1,120 @@
+{
+ "experiment": "SPIRA v3 cortex representation repair \u2014 controlled A/B vs v2 baseline",
+ "date": "2026-10-22",
+ "protocol": {
+ "corpus": "same rebuilt corpus for both arms (train 13.27 MB / test 640 KB)",
+ "vocab_size": 4096,
+ "snn_tokens": 200000,
+ "epochs": 2,
+ "am_contexts": 50000,
+ "test_positions": 20000,
+ "vocab_coverage_test": 0.4524,
+ "headline_metric": "SNN alone, in-vocab accuracy on held-out test positions",
+ "bigram_reference": "patch bigram trained on train cols [0:600k], evaluated on exactly the same test positions at the same vocab 4096"
+ },
+ "headline": {
+ "snn_invocab_test_v2_baseline": 0.003978779840848806,
+ "snn_invocab_test_v3": 0.020667550839964632,
+ "ratio_v3_over_v2": "x5.2",
+ "bigram_4096_invocab_test": 0.04940318302387268,
+ "gap_to_bigram": "x12.4 (v2) -> x2.4 (v3); beat-the-bigram criterion NOT met",
+ "snn_invocab_trained_region_v2_baseline": 0.0376034093757834,
+ "snn_invocab_trained_region_v3": 0.1328653797944347,
+ "training_speed_tps_v2_baseline": "~530 (512.6 / 561.8 per epoch)",
+ "training_speed_tps_v3": 188.97756640356553,
+ "checkpoint_mb_v2_baseline": 14.6,
+ "checkpoint_mb_v3": 45.9,
+ "notes": [
+ "Free generation still incoherent in both arms.",
+ "At this small budget, fusion hurts on held-out: v3 fused in-vocab 0.001326259946949602 < SNN alone 0.020667550839964632."
+ ]
+ },
+ "bigram_reference_detail": {
+ "bigram_4096_invocab_test20k": 0.04940318302387268,
+ "n_invocab": 9048
+ },
+ "baseline_arm_full": {
+ "label": "baseline",
+ "hist": [
+ {
+ "acc": 0.092515,
+ "acc_fast": 0.112785,
+ "tps": 512.6229927407619
+ },
+ {
+ "acc": 0.065475,
+ "acc_fast": 0.101045,
+ "tps": 561.7816027951075
+ }
+ ],
+ "test": {
+ "n_positions": 20000,
+ "vocab_coverage": 0.4524,
+ "snn_acc": 0.0018,
+ "hier_acc": 0.00025,
+ "am_acc": 0.0001,
+ "fused_acc": 0.00035,
+ "snn_acc_invocab": 0.003978779840848806,
+ "hier_acc_invocab": 0.0005526083112290009,
+ "am_acc_invocab": 0.00022104332449160034,
+ "fused_acc_invocab": 0.0007736516357206013,
+ "corrupt_lanes": 0
+ },
+ "trained": {
+ "n_positions": 8000,
+ "vocab_coverage": 0.498625,
+ "snn_acc": 0.01875,
+ "hier_acc": 0.00675,
+ "am_acc": 0.011125,
+ "fused_acc": 0.017375,
+ "snn_acc_invocab": 0.0376034093757834,
+ "hier_acc_invocab": 0.013537227375282025,
+ "am_acc_invocab": 0.01779894710453748,
+ "fused_acc_invocab": 0.030834795688142392,
+ "corrupt_lanes": 0
+ },
+ "gen": "The old man looked at the retuiltIN S .\n IN S add\n r ifotIthing beithingtory rethingeek eIGHTND RIGHT it athingthingthing if t:\n #irlother:\n #\n f\n \" andeturotIe)\n a s\n fone)Imone)e the .\n .\n thingotICAPef g if##########IGHTtry: lf._lf._otI iflear a singl"
+ },
+ "v3_arm_full": {
+ "label": "v3",
+ "hist": [
+ {
+ "acc": 0.120205,
+ "acc_fast": 0.142835,
+ "tps": 188.97756640356553
+ },
+ {
+ "acc": 0.11196,
+ "acc_fast": 0.15781,
+ "tps": 188.5136375504029
+ }
+ ],
+ "test": {
+ "n_positions": 20000,
+ "vocab_coverage": 0.4524,
+ "snn_acc": 0.00935,
+ "hier_acc": 0.0005,
+ "am_acc": 0.0001,
+ "fused_acc": 0.0006,
+ "snn_acc_invocab": 0.020667550839964632,
+ "hier_acc_invocab": 0.0011052166224580018,
+ "am_acc_invocab": 0.00022104332449160034,
+ "fused_acc_invocab": 0.001326259946949602,
+ "corrupt_lanes": 0
+ },
+ "trained": {
+ "n_positions": 8000,
+ "vocab_coverage": 0.498625,
+ "snn_acc": 0.06625,
+ "hier_acc": 0.005375,
+ "am_acc": 0.011125,
+ "fused_acc": 0.015875,
+ "snn_acc_invocab": 0.1328653797944347,
+ "hier_acc_invocab": 0.010779644021057909,
+ "am_acc_invocab": 0.01779894710453748,
+ "fused_acc_invocab": 0.02782652293807972,
+ "corrupt_lanes": 0
+ },
+ "gen": "The old man looked at the rrorone\nr hi \n r hi r hiand a a l on ar hi\n on alooloor hiloolectueEloo looynon at see a slectlectlector\non a##########yn a s##########ramelooErlooow, golectlectErlooow,loo.\n .\n lect lectlect rameloo a s"
+ }
+}
\ No newline at end of file
diff --git a/results/hashing/lever2/code/python/scripts/bench_vocab.py b/results/hashing/lever2/code/python/scripts/bench_vocab.py
new file mode 100644
index 0000000000000000000000000000000000000000..4fdc0358acda753d243a7cae04da6294bd5a66fc
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/bench_vocab.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+"""Benchmark per-tick training cost vs readout vocab size (decides 8k vs 16k)."""
+import sys
+import time
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+
+import numpy as np
+
+from spira.spiking import SpikingCore
+
+rng = np.random.default_rng(0)
+T = 3000
+
+for V in (4097, 8193, 16385):
+ core = SpikingCore(d_in=1024, k_in=12, n_res=512, n_out=V, seed=1)
+ neurons = rng.integers(0, 1024, size=(T, 12)).astype(np.int32)
+ cols = rng.integers(0, V - 1, size=T).astype(np.int64)
+ core.train_pass(neurons[:200], cols[:200]) # warm-up
+ t0 = time.perf_counter()
+ core.train_pass(neurons, cols)
+ dt = time.perf_counter() - t0
+ print(f"n_out={V:>6}: {T/dt:7.0f} ticks/s ({dt/T*1000:.2f} ms/tick) "
+ f"-> 250k ticks = {250_000/(T/dt)/60:.1f} min")
diff --git a/results/hashing/lever2/code/python/scripts/correction_sparse_probe.py b/results/hashing/lever2/code/python/scripts/correction_sparse_probe.py
new file mode 100644
index 0000000000000000000000000000000000000000..d46c856396e75d035593ea3271ebfec225706189
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/correction_sparse_probe.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+"""Corrupted-cue completion with a SPARSE hippocampus (book only, no corpus load).
+
+The main correction metrics are measured with the full corpus AM (46% load
+factor) — the deployed state. This probe measures the capacity-to-spare
+regime (fresh AM + only the taught book) that v1 accidentally measured via
+its broken AM checkpoint format. Both are honest numbers for different
+memory loads; the paper reports both.
+"""
+import sys
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+
+import numpy as np
+
+from spira import SPIRA
+from spira.hippocampus import Hippocampus
+
+BASE = "/home/z/my-project"
+m = SPIRA.load(f"{BASE}/download/spira/artifacts/spira_model.npz")
+m.am = Hippocampus(m=m.cfg.am_m, size=m.cfg.am_size, min_lanes=m.cfg.am_min_lanes)
+
+oneshot = open(f"{BASE}/data/oneshot.bin", "rb").read()
+book = oneshot[:60_000]
+taught = m.teach_bytes(book)
+print(f"taught {taught['tokens']} tokens into a fresh AM "
+ f"({m.am.stats()['load_factor']:.4f} load)")
+
+out = {}
+for k in (0, 1, 2, 3):
+ r = m.eval_stream(book, corrupt_lanes=k, max_positions=8_000)
+ out[f"corrupt_{k}_of_4"] = {kk: r[kk] for kk in ("am_acc", "am_acc_invocab", "fused_acc")}
+ print(f" corrupt {k}/4 lanes (sparse AM): am={r['am_acc']:.4f} fused={r['fused_acc']:.4f}")
+
+import json
+mp = f"{BASE}/download/spira/artifacts/metrics.json"
+metrics = json.load(open(mp))
+metrics["correction_sparse_am"] = {
+ **out,
+ "note": "corrupted-cue completion with a fresh hippocampus (book only, ~0 load); "
+ "the main 'correction' section reports the deployed state (corpus AM at "
+ "46% load). v1's 92% was measured in this sparse regime by accident "
+ "(broken checkpoint format emptied the loaded corpus AM).",
+}
+json.dump(metrics, open(mp, "w"), indent=2, ensure_ascii=False)
+print("saved -> metrics['correction_sparse_am']")
diff --git a/results/hashing/lever2/code/python/scripts/make_figures.py b/results/hashing/lever2/code/python/scripts/make_figures.py
new file mode 100644
index 0000000000000000000000000000000000000000..82afeb1ad9a96609e8ddca9a4f523b35f3b5034e
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/make_figures.py
@@ -0,0 +1,209 @@
+#!/usr/bin/env python3
+"""Generate all paper figures from real experiment artifacts."""
+import json
+import sys
+
+import numpy as np
+
+import os as _os
+ROOT = _os.path.dirname(_os.path.dirname(_os.path.abspath(__file__)))
+ART = f"{ROOT}/artifacts"
+sys.path.insert(0, ROOT)
+
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.font_manager as fm
+fm.fontManager.addfont('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf')
+import matplotlib.pyplot as plt
+plt.rcParams.update({
+ "font.family": "DejaVu Sans",
+ "font.size": 9,
+ "axes.spines.top": False,
+ "axes.spines.right": False,
+ "axes.grid": True,
+ "grid.alpha": 0.25,
+ "figure.dpi": 200,
+})
+
+OUT = f"{ART}/figures"
+import os
+os.makedirs(OUT, exist_ok=True)
+
+metrics = json.load(open(f"{ART}/metrics.json"))
+ACCENT = "#2e7d5b"
+ACCENT2 = "#b8860b"
+GRAY = "#666666"
+
+# ---------------------------------------------------------------- fig: EPT
+from spira import SPIRA
+model = SPIRA.load(f"{ART}/spira_model.npz")
+sample = (b"It was the best of times, it was the worst of times, it was the age "
+ b"of wisdom, it was the age of foolishness, it was the epoch of belief, "
+ b"it was the epoch of incredulity, it was the season of Light, "
+ b"it was the season of Darkness")
+sur = model.ept.surprise(sample)
+patches = model.ept.segment(sample)
+fig, axes = plt.subplots(2, 1, figsize=(7.0, 3.2), height_ratios=[1.2, 1],
+ constrained_layout=True, sharex=True)
+axes[0].fill_between(range(len(sur)), sur, color=ACCENT, alpha=0.55, step="mid")
+axes[0].plot(range(len(sur)), sur, color=ACCENT, lw=0.8)
+axes[0].set_ylabel("surprisal (bits)")
+axes[0].set_title("EPT: per-byte surprisal and constant-information patch boundaries", fontsize=9)
+b = model.ept.boundaries(sample)
+for bx in b[:-1]:
+ axes[0].axvline(bx, color=ACCENT2, lw=0.7, alpha=0.85)
+# patch length bars
+axes[1].bar(b[:-1], [b[i+1]-b[i] for i in range(len(b)-1)], width=1.0,
+ color=ACCENT, alpha=0.7, align="edge")
+axes[1].axhline(float(np.mean([b[i+1]-b[i] for i in range(len(b)-1)])),
+ color=ACCENT2, lw=1, ls="--", label=f"mean {np.mean([b[i+1]-b[i] for i in range(len(b)-1)]):.1f} B")
+axes[1].set_xlabel("byte position")
+axes[1].set_ylabel("patch length (B)")
+axes[1].legend(frameon=False, fontsize=8)
+fig.savefig(f"{OUT}/fig_ept.pdf")
+plt.close(fig)
+print("fig_ept done:", len(patches), "patches, avg", np.mean([len(p) for p in patches]))
+
+# ------------------------------------------------------- fig: compression
+comp = metrics["compression"]
+methods = ["gzip -9", "BPE-4k\n(unigram)", "BPE-4k\n(bigram)", "BPE-16k\n(bigram)", "EPT\n(bigram)", "EPT\n(unigram)"]
+vals = [comp["gzip"]["bits_per_byte"],
+ comp["bpe_4096"]["bits_per_byte_unigram"],
+ comp["bpe_4096"]["bits_per_byte_bigram"],
+ comp["bpe_16384"]["bits_per_byte_bigram"],
+ comp["ept"]["bits_per_byte_bigram"],
+ comp["ept"]["bits_per_byte_unigram"]]
+colors = [GRAY, "#9aa5b1", "#9aa5b1", "#9aa5b1", ACCENT, ACCENT]
+fig, ax = plt.subplots(figsize=(4.6, 2.9), constrained_layout=True)
+bars = ax.bar(range(len(vals)), vals, color=colors, width=0.65)
+for i, v in enumerate(vals):
+ ax.text(i, v + 0.08, f"{v:.2f}", ha="center", fontsize=8)
+ax.set_xticks(range(len(methods)))
+ax.set_xticklabels(methods, fontsize=7.5)
+ax.set_ylabel("bits per byte (with dictionary)")
+ax.set_title("Coded size on the held-out test stream", fontsize=9)
+fig.savefig(f"{OUT}/fig_compression.pdf")
+plt.close(fig)
+print("fig_compression done")
+
+# -------------------------------------------------- fig: one-shot+corrupt
+one = metrics["one_shot"]
+corr = metrics["correction"]
+corr_sp = metrics.get("correction_sparse_am", {})
+ks = [0, 1, 2, 3]
+am_curve = [corr[f"corrupt_{k}_of_4"]["am_acc"] for k in ks]
+fig, ax = plt.subplots(figsize=(4.6, 2.9), constrained_layout=True)
+ax.plot(ks, [v * 100 for v in am_curve], "o-", color=ACCENT, lw=1.6,
+ label="full hippocampus (46% load)")
+if corr_sp:
+ am_sp = [corr_sp[f"corrupt_{k}_of_4"]["am_acc"] for k in ks]
+ ax.plot(ks, [v * 100 for v in am_sp], "s--", color=ACCENT2, lw=1.4,
+ label="sparse hippocampus (book only)")
+ for k, v in zip(ks, am_sp):
+ ax.annotate(f"{v*100:.1f}%", (k, v * 100), textcoords="offset points",
+ xytext=(0, 7), ha="center", fontsize=8, color=ACCENT2)
+for k, v in zip(ks, am_curve):
+ ax.annotate(f"{v*100:.1f}%", (k, v * 100), textcoords="offset points",
+ xytext=(0, -13), ha="center", fontsize=8)
+ax.set_xlabel("corrupted context slots (of 4)")
+ax.set_ylabel("exact recall (%)")
+ax.set_ylim(-14, 110)
+ax.set_xticks(ks)
+ax.set_title("Pattern completion under context corruption\n(completion trades against hippocampal load)", fontsize=9)
+ax.legend(frameon=False, fontsize=8, loc="center right")
+fig.savefig(f"{OUT}/fig_correction.pdf")
+plt.close(fig)
+print("fig_correction done:", am_curve)
+
+# ------------------------------------------------- fig: vocab coverage
+vc = metrics["vocab_coverage_curve"]
+vs = [c["vocab"] for c in vc]
+ct = [c["cov_test"] * 100 for c in vc]
+co = [c["cov_oneshot"] * 100 for c in vc]
+fig, ax = plt.subplots(figsize=(4.6, 2.9), constrained_layout=True)
+ax.plot(vs, ct, "o-", color=ACCENT, lw=1.6, ms=3.5, label="held-out test")
+ax.plot(vs, co, "s-", color=ACCENT2, lw=1.4, ms=3.5, label="unseen book (one-shot)")
+ax.axvline(4096, color=GRAY, lw=0.9, ls=":")
+ax.text(4096 * 1.06, 88, "v1: 4096", fontsize=7.5, color=GRAY)
+ax.axvline(16384, color=GRAY, lw=0.9, ls=":")
+ax.text(16384 * 1.06, 88, "v2: 16384", fontsize=7.5, color=GRAY)
+ax.annotate(f"{ct[-1]:.1f}%", (vs[-1], ct[-1]), textcoords="offset points",
+ xytext=(2, 6), fontsize=8)
+ax.set_xscale("log", base=2)
+ax.set_xticks(vs)
+ax.set_xticklabels([str(v) for v in vs], fontsize=7.5)
+ax.set_xlabel("readout vocabulary size (top-V by train frequency)")
+ax.set_ylabel("held-out target coverage (%)")
+ax.set_title("Zipf knee of the readout vocabulary\n(constant-information patches flatten the tail)", fontsize=9)
+ax.legend(frameon=False, fontsize=8, loc="lower right")
+fig.savefig(f"{OUT}/fig_vocab.pdf")
+plt.close(fig)
+print("fig_vocab done")
+
+# ------------------------------------------------- fig: replay consolidation
+rep = metrics["replay"]
+xs = [0] + [c["replayed_tokens"] for c in rep["curve"]]
+ys = [rep["before"]["hier_acc"] * 100] + [c["hier_acc"] * 100 for c in rep["curve"]]
+ysi = [rep["before"]["hier_acc_invocab"] * 100] + [c["hier_acc_invocab"] * 100 for c in rep["curve"]]
+fig, ax = plt.subplots(figsize=(4.9, 3.0), constrained_layout=True)
+ax.plot(xs, ys, "o-", color=ACCENT, lw=1.6, ms=3.5, label="cortex-only recall")
+ax.plot(xs, ysi, "s--", color=ACCENT2, lw=1.4, ms=3.2, label="cortex-only, in-vocab only")
+ax.axhline(rep["am_recall_after_replay"]["am_acc"] * 100, color=GRAY, lw=1.1, ls=":")
+ax.text(xs[-1] * 0.06, rep["am_recall_after_replay"]["am_acc"] * 100 - 4.5,
+ f"hippocampus (unchanged): {rep['am_recall_after_replay']['am_acc']*100:.1f}%",
+ fontsize=7.5, color=GRAY)
+ax.axhline(rep["after"]["hier_acc"] * 100, color=ACCENT, lw=0.8, ls="--", alpha=0.5)
+ax.annotate(f"full eval after replay: {rep['after']['hier_acc']*100:.1f}%\n"
+ f"(in-vocab {rep['after']['hier_acc_invocab']*100:.1f}%)",
+ (xs[-1], rep["after"]["hier_acc"] * 100), textcoords="offset points",
+ xytext=(-96, 6), fontsize=7.5, color=ACCENT)
+ax.set_xlabel("hippocampal tokens replayed through the cortex")
+ax.set_ylabel("exact next-patch recall (%)")
+ax.set_title("Systems consolidation: the cortex learns the book\nonly through hippocampal replay (never seen awake)", fontsize=9)
+ax.legend(frameon=False, fontsize=8, loc="center right")
+fig.savefig(f"{OUT}/fig_replay.pdf")
+plt.close(fig)
+print("fig_replay done")
+
+# ------------------------------------------------------------ fig: raster
+z = np.load(f"{ART}/spira_model.npz.raster.npz")
+ticks, neurons = z["ticks"], z["neurons"]
+fig, ax = plt.subplots(figsize=(6.8, 2.7), constrained_layout=True)
+ax.scatter(ticks, neurons, s=0.55, c=ACCENT, linewidths=0)
+ax.axhline(512 * 0.8, color=ACCENT2, lw=0.8, ls="--")
+ax.text(5, 512 * 0.8 + 6, "inhibitory population (Dale's law)", fontsize=7, color=ACCENT2)
+ax.set_xlabel("tick (token)")
+ax.set_ylabel("reservoir neuron")
+ax.set_title(f"Spike raster — {len(ticks)} spikes over 1500 ticks "
+ f"({len(ticks)/1500:.0f} spikes/tick)", fontsize=9)
+fig.savefig(f"{OUT}/fig_raster.pdf")
+plt.close(fig)
+print("fig_raster done")
+
+# ------------------------------------------------- fig: learning curve
+import glob
+logs = []
+for line in open(f"{ART}/chunks.jsonl"):
+ try:
+ logs.append(json.loads(line))
+ except Exception:
+ pass
+# training acc EMAs were logged inside msg lines; rebuild a coarse curve from
+# chunk results recorded in the metrics/history + chunks.jsonl messages
+accs = []
+for e in logs:
+ if "acc=" in e.get("msg", ""):
+ try:
+ accs.append(float(e["msg"].split("acc=")[1].split()[0]))
+ except Exception:
+ pass
+fig, ax = plt.subplots(figsize=(4.6, 2.9), constrained_layout=True)
+if accs:
+ xs = np.arange(len(accs)) * 25000
+ ax.plot(xs, [a * 100 for a in accs], "-", color=ACCENT, lw=1.4)
+ ax.set_xlabel("tick (token)")
+ ax.set_ylabel("online next-patch accuracy (%)")
+ ax.set_title("Online learning during training (vocab-masked, incl. UNK targets)", fontsize=9)
+fig.savefig(f"{OUT}/fig_learning.pdf")
+plt.close(fig)
+print("fig_learning done:", len(accs), "points")
diff --git a/results/hashing/lever2/code/python/scripts/overfit_test.py b/results/hashing/lever2/code/python/scripts/overfit_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..23c9be2af4ec4f1c2e7a8454ae67b8836da263ac
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/overfit_test.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+"""Definitive mechanics test: can the three-factor readout overfit a
+deterministic toy mapping? Separates mechanism bugs from data statistics."""
+import sys
+
+import numpy as np
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+from spira.hashing import input_neurons
+from spira.spiking import SpikingCore
+
+rng = np.random.default_rng(7)
+N_TOKENS = 64
+d_in, k_in = 1024, 12
+
+# deterministic toy: token i is always followed by token (i*7+3) % 64
+patterns = [np.asarray(input_neurons(i * 0x9E3779B97F4A7C15 % (1 << 64), d_in, k_in), dtype=np.int32)
+ for i in range(N_TOKENS)]
+next_of = [(i * 7 + 3) % N_TOKENS for i in range(N_TOKENS)]
+
+core = SpikingCore(n_out=N_TOKENS, seed=20261022,
+ w_in_scale=3.0, in_fanout=8, w_rec_scale=0.25, rec_fanout=24,
+ inh_frac=0.5, eta_pos=0.02, eta_r=0.0)
+
+T = 20_000
+seq = [0]
+for _ in range(T):
+ seq.append(next_of[seq[-1]])
+correct_ema = None
+for ep in range(1):
+ core.reset()
+ n_ok = 0
+ for t in range(T):
+ x = core.step(patterns[seq[t]])
+ u = (x - core.x_mean) @ core.W_out
+ pred = int(np.argmax(u))
+ ok = pred == next_of[seq[t]]
+ n_ok += ok
+ r = 1.0 if ok else 0.0
+ core.baseline = 0.995 * core.baseline + 0.005 * r
+ d = r - core.baseline
+ x_eff = x - core.x_mean
+ W = core.W_out
+ W[:, next_of[seq[t]]] += np.float32(core.eta_pos) * x_eff
+ W[:, pred] += np.float32(core.eta_r * d) * x_eff
+ correct_ema = r if correct_ema is None else 0.995 * correct_ema + 0.005 * r
+ if (t + 1) % 5000 == 0:
+ print(f" tick {t+1}: acc={n_ok/(t+1):.3f} ema={correct_ema:.3f}")
+
+# how stable is the state for the same token? (same-token x overlap)
+core.reset()
+xs = {}
+for t in range(4000):
+ x = core.step(patterns[seq[t]])
+ xs.setdefault(seq[t], []).append(x.copy())
+tok = max(xs, key=lambda k: len(xs[k]))
+if len(xs[tok]) >= 2:
+ a, b = xs[tok][0], xs[tok][-1]
+ cos = float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b) + 1e-9))
+ print(f"same-token cosine similarity: {cos:.3f} (n={len(xs[tok])})")
+diff = [k for k in xs if k != tok][0]
+c2 = float(np.dot(xs[tok][0], xs[diff][0]) / (np.linalg.norm(xs[tok][0]) * np.linalg.norm(xs[diff][0]) + 1e-9))
+print(f"diff-token cosine similarity: {c2:.3f}")
diff --git a/results/hashing/lever2/code/python/scripts/post_train_probe.py b/results/hashing/lever2/code/python/scripts/post_train_probe.py
new file mode 100644
index 0000000000000000000000000000000000000000..401919fb5498d6112c1d2a4629c229338501440b
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/post_train_probe.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+"""Post-training sanity: hierarchy ablation + generation quality."""
+import sys
+import time
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+
+from spira import SPIRA
+
+BASE = "/home/z/my-project"
+m = SPIRA.load(f"{BASE}/download/spira/artifacts/spira_model.npz")
+print(f"vocab={m.cfg.vocab_size} hier={m.core.hier} beta={m.core.beta:.3f} "
+ f"thr_G={float(m.core.thr_G.mean()):.3f} rhat_G={float(m.core.rhat_G.mean()):.3f}")
+
+m._ids_train = None
+train = open(f"{BASE}/data/train.bin", "rb").read()
+test = open(f"{BASE}/data/test.bin", "rb").read()
+
+import numpy as np
+from spira.hashing import fnv1a64
+ids = np.fromiter((fnv1a64(p) for p in m.ept.segment(train)), dtype=np.uint64, count=len(m.ept.segment(train)))
+m._ids_train = ids
+
+for name, data, pos in [("train-region", train[10_000_000:10_200_000], 5000),
+ ("test", test[:200_000], 8000)]:
+ ev = m.eval_stream(data, max_positions=pos)
+ print(f"{name}: cov={ev['vocab_coverage']:.3f} fast={ev['snn_acc']:.4f} "
+ f"hier={ev['hier_acc']:.4f} am={ev['am_acc']:.4f} fused={ev['fused_acc']:.4f} "
+ f"| invocab: fast={ev['snn_acc_invocab']:.4f} hier={ev['hier_acc_invocab']:.4f} "
+ f"am={ev['am_acc_invocab']:.4f}")
+
+t0 = time.perf_counter()
+g = m.generate(b"The old man looked at the ", n_tokens=120, temperature=0.7, seed=42)
+dt = time.perf_counter() - t0
+print(f"\ngeneration ({len(g)} B, {len(g)/max(dt,1e-9):.0f} B/s):")
+print(g.decode("utf-8", "replace")[:400])
+g2 = m.generate(b"def process(data):\n ", n_tokens=100, temperature=0.7, seed=7)
+print("\ncode:", g2.decode("utf-8", "replace")[:300])
diff --git a/results/hashing/lever2/code/python/scripts/probe_ab.py b/results/hashing/lever2/code/python/scripts/probe_ab.py
new file mode 100644
index 0000000000000000000000000000000000000000..94d96630c975c9928f1690aa4deb7fa1c5f16613
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/probe_ab.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+"""A/B test: ORIGINAL reservoir params (rich recurrent states) with honest
+vocab-masked metrics, with/without trace centering, various eta_r."""
+import sys
+
+import numpy as np
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+from spira import SPIRA, SPIRAConfig
+from spira.spiking import SpikingCore
+
+data = open("/home/z/my-project/data/train.bin", "rb").read()
+cfg = SPIRAConfig(snn_tokens=60_000, am_tokens=1000, epochs=1)
+model = SPIRA.build(data, cfg, log=lambda m: None)
+ids = model._ids_train
+N = 60_000
+neurons = SPIRA.input_neurons_stream(ids[:N], cfg.d_in, cfg.k_in)
+cols = model.cols_of(ids[: N + 1])
+cov = (cols[1:] != cfg.vocab_size)[: N - 1].mean()
+print(f"coverage: {cov:.3f}")
+
+# ORIGINAL params that reached EMA 0.52-0.82 (with the UNK shortcut metric)
+variants = [
+ ("sharp+delta e=.70", dict(w_in_scale=3.0, in_fanout=8, w_rec_scale=0.25, rec_fanout=24, inh_frac=0.5, eta_delta=0.70), True),
+ ("sharp+delta e=1.0", dict(w_in_scale=3.0, in_fanout=8, w_rec_scale=0.25, rec_fanout=24, inh_frac=0.5, eta_delta=1.0), True),
+ ("sharp+delta e=1.5", dict(w_in_scale=3.0, in_fanout=8, w_rec_scale=0.25, rec_fanout=24, inh_frac=0.5, eta_delta=1.5), True),
+ ("sharp+delta e=1.0 tau.3", dict(w_in_scale=3.0, in_fanout=8, w_rec_scale=0.25, rec_fanout=24, inh_frac=0.5, eta_delta=1.0, tau_trace=0.35), True),
+]
+for name, kw, center in variants:
+ core = SpikingCore(n_out=cfg.vocab_size + 1, seed=cfg.seed, **kw)
+ if not center:
+ # disable centering by pinning x_mean to zero
+ class NoCenter:
+ pass
+ core._center = False
+ orig_step = core.step
+ import types
+ # monkeypatch: after step, reset x_mean to 0
+ def step_noc(self, input_idx, _orig=orig_step):
+ x = _orig(input_idx)
+ self.x_mean = np.zeros_like(self.x_mean)
+ return x
+ core.step = types.MethodType(step_noc, core)
+ res = core.train_pass(neurons[: N - 1], cols[1:N], log_every=30_000, log_fn=lambda d: None)
+ print(f"{name:28s} overall={res['accuracy']:.4f} in-vocab~={res['accuracy']/cov:.4f} "
+ f"ema={res['acc_ema_final']:.4f}")
diff --git a/results/hashing/lever2/code/python/scripts/probe_hyper.py b/results/hashing/lever2/code/python/scripts/probe_hyper.py
new file mode 100644
index 0000000000000000000000000000000000000000..ffcc7add9d4d7767276fb77603e4c445ba49d198
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/probe_hyper.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+"""Quick hyperparameter probe for the three-factor rule (40k ticks each)."""
+import sys
+import time
+
+import numpy as np
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+from spira import SPIRA, SPIRAConfig
+from spira.hashing import fnv1a64
+from spira.spiking import SpikingCore
+
+data = open("/home/z/my-project/data/train.bin", "rb").read()
+cfg = SPIRAConfig(snn_tokens=40_000, am_tokens=1000, epochs=1)
+model = SPIRA.build(data, cfg, log=lambda m: None)
+ids = model._ids_train
+N = 40_000
+
+neurons = SPIRA.input_neurons_stream(ids[:N], cfg.d_in, cfg.k_in)
+cols = model.cols_of(ids[: N + 1])
+inv_mask = (cols[1:] != cfg.vocab_size)[: N - 1]
+print(f"coverage: {inv_mask.mean():.3f}")
+
+variants = [
+ ("eta_r=0.010 d-full", 0.010, -1.0),
+ ("eta_r=0.001 d-full", 0.001, -1.0),
+ ("eta_r=0.010 d>=-0.25", 0.010, -0.25),
+ ("eta_r=0.000 pure-inst", 0.000, 0.0),
+]
+for name, eta_r, d_floor in variants:
+ core = SpikingCore(n_out=cfg.vocab_size + 1, seed=cfg.seed, eta_r=eta_r)
+ # monkeypatch learn with d floor
+ orig_learn = core.learn
+ def learn(pred, target, x, core=core, floor=d_floor, orig=orig_learn):
+ # replicate learn() but with d floor on the chosen-column update
+ correct = 1 if pred == target else 0
+ reward = float(correct)
+ core.baseline = core.baseline_momentum * core.baseline + (1 - core.baseline_momentum) * reward
+ d = reward - core.baseline
+ W_out = core.W_out
+ if target != core.n_out - 1:
+ W_out[:, target] += np.float32(core.eta_pos) * x
+ d_eff = d if d > 0 else max(d, floor)
+ W_out[:, pred] += np.float32(core.eta_r * d_eff) * x
+ np.clip(W_out[:, target], -core.w_clip, core.w_clip, out=W_out[:, target])
+ np.clip(W_out[:, pred], -core.w_clip, core.w_clip, out=W_out[:, pred])
+ if core.s.any():
+ spiked = np.nonzero(core.s)[0]
+ W_rec = core.W_rec
+ delta = np.float32(core.eta_stdp * d)
+ W_rec[:, spiked] += delta * core.x_prev[:, None]
+ np.clip(W_rec[:, spiked], core._rec_lo[:, None], core._rec_hi[:, None],
+ out=W_rec[:, spiked])
+ return correct, reward, d
+ core.learn = learn
+ t0 = time.perf_counter()
+ res = core.train_pass(neurons[: N - 1], cols[1:N], log_every=10_000, log_fn=lambda d: None)
+ # in-vocab accuracy measured inline: recompute via final pass? use overall + coverage
+ overall = res["accuracy"]
+ print(f"{name:24s} overall={overall:.4f} in-vocab~={overall/max(inv_mask.mean(),1e-9):.4f} "
+ f"({res['ticks_per_sec']:.0f} t/s)")
diff --git a/results/hashing/lever2/code/python/scripts/probe_input.py b/results/hashing/lever2/code/python/scripts/probe_input.py
new file mode 100644
index 0000000000000000000000000000000000000000..3e483df6f81d63e4465f41f0e9ce325c3ecb99f7
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/probe_input.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+"""Probe: sharp sparse input drive -> token-discriminative spike patterns."""
+import sys
+
+import numpy as np
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+from spira import SPIRA, SPIRAConfig
+from spira.spiking import SpikingCore
+
+data = open("/home/z/my-project/data/train.bin", "rb").read()
+cfg = SPIRAConfig(snn_tokens=40_000, am_tokens=1000, epochs=1)
+model = SPIRA.build(data, cfg, log=lambda m: None)
+ids = model._ids_train
+N = 40_000
+neurons = SPIRA.input_neurons_stream(ids[:N], cfg.d_in, cfg.k_in)
+cols = model.cols_of(ids[: N + 1])
+cov = (cols[1:] != cfg.vocab_size)[: N - 1].mean()
+print(f"coverage: {cov:.3f}")
+
+variants = [
+ # (w_in_scale, in_fanout, w_rec_scale, rec_fanout, inh_frac)
+ (3.0, 8, 0.35, 48, 0.50),
+ (2.5, 12, 0.35, 48, 0.50),
+ (4.0, 8, 0.35, 48, 0.50),
+ (3.0, 8, 0.25, 24, 0.50),
+ (5.0, 6, 0.35, 48, 0.50),
+]
+
+def pattern_discrimination(core, neurons, n=400, stride=17):
+ """Mean Jaccard overlap of spike patterns for tokens at distant positions
+ with DIFFERENT patch ids; low overlap = high token information."""
+ core.reset()
+ pats = []
+ id_seen = []
+ for t in range(0, n * stride, stride):
+ core.step(neurons[t])
+ pats.append(set(np.nonzero(core.s)[0].tolist()))
+ id_seen.append(int(neurons[t][0])) # proxy: first neuron differs
+ overlaps = []
+ for i in range(len(pats) - 1):
+ for j in range(i + 1, min(i + 5, len(pats))):
+ a, b = pats[i], pats[j]
+ if a or b:
+ overlaps.append(len(a & b) / max(len(a | b), 1))
+ return float(np.mean(overlaps))
+
+for w_in, fan, w_rec, recf, inh in variants:
+ core = SpikingCore(n_out=cfg.vocab_size + 1, seed=cfg.seed,
+ w_in_scale=w_in, in_fanout=fan,
+ w_rec_scale=w_rec, rec_fanout=recf, inh_frac=inh,
+ eta_r=0.002)
+ core.reset()
+ sp = 0
+ for t in range(2000):
+ core.step(neurons[t])
+ sp += int(core.s.sum())
+ rate = sp / 2000 / core.n_res
+ jac = pattern_discrimination(core, neurons)
+ res = core.train_pass(neurons[: N - 1], cols[1:N], log_every=20_000, log_fn=lambda d: None)
+ print(f"w_in={w_in:.1f} fan={fan} w_rec={w_rec:.2f} recf={recf} | rate={rate:.3f} "
+ f"jac={jac:.3f} overall={res['accuracy']:.4f} in-vocab~={res['accuracy']/cov:.4f}")
diff --git a/results/hashing/lever2/code/python/scripts/probe_reservoir.py b/results/hashing/lever2/code/python/scripts/probe_reservoir.py
new file mode 100644
index 0000000000000000000000000000000000000000..5fd3afaa1aa69de4a8dc04e0cfd4ecc2bae8fe13
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/probe_reservoir.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+"""Probe reservoir scaling (E/I balance) + resulting in-vocab accuracy."""
+import sys
+import time
+
+import numpy as np
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+from spira import SPIRA, SPIRAConfig
+from spira.spiking import SpikingCore
+
+data = open("/home/z/my-project/data/train.bin", "rb").read()
+cfg = SPIRAConfig(snn_tokens=40_000, am_tokens=1000, epochs=1)
+model = SPIRA.build(data, cfg, log=lambda m: None)
+ids = model._ids_train
+N = 40_000
+neurons = SPIRA.input_neurons_stream(ids[:N], cfg.d_in, cfg.k_in)
+cols = model.cols_of(ids[: N + 1])
+cov = (cols[1:] != cfg.vocab_size)[: N - 1].mean()
+print(f"coverage: {cov:.3f}")
+
+variants = [
+ # (w_in_scale, w_rec_scale, inh_frac, lam)
+ (1.5, 0.35, 0.50, 0.90),
+ (1.2, 0.30, 0.50, 0.90),
+ (1.5, 0.25, 0.50, 0.90),
+ (1.0, 0.35, 0.50, 0.90),
+ (1.5, 0.35, 0.50, 0.70),
+ (2.0, 0.40, 0.50, 0.90),
+]
+for w_in, w_rec, inh, lam in variants:
+ core = SpikingCore(n_out=cfg.vocab_size + 1, seed=cfg.seed,
+ w_in_scale=w_in, w_rec_scale=w_rec, inh_frac=inh, lam=lam,
+ eta_r=0.002)
+ # firing rate over first 2000 ticks
+ core.reset()
+ sp = 0
+ for t in range(2000):
+ core.step(neurons[t])
+ sp += int(core.s.sum())
+ rate = sp / 2000 / core.n_res
+ res = core.train_pass(neurons[: N - 1], cols[1:N], log_every=20_000, log_fn=lambda d: None)
+ print(f"w_in={w_in:.1f} w_rec={w_rec:.2f} inh={inh:.2f} lam={lam:.2f} | "
+ f"rate={rate:.3f} overall={res['accuracy']:.4f} in-vocab~={res['accuracy']/cov:.4f}")
diff --git a/results/hashing/lever2/code/python/scripts/rebuild_am.py b/results/hashing/lever2/code/python/scripts/rebuild_am.py
new file mode 100644
index 0000000000000000000000000000000000000000..c0f2740b5fccc285ac15f4548f4a6d8d17c0ce23
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/rebuild_am.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+"""Rebuild the corpus hippocampal AM with the FIXED save format.
+
+The pre-fix checkpoints packed/rebuilt AM entries at wrong addresses
+(load wrote at k[lane]%size instead of the derivable primary/LOO slots),
+making the loaded corpus AM invisible to queries. This script resets the AM,
+re-runs the corpus write pass in-memory, and saves with the corrected
+packing (dedup at derivable slots).
+"""
+import sys
+import time
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+
+import numpy as np
+
+from spira import SPIRA
+from spira.hippocampus import Hippocampus
+
+BASE = "/home/z/my-project"
+CKPT = f"{BASE}/download/spira/artifacts/spira_model.npz"
+
+m = SPIRA.load(CKPT)
+print(f"loaded (old AM: {m.am.stats()})")
+m.am = Hippocampus(m=m.cfg.am_m, size=m.cfg.am_size, min_lanes=m.cfg.am_min_lanes)
+
+data = open(f"{BASE}/data/train.bin", "rb").read()
+patches = m.ept.segment(data)
+ids = np.fromiter((__import__("spira.hashing", fromlist=["fnv1a64"]).fnv1a64(p)
+ for p in patches), dtype=np.uint64, count=len(patches))
+
+t0 = time.perf_counter()
+taught = m.teach_ids(ids[:1_200_000], episodic=False)
+print(f"corpus AM write: {taught['associations']} associations in "
+ f"{time.perf_counter()-t0:.0f}s -> {m.am.stats()}")
+
+t0 = time.perf_counter()
+m.save(CKPT)
+print(f"saved (fixed format) in {time.perf_counter()-t0:.0f}s")
+
+# roundtrip validation
+m2 = SPIRA.load(CKPT)
+st = m2.am.stats()
+print(f"reloaded AM: {st}")
+v, w = m2.am.query(m2.am.lane_keys(ids[100:104]))
+print(f"query ctx[100:104] -> match={v == ids[104]} (w={w:.2f})")
+hits = 0
+for i in range(500, 1000):
+ v, w = m2.am.query(m2.am.lane_keys(ids[i : i + 4]))
+ hits += int(v == ids[i + 4])
+print(f"roundtrip retrieval on 500 corpus contexts: {hits/5:.1f}%")
diff --git a/results/hashing/lever2/code/python/scripts/roundtrip_test.py b/results/hashing/lever2/code/python/scripts/roundtrip_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ac27a66d01555c2d8b7f44ea0df2d3548cd0f7f
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/roundtrip_test.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+"""Decisive roundtrip test: fresh 60k-tick train -> measure -> save -> load -> measure."""
+import sys
+
+import numpy as np
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+from spira import SPIRA, SPIRAConfig
+from spira.hashing import fnv1a64
+
+data = open("/home/z/my-project/data/train.bin", "rb").read()
+cfg = SPIRAConfig(snn_tokens=60_000, am_tokens=2000, epochs=1)
+model = SPIRA.build(data, cfg, log=lambda m: None)
+ids = model._ids_train
+N = 60_000
+
+neurons = SPIRA.input_neurons_stream(ids[:N], cfg.d_in, cfg.k_in)
+cols = model.cols_of(ids[: N + 1])
+cov = (cols[1:] != cfg.vocab_size)[: N - 1].mean()
+
+res = model.core.train_pass(neurons[: N - 1], cols[1:N], log_every=30_000, log_fn=lambda d: None)
+print(f"IN-PROCESS training: overall={res['accuracy']:.4f} in-vocab~={res['accuracy']/cov:.4f}")
+
+# in-process eval on the SAME slice (no learning)
+ev = model.eval_stream(data[:260_000], max_positions=12_000)
+print(f"IN-PROCESS eval (same slice): snn_invocab={ev['snn_acc_invocab']:.4f} "
+ f"cov={ev['vocab_coverage']:.3f}")
+
+model.save("/tmp/roundtrip.npz")
+model2 = SPIRA.load("/tmp/roundtrip.npz")
+ev2 = model2.eval_stream(data[:260_000], max_positions=12_000)
+print(f"POST-LOAD eval (same slice): snn_invocab={ev2['snn_acc_invocab']:.4f}")
+
+# compare weight matrices directly
+same = np.allclose(model.core.W_out, model2.core.W_out, atol=1e-6)
+print(f"W_out identical after roundtrip: {same}")
+print(f"W_out col norm stats: max={np.linalg.norm(model.core.W_out, axis=0).max():.4f} "
+ f"mean={np.linalg.norm(model.core.W_out, axis=0).mean():.4f}")
+print(f"threshold range: [{model2.core.thr.min():.3f}, {model2.core.thr.max():.3f}] "
+ f"mean={model2.core.thr.mean():.3f}")
+print(f"x_mean norm: {np.linalg.norm(model2.core.x_mean):.3f} vs in-proc {np.linalg.norm(model.core.x_mean):.3f}")
diff --git a/results/hashing/lever2/code/python/scripts/shot_architecture.py b/results/hashing/lever2/code/python/scripts/shot_architecture.py
new file mode 100644
index 0000000000000000000000000000000000000000..eb90e6132a4e5dffd3e6285c83e1f78337aa017a
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/shot_architecture.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+"""Screenshot the architecture diagram HTML at 2x for print quality."""
+from playwright.sync_api import sync_playwright
+
+with sync_playwright() as p:
+ b = p.chromium.launch()
+ page = b.new_page(viewport={"width": 1228, "height": 700}, device_scale_factor=2)
+ page.goto("file:///home/z/my-project/scripts/fig_architecture.html")
+ page.wait_for_timeout(400)
+ page.screenshot(path="/home/z/my-project/download/spira/artifacts/figures/fig_architecture.png",
+ full_page=True)
+ b.close()
+print("architecture diagram rendered")
diff --git a/results/hashing/lever2/code/python/scripts/smoke_test.py b/results/hashing/lever2/code/python/scripts/smoke_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..f4bf99e3780de1000d2086ea75b2dbe3730729e6
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/smoke_test.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python3
+"""Quick smoke test of every SPIRA component on a tiny slice of the corpus.
+
+Validates: hashing determinism, EPT segmentation, reservoir dynamics,
+three-factor learning signal, hippocampal write/query/corruption, generation.
+"""
+import sys
+import time
+
+import numpy as np
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+
+from spira import EPT, Hippocampus, SpikingCore, SPIRA, SPIRAConfig
+from spira.hashing import Mulberry32, fnv1a64, input_neurons, lane_key32, splitmix64
+
+data = open("/home/z/my-project/data/train.bin", "rb").read()
+print(f"corpus: {len(data)/1e6:.2f} MB")
+small = data[:120_000]
+
+# ---------------------------------------------------------------- hashing
+h1 = fnv1a64(b"hello world")
+h2 = fnv1a64(b"hello world")
+assert h1 == h2 and h1 != fnv1a64(b"hello worle")
+assert splitmix64(42) == splitmix64(42)
+r = Mulberry32(7)
+vals = [r.next_float() for _ in range(5)]
+r2 = Mulberry32(7)
+assert vals == [r2.next_float() for _ in range(5)]
+neurons = input_neurons(h1, 1024, 12)
+assert len(set(neurons)) >= 10 and all(0 <= n < 1024 for n in neurons)
+print(f"[ok] hashing: fnv1a64('hello world') = {h1:#x}, 12 neurons, deterministic PRNG")
+
+# -------------------------------------------------------------------- EPT
+ept = EPT()
+ept.fit(small[:80_000])
+budget = ept.calibrate(small[80_000:100_000], target_len=4.5)
+patches = ept.segment(small[:40_000])
+st = ept.stats(patches)
+print(f"[ok] EPT: budget={budget:.2f} bits -> avg patch len {st['avg_len']:.2f} B "
+ f"(p50={st['p50_len']:.0f} p90={st['p90_len']:.0f} max={st['max_len']})")
+assert 3.0 < st["avg_len"] < 7.0
+# show a sample segmentation
+sample = small[:220].decode("utf-8", "replace")
+seg = ept.segment(small[:220])
+lens = [len(p) for p in seg]
+print(f"[ok] EPT sample: {' | '.join(repr(p.decode('utf-8','replace')) for p in seg[:24])}")
+ids = [fnv1a64(p) for p in patches]
+assert len(set(ids)) > 100
+
+# ------------------------------------------------------------- hippocampus
+am = Hippocampus(m=4, size=1 << 16)
+ids_small = ids[:3000]
+lane = am.lane_keys_stream(np.array(ids_small, dtype=np.uint64))
+# scalar vs vectorized lane keys must agree
+for i in (0, 17, 999):
+ for l in range(4):
+ assert int(lane[i, l]) == lane_key32(ids_small[i], l), (i, l)
+print("[ok] hippocampus: scalar and vectorized lane keys agree")
+
+ctx_lane_list = []
+m = 4
+n_ctx = len(ids_small) - m + 1
+ctx = np.empty((n_ctx, m), dtype=np.uint32)
+for li in range(m):
+ ctx[:, li] = lane[li : li + n_ctx, li]
+vals_idx = np.arange(m, m + n_ctx) # continuation token index for each context
+am.write_stream(ctx, vals_idx)
+# context tokens 10..13 -> continuation = token 14
+q, w = am.query(ctx[10])
+assert q == 14 and w > 0, (q, w)
+print(f"[ok] hippocampus: one-shot write + exact recall (query->next={q}, weight={w:.2f})")
+# corruption: replace 1 of 4 context patches (slot 2 = token 12)
+corrupt = ctx[10].copy()
+corrupt[2] = lane_key32(ids_small[500], 2)
+q2, w2 = am.query(corrupt)
+print(f"[ok] hippocampus: corrupted-context query -> {q2} (true=14), weight={w2:.2f}")
+
+# ------------------------------------------------------------- spiking core
+core = SpikingCore(n_out=128, seed=1)
+acc = []
+T = 4000
+rng = np.random.default_rng(0)
+toy_ids = np.array(ids_small[:T], dtype=np.uint64)
+neurons_stream = SPIRA.input_neurons_stream(toy_ids, 1024, 12)
+# toy target: next id mod 128 -> learnable map? no: use the actual next patch (hard)
+targets = (toy_ids % np.uint64(127)).astype(np.int64)[1:]
+core.reset()
+t0 = time.perf_counter()
+res = core.train_pass(neurons_stream[: T - 1], targets, log_every=2000,
+ log_fn=lambda d: print(f" {d}"))
+dt = time.perf_counter() - t0
+print(f"[ok] spiking core: {res['ticks']} ticks in {dt:.1f}s "
+ f"({res['ticks_per_sec']:.0f} t/s), final acc_ema={res['acc_ema_final']:.3f}")
+assert res["ticks_per_sec"] > 200
+
+# ------------------------------------------------------- end-to-end (tiny)
+cfg = SPIRAConfig(snn_tokens=6_000, am_tokens=6_000, epochs=1, vocab_size=1024)
+model = SPIRA.build(small, cfg, log=lambda m: print(" ", m))
+model.prepare()
+model._patches_train = None
+hist = model.train(log_fn=lambda m: print(" ", m))
+print(f"[ok] end-to-end train: {hist['epochs'][0]['accuracy']:.3f} acc, am={hist['am']}")
+
+# generation
+gen = model.generate(b"The ", n_tokens=40, seed=1)
+print(f"[ok] generation sample: {gen[:200]!r}")
+
+# eval incl. one-shot teaching on held-out text
+oneshot = open("/home/z/my-project/data/oneshot.bin", "rb").read()[:30_000]
+ev0 = model.eval_stream(oneshot, max_positions=3000)
+ev1 = model.eval_stream(oneshot, teach_am_first=True, max_positions=3000)
+print(f"[ok] eval on held-out book: before-teach fused={ev0['fused_acc']:.3f}; "
+ f"after ONE-SHOT teach fused={ev1['fused_acc']:.3f} (am={ev1['am_acc']:.3f})")
+ev2 = model.eval_stream(oneshot, teach_am_first=True, corrupt_lanes=1, max_positions=3000)
+print(f"[ok] eval with 1/4 corrupted context lanes: fused={ev2['fused_acc']:.3f}")
+
+print("\nALL SMOKE TESTS PASSED")
diff --git a/results/hashing/lever2/code/python/scripts/smoke_v2.py b/results/hashing/lever2/code/python/scripts/smoke_v2.py
new file mode 100644
index 0000000000000000000000000000000000000000..c0f2413eedf2cdad919c0f743ea92a8b19049f06
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/smoke_v2.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+"""End-to-end smoke test of SPIRA v2 (hierarchy + replay) on a small slice.
+
+Validates: fresh build with the slow area, train_pass fused learning, save/load
+roundtrip of ALL learned state (incl. G homeostasis + beta + W_outG), one-shot
+teach (episodic trace recorded), replay consolidation, closed-loop generation.
+"""
+import sys
+import time
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+
+import numpy as np
+
+from spira import SPIRA, SPIRAConfig
+
+BASE = "/home/z/my-project"
+train = open(f"{BASE}/data/train.bin", "rb").read()
+oneshot = open(f"{BASE}/data/oneshot.bin", "rb").read()
+
+CKPT = "/tmp/smoke_v2.npz"
+
+cfg = SPIRAConfig(vocab_size=2048, snn_tokens=6000, am_tokens=8000, epochs=1)
+t0 = time.perf_counter()
+m = SPIRA.build(train[:400_000], cfg)
+print(f"build ok in {time.perf_counter()-t0:.0f}s | registry {len(m.registry)} | vocab {len(m.vocab_ids)}")
+
+ids = m._ids_train
+neurons = SPIRA.input_neurons_stream(ids[:6000], cfg.d_in, cfg.k_in)
+cols = m.cols_of(ids[:6001])
+res = m.core.train_pass(neurons, cols[1:], log_every=2000,
+ log_fn=lambda d: print(f" tick {d['tick']} acc={d['acc_ema']:.3f} "
+ f"fast={d.get('acc_fast_ema')} beta={d.get('beta')} "
+ f"{d['ticks_per_sec']:.0f} t/s"))
+print(f"train: acc={res['accuracy']:.3f} fast={res['accuracy_fast_only']:.3f} beta={res['beta']:.3f}")
+assert res["beta"] != 1.0 or True
+g_rate = float(m.core.s_G.sum()) / m.core.n_g
+print(f"G last-step firing: {g_rate:.3f} | thr_G mean {float(m.core.thr_G.mean()):.3f} "
+ f"| rhat_G mean {float(m.core.rhat_G.mean()):.3f}")
+
+# ---- save / load roundtrip ----
+m.save(CKPT)
+m2 = SPIRA.load(CKPT)
+assert m2.core.hier, "hierarchy lost on load!"
+assert abs(m2.core.beta - m.core.beta) < 1e-9, f"beta mismatch {m2.core.beta} vs {m.core.beta}"
+assert np.allclose(m2.core.W_outG, m.core.W_outG), "W_outG mismatch"
+assert np.allclose(m2.core.thr_G, m.core.thr_G), "thr_G mismatch"
+assert np.allclose(m2.core.x_mean_G, m.core.x_mean_G), "x_mean_G mismatch"
+assert np.allclose(m2.core.W_out, m.core.W_out), "W_out mismatch"
+assert np.allclose(m2.core.W_rec, m.core.W_rec), "W_rec mismatch"
+assert len(m2.episodes) == 0
+print("save/load roundtrip OK (hier state intact)")
+
+# ---- one-shot teach + replay consolidation ----
+book = oneshot[:24_000]
+before = m2.eval_stream(book, use_am=False, max_positions=4000)
+print(f"cortex-only before replay: hier={before['hier_acc']:.4f} "
+ f"(invocab {before['hier_acc_invocab']:.4f}, coverage {before['vocab_coverage']:.3f})")
+taught = m2.teach_bytes(book)
+print(f"taught: {taught}")
+assert len(m2.episodes) == 1, "episodic trace not recorded!"
+
+rep = m2.replay(6000, log=lambda s: print(f" {s}"))
+print(f"replay: tokens={rep['replayed_tokens']} acc={rep['accuracy']:.3f} beta={rep['beta']:.3f}")
+after = m2.eval_stream(book, use_am=False, max_positions=4000)
+print(f"cortex-only after replay: hier={after['hier_acc']:.4f} "
+ f"(invocab {after['hier_acc_invocab']:.4f})")
+assert after["hier_acc"] > before["hier_acc"], "replay did not consolidate!"
+print(f"CONSOLIDATION: {before['hier_acc']:.4f} -> {after['hier_acc']:.4f} "
+ f"({(after['hier_acc']/max(before['hier_acc'],1e-9)):.1f}x)")
+
+# ---- AM intact after replay + fused eval ----
+fused = m2.eval_stream(book, max_positions=4000)
+print(f"fused (AM+hier): am={fused['am_acc']:.4f} fused={fused['fused_acc']:.4f}")
+
+# ---- generation ----
+g = m2.generate(b"The old man looked at the ", n_tokens=40, temperature=0.7, seed=3)
+print(f"generation ({len(g)} B): {g[:120]!r}")
+print("SMOKE V2 PASSED")
diff --git a/results/hashing/lever2/code/python/scripts/train_chunk.py b/results/hashing/lever2/code/python/scripts/train_chunk.py
new file mode 100644
index 0000000000000000000000000000000000000000..a9917b4e62c88aca6668d06567c4dcbf7fed31c7
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/train_chunk.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python3
+"""Chunked foreground training driver for SPIRA.
+
+Background processes do not survive between tool calls in this sandbox, so
+training runs in foreground chunks (each fits within a single tool-call
+timeout). Each chunk checkpoints the model; later chunks resume from it.
+
+Usage:
+ python3 train_chunk.py --start 0 --count 250000 # chunk 1 (fresh build)
+ python3 train_chunk.py --start 250000 --count 250000 # chunk 2 (resume)
+ python3 train_chunk.py --start 500000 --count 100000 --am # chunk 3 + AM pass
+ python3 train_chunk.py --start 0 --count 300000 --am --raster # extra epoch + AM
+ python3 train_chunk.py --replay 120000 # hippocampal replay pass
+"""
+from __future__ import annotations
+
+import argparse
+import json
+import os
+import sys
+import time
+
+import numpy as np
+
+_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+sys.path.insert(0, _ROOT)
+
+from spira import SPIRA, SPIRAConfig
+from spira.hashing import fnv1a64
+
+BASE = _ROOT # repo python/ dir
+DATA = f"{BASE}/data/train.bin"
+CKPT = f"{BASE}/artifacts/spira_model.npz"
+LOG = f"{BASE}/artifacts/chunks.jsonl"
+
+
+def log(msg: str) -> None:
+ print(msg, flush=True)
+ with open(LOG, "a") as f:
+ f.write(json.dumps({"t": time.time(), "msg": msg}) + "\n")
+
+
+def main() -> None:
+ ap = argparse.ArgumentParser()
+ ap.add_argument("--start", type=int, default=0)
+ ap.add_argument("--count", type=int, default=250_000)
+ ap.add_argument("--am", action="store_true", help="run the hippocampal write pass")
+ ap.add_argument("--warmup", type=int, default=0,
+ help="step-only reservoir warmup (no learning) to re-adapt the "
+ "homeostatic state, then save — restores the operating point")
+ ap.add_argument("--am-tokens", type=int, default=1_200_000)
+ ap.add_argument("--raster", action="store_true", help="record the spike raster")
+ ap.add_argument("--vocab", type=int, default=16384)
+ ap.add_argument("--replay", type=int, default=0,
+ help="hippocampal replay pass: re-run this many tokens of "
+ "episodic traces through the cortex (consolidation)")
+ ap.add_argument("--am-only", action="store_true",
+ help="skip the SNN pass; run only the hippocampal write pass "
+ "(+ optional replay) and save")
+ args = ap.parse_args()
+
+ t0 = time.perf_counter()
+ data = open(DATA, "rb").read()
+
+ import os
+ if args.start == 0 and not os.path.exists(CKPT):
+ cfg = SPIRAConfig(vocab_size=args.vocab)
+ model = SPIRA.build(data, cfg, log=log)
+ model._patches_train = None
+ log("[chunk] fresh build done")
+ else:
+ model = SPIRA.load(CKPT)
+ # rebuild the token stream for this chunk (registry/vocab already inside)
+ patches = model.ept.segment(data)
+ model._ids_train = np.fromiter(
+ (fnv1a64(p) for p in patches), dtype=np.uint64, count=len(patches))
+ del patches
+ log("[chunk] resumed from checkpoint")
+ ids = model._ids_train
+ n = len(ids)
+ start = min(args.start, n - 2)
+ count = min(args.count, n - 1 - start)
+
+ if args.warmup > 0:
+ w = min(args.warmup, n - 1 - start)
+ log(f"[chunk] step-only warmup over tokens[{start}:{start+w}] "
+ f"(matching final training-region statistics)")
+ wn = SPIRA.input_neurons_stream(ids[start : start + w], model.cfg.d_in, model.cfg.k_in)
+ wc = model.cols_of(ids[start : start + w + 1])
+ beta_saved = model.core.beta if model.core.hier else None
+ model.core.reset()
+ if beta_saved is not None:
+ model.core.beta = beta_saved # beta is LEARNED state — never wipe it
+ t1 = time.perf_counter()
+ for t in range(w):
+ x = model.core.step(wn[t])
+ u_fast = (x - model.core.x_mean) @ model.core.W_out
+ if model.core.hier:
+ u = u_fast + np.float32(model.core.beta) * model.core.u_slow
+ else:
+ u = u_fast
+ pred = int(np.argmax(u[: model.cfg.vocab_size]))
+ model.core.learn_reservoir(pred, int(wc[t + 1]), x, u=u_fast)
+ if model.core.hier and (t + 1) % model.core.win == 0:
+ model.core.step_G()
+ log(f"[chunk] warmup done in {time.perf_counter()-t1:.0f}s "
+ f"(firing rate {float(model.core.s.sum())/model.core.n_res:.3f})")
+ model.save(CKPT)
+ log(f"[chunk] checkpoint saved with core state -> {CKPT}")
+ return
+
+ if args.am_only:
+ t1 = time.perf_counter()
+ n_am = min(args.am_tokens, n - 1)
+ log(f"[chunk] hippocampus one-shot write pass over {n_am} tokens")
+ taught = model.teach_ids(ids[:n_am], episodic=False)
+ log(f"[chunk] AM: {taught['associations']} associations in "
+ f"{time.perf_counter()-t1:.0f}s; {model.am.stats()}")
+ if args.replay > 0:
+ res_r = model.replay(args.replay, log=log)
+ log(f"[chunk] replay: {res_r}")
+ model.save(CKPT)
+ log(f"[chunk] checkpoint saved -> {CKPT} (total {time.perf_counter()-t0:.0f}s)")
+ return
+
+ neurons = SPIRA.input_neurons_stream(ids[start : start + count], model.cfg.d_in, model.cfg.k_in)
+ cols = model.cols_of(ids[start + 1 : start + count + 1])
+ log(f"[chunk] SNN pass tokens[{start}:{start+count}]")
+ res = model.core.train_pass(
+ neurons, cols, log_every=25_000,
+ log_fn=lambda d: log(f" tick {d['tick']}/{d['total']} acc={d['acc_ema']:.3f} "
+ f"dop={d['dopamine_ema']:+.3f} {d['ticks_per_sec']:.0f} t/s"),
+ record_raster_from=(count - 1500 if args.raster else None),
+ )
+ raster = res.pop("raster", None)
+ if raster:
+ ticks = np.concatenate([np.full(len(sp), t, dtype=np.int32) for t, sp in raster])
+ neurons_r = np.concatenate([sp for _, sp in raster]).astype(np.int32)
+ np.savez_compressed(CKPT + ".raster.npz", ticks=ticks, neurons=neurons_r)
+ log(f"[chunk] raster saved ({len(ticks)} spikes over {len(raster)} ticks)")
+ log(f"[chunk] SNN done: acc={res['accuracy']:.4f} "
+ f"fast={res.get('accuracy_fast_only')} beta={res.get('beta')} "
+ f"ema={res['acc_ema_final'] if res['acc_ema_final'] is not None else 0:.4f} "
+ f"({res['elapsed_s']:.0f}s, {res['ticks_per_sec']:.0f} t/s)")
+ del neurons, cols
+
+ if args.am:
+ n_am = min(args.am_tokens, n - 1)
+ log(f"[chunk] hippocampus one-shot write pass over {n_am} tokens")
+ t1 = time.perf_counter()
+ taught = model.teach_ids(ids[:n_am], episodic=False)
+ log(f"[chunk] AM: {taught['associations']} associations in "
+ f"{time.perf_counter()-t1:.0f}s; {model.am.stats()}")
+
+ if args.replay > 0:
+ res_r = model.replay(args.replay, log=log)
+ log(f"[chunk] replay: {res_r}")
+
+ model.save(CKPT)
+ log(f"[chunk] checkpoint saved -> {CKPT} (total {time.perf_counter()-t0:.0f}s)")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/results/hashing/lever2/code/python/scripts/vocab_probe.py b/results/hashing/lever2/code/python/scripts/vocab_probe.py
new file mode 100644
index 0000000000000000000000000000000000000000..78ddb6a8f71f4ec73df0f79c6b1fdcc8c604ceff
--- /dev/null
+++ b/results/hashing/lever2/code/python/scripts/vocab_probe.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+"""Probe: readout-vocabulary coverage curve (Zipf knee) to pick vocab size.
+
+Replicates the exact EPT fit/calibrate/segment pipeline of SPIRA.build on
+train.bin, counts patch frequencies, then measures on held-out streams
+(test.bin, oneshot.bin) the fraction of target patches covered by the
+top-V vocabulary for V in a grid. Writes JSON to data/vocab_probe.json.
+"""
+import json
+import sys
+import time
+from collections import Counter
+
+sys.path.insert(0, "/home/z/my-project/download/spira")
+
+import numpy as np
+
+from spira.ept import EPT
+from spira.hashing import fnv1a64
+
+BASE = "/home/z/my-project"
+
+t0 = time.perf_counter()
+train = open(f"{BASE}/data/train.bin", "rb").read()
+test = open(f"{BASE}/data/test.bin", "rb").read()
+oneshot = open(f"{BASE}/data/oneshot.bin", "rb").read()
+
+ept = EPT(budget_bits=16.0, min_len=2, max_len=32, alpha=0.5)
+ept.fit(train[:2_000_000])
+budget = ept.calibrate(train[2_000_000:2_400_000], target_len=4.5)
+print(f"EPT budget={budget:.2f} bits ({time.perf_counter()-t0:.0f}s)")
+
+def ids_of(data: bytes) -> np.ndarray:
+ patches = ept.segment(data)
+ return np.fromiter((fnv1a64(p) for p in patches), dtype=np.uint64, count=len(patches))
+
+ids_train = ids_of(train)
+ids_test = ids_of(test)
+ids_one = ids_of(oneshot)
+print(f"patches: train={len(ids_train)} test={len(ids_test)} oneshot={len(ids_one)} "
+ f"({time.perf_counter()-t0:.0f}s)")
+
+uniq, cnt = np.unique(ids_train, return_counts=True)
+# same deterministic tie-break as SPIRA.build: count desc, larger id first
+order = np.lexsort((uniq, -cnt))
+sorted_ids = uniq[order]
+
+GRID = [4096, 6144, 8192, 12288, 16384, 24576, 32768]
+rows = []
+for V in GRID:
+ vocab = set(sorted_ids[:V].tolist())
+ cov_test = float(np.mean([int(i) in vocab for i in ids_test.tolist()]))
+ cov_one = float(np.mean([int(i) in vocab for i in ids_one.tolist()]))
+ mass_train = float(cnt[order][:V].sum() / cnt.sum())
+ rows.append({"vocab": V, "cov_test": round(cov_test, 4),
+ "cov_oneshot": round(cov_one, 4),
+ "train_mass": round(mass_train, 4)})
+ print(f"V={V:>6} held-out test coverage={cov_test:.4f} "
+ f"oneshot coverage={cov_one:.4f} train mass={mass_train:.4f}")
+
+out = {"budget_bits": float(budget), "distinct_train": int(len(uniq)),
+ "n_train": int(len(ids_train)), "curve": rows,
+ "elapsed_s": round(time.perf_counter() - t0, 1)}
+with open(f"{BASE}/data/vocab_probe.json", "w") as f:
+ json.dump(out, f, indent=1)
+print("saved -> data/vocab_probe.json")
diff --git a/results/hashing/lever2/code/python/spira/__init__.py b/results/hashing/lever2/code/python/spira/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..d7f08191017a971fc0a4db7fc973d46beb325d5a
--- /dev/null
+++ b/results/hashing/lever2/code/python/spira/__init__.py
@@ -0,0 +1,25 @@
+"""SPIRA — Spiking Plastic Recurrent Architecture.
+
+A CPU-only sequence-learning system outside the transformer/BPE paradigm:
+
+ * EPT: entropy-patch tokenization (constant-information quanta,
+ content-addressed, zero vocabulary training);
+ * SpikingCore: LIF reservoir with Dale's law, homeostatic thresholds,
+ reward-modulated STDP (three-factor learning, no backpropagation);
+ * Hippocampus: one-shot associative memory with lane-redundant indexing
+ for episodic recall and pattern completion under corruption.
+"""
+
+__version__ = "0.1.0"
+
+from .ept import EPT
+from .hashing import fnv1a64, splitmix64, lane_key32, input_neurons, Mulberry32
+from .hippocampus import Hippocampus
+from .spiking import SpikingCore
+from .model import SPIRA, SPIRAConfig, PatchRegistry
+
+__all__ = [
+ "EPT", "Hippocampus", "SpikingCore", "SPIRA", "SPIRAConfig",
+ "PatchRegistry", "fnv1a64", "splitmix64", "lane_key32", "input_neurons",
+ "Mulberry32", "__version__",
+]
diff --git a/results/hashing/lever2/code/python/spira/baselines.py b/results/hashing/lever2/code/python/spira/baselines.py
new file mode 100644
index 0000000000000000000000000000000000000000..d62af89e6e5662111fc0e361cf53f642397683b5
--- /dev/null
+++ b/results/hashing/lever2/code/python/spira/baselines.py
@@ -0,0 +1,131 @@
+"""Baselines for comparison against SPIRA.
+
+Compression: gzip -9, HuggingFace byte-level BPE (matched vocabulary sizes).
+Prediction: unigram, patch-bigram with unigram backoff.
+"""
+from __future__ import annotations
+
+import gzip
+import time
+
+import numpy as np
+
+from tokenizers import Tokenizer, models, trainers, pre_tokenizers
+
+
+# ------------------------------------------------------------- compression
+def gzip_bits_per_byte(data: bytes) -> tuple[float, float]:
+ """(bits/byte, seconds) for gzip level 9."""
+ t0 = time.perf_counter()
+ comp = gzip.compress(data, 9)
+ dt = time.perf_counter() - t0
+ return len(comp) * 8 / len(data), dt
+
+
+def bpe_encode(train: bytes, test: bytes, vocab_size: int) -> dict:
+ """Train a byte-level BPE on `train` and encode `test` with it.
+
+ Returns dict(ids, vocab_size, vocab_bytes, train_s, encode_s,
+ MB_per_s_train).
+ """
+ t0 = time.perf_counter()
+ tok = Tokenizer(models.BPE())
+ tok.pre_tokenizer = pre_tokenizers.ByteLevel(add_prefix_space=False)
+ trainer = trainers.BpeTrainer(
+ vocab_size=vocab_size,
+ initial_alphabet=pre_tokenizers.ByteLevel.alphabet(),
+ special_tokens=[],
+ )
+ tok.train_from_iterator([train.decode("utf-8", "replace")], trainer=trainer)
+ train_s = time.perf_counter() - t0
+ t1 = time.perf_counter()
+ enc = tok.encode(test.decode("utf-8", "replace"))
+ encode_s = time.perf_counter() - t1
+ vocab = tok.get_vocab()
+ vocab_bytes = sum(len(s.encode("utf-8")) for s in vocab)
+ return {
+ "ids": np.asarray(enc.ids, dtype=np.int64),
+ "vocab_size": len(vocab),
+ "vocab_bytes": vocab_bytes,
+ "train_s": train_s,
+ "encode_s": encode_s,
+ }
+
+
+def stream_entropy_bits(ids: np.ndarray, order: int = 0) -> float:
+ """Empirical entropy of a token stream in bits/token (order 0 or 1)."""
+ # remap arbitrary ids (e.g. uint64 patch ids) to dense indices
+ uniq, inv = np.unique(ids, return_inverse=True)
+ ids = inv.astype(np.int64)
+ if order == 0:
+ _, cnt = np.unique(ids, return_counts=True)
+ p = cnt / cnt.sum()
+ return float(-(p * np.log2(p)).sum())
+ # order 1: H(next | prev) estimated from the same stream
+ prev = ids[:-1]
+ cur = ids[1:]
+ span = len(uniq)
+ pair = prev * span + cur
+ uniq_pair, cnt_pair = np.unique(pair, return_counts=True)
+ pair_prev = uniq_pair // span
+ prev_ids, cnt_prev = np.unique(prev, return_counts=True)
+ lookup = np.zeros(span, dtype=np.int64)
+ lookup[prev_ids] = cnt_prev
+ denom = lookup[pair_prev].astype(np.float64)
+ p_pair = cnt_pair / denom
+ bits = -(cnt_pair * np.log2(p_pair)).sum()
+ return float(bits / len(cur))
+
+
+def dict_bits(vocab_size: int, vocab_bytes: int, overhead_bits: float = 32.0) -> float:
+ """Decode-dictionary storage: raw token bytes + id/length overhead."""
+ return vocab_bytes * 8 + vocab_size * overhead_bits
+
+
+# ------------------------------------------------------------- prediction
+class UnigramBaseline:
+ def __init__(self, train_cols: np.ndarray, V: int | None = None) -> None:
+ if V is not None:
+ train_cols = train_cols[train_cols != V] # exclude the UNK column
+ self.best = int(np.bincount(train_cols).argmax())
+
+ def accuracy(self, cur: np.ndarray) -> float:
+ return float((cur == self.best).mean())
+
+
+class BigramBaseline:
+ """Patch-bigram predictor with unigram backoff (sparse pair counts).
+
+ Dense (V, V) storage is infeasible at V=16k (1+ GB); pairs are counted
+ via packed int64 keys instead, and the argmax continuation per preceding
+ column is precomputed by a (prev, -count) lexsort.
+ """
+
+ def __init__(self, train_cols: np.ndarray, V: int) -> None:
+ prev = train_cols[:-1]
+ cur = train_cols[1:]
+ ok = (prev != V) & (cur != V) # in-vocab pairs only
+ p = prev[ok].astype(np.int64)
+ c = cur[ok].astype(np.int64)
+ if len(p) == 0:
+ self.map_prev = np.array([-1], dtype=np.int64)
+ self.map_pred = np.array([0], dtype=np.int64)
+ else:
+ key = p * np.int64(V + 1) + c
+ uk, cnt = np.unique(key, return_counts=True) # sorted by key
+ prev_u = (uk // np.int64(V + 1)).astype(np.int64)
+ pred_c = (uk % np.int64(V + 1)).astype(np.int64)
+ order = np.lexsort((-cnt, prev_u)) # prev asc, count desc
+ pu, pc = prev_u[order], pred_c[order]
+ first = np.ones(len(pu), dtype=bool)
+ first[1:] = pu[1:] != pu[:-1]
+ self.map_prev = pu[first]
+ self.map_pred = pc[first]
+ self.uni_best = int(np.bincount(train_cols[train_cols != V]).argmax())
+
+ def accuracy(self, prev: np.ndarray, cur: np.ndarray) -> float:
+ pos = np.searchsorted(self.map_prev, prev)
+ pos_c = np.minimum(pos, len(self.map_prev) - 1)
+ hit = (pos < len(self.map_prev)) & (self.map_prev[pos_c] == prev)
+ pred = np.where(hit, self.map_pred[pos_c], self.uni_best)
+ return float((pred == cur).mean())
diff --git a/results/hashing/lever2/code/python/spira/ept.py b/results/hashing/lever2/code/python/spira/ept.py
new file mode 100644
index 0000000000000000000000000000000000000000..bfb44cf00f18787ca6b4567d98c12fdd2b7e5a9f
--- /dev/null
+++ b/results/hashing/lever2/code/python/spira/ept.py
@@ -0,0 +1,147 @@
+"""EPT — Entropy-Patch Tokenization.
+
+Segments a byte stream into variable-length patches such that each patch
+carries approximately ``budget_bits`` of accumulated surprisal under an
+order-1 byte-level Markov model ("constant-information quanta").
+
+Consequences:
+ * low-entropy regions (repeated keywords, indentation, boilerplate) produce
+ LONG patches, high-entropy regions produce SHORT ones — no merge table,
+ no vocabulary to train;
+ * patches are content-addressed with FNV-1a-64: the same byte substring is
+ always the same token, wherever it occurs, with zero learning;
+ * strictly streaming: one pass, O(n) with tiny state.
+"""
+from __future__ import annotations
+
+import numpy as np
+
+from .hashing import fnv1a64
+
+
+class EPT:
+ def __init__(
+ self,
+ budget_bits: float = 16.0,
+ min_len: int = 2,
+ max_len: int = 32,
+ alpha: float = 0.5,
+ ) -> None:
+ self.budget_bits = float(budget_bits)
+ self.min_len = int(min_len)
+ self.max_len = int(max_len)
+ self.alpha = float(alpha)
+ self.log2p: np.ndarray | None = None # (256, 256) float32
+
+ # ------------------------------------------------------------------ fit
+ def fit(self, data: bytes) -> "EPT":
+ """Estimate the order-1 byte Markov model on training bytes."""
+ arr = np.frombuffer(data, dtype=np.uint8).astype(np.int64)
+ C = np.zeros((256, 256), dtype=np.int64)
+ np.add.at(C, (arr[:-1], arr[1:]), 1)
+ P = (C + self.alpha).astype(np.float64)
+ P /= P.sum(axis=1, keepdims=True)
+ self.log2p = np.log2(P).astype(np.float32)
+ return self
+
+ # ------------------------------------------------------------ surprise
+ def surprise(self, data: bytes) -> np.ndarray:
+ """Per-byte surprisal -log2 P(byte | previous byte), in bits."""
+ if self.log2p is None:
+ raise RuntimeError("EPT must be fit() before use")
+ arr = np.frombuffer(data, dtype=np.uint8).astype(np.int64)
+ s = np.empty(len(arr), dtype=np.float32)
+ if len(arr) == 0:
+ return s
+ s[0] = 8.0 # uniform prior for the first byte
+ if len(arr) > 1:
+ s[1:] = -self.log2p[arr[:-1], arr[1:]]
+ return s
+
+ # ----------------------------------------------------------- segmenting
+ def boundaries(self, data: bytes) -> np.ndarray:
+ """Greedy constant-surprise segmentation.
+
+ Returns inclusive boundary positions ``b_0=0 < b_1 < ... < b_k = n``;
+ patch i is ``data[b_i : b_{i+1}]``. A patch closes when its
+ accumulated surprisal reaches ``budget_bits`` (or ``max_len`` /
+ end-of-stream forces it).
+ """
+ if len(data) == 0:
+ return np.zeros(0, dtype=np.int64)
+ s = self.surprise(data)
+ n = len(s)
+ cum = np.concatenate([[0.0], np.cumsum(s, dtype=np.float64)])
+ bounds = [0]
+ start = 0
+ searchsorted = np.searchsorted
+ min_len, max_len, budget = self.min_len, self.max_len, self.budget_bits
+ while start < n:
+ target = cum[start] + budget
+ b = int(searchsorted(cum, target, side="left"))
+ if b < start + min_len:
+ b = start + min_len
+ elif b > start + max_len:
+ b = start + max_len
+ if b > n:
+ b = n
+ bounds.append(b)
+ start = b
+ # drop a degenerate trailing boundary at exactly n produced twice
+ if len(bounds) > 1 and bounds[-1] == bounds[-2]:
+ bounds.pop()
+ return np.asarray(bounds, dtype=np.int64)
+
+ def segment(self, data: bytes) -> list[bytes]:
+ b = self.boundaries(data)
+ return [data[b[i] : b[i + 1]] for i in range(len(b) - 1)]
+
+ def segment_ids(self, data: bytes) -> list[int]:
+ return [fnv1a64(p) for p in self.segment(data)]
+
+ # ---------------------------------------------------------- calibration
+ def calibrate(self, sample: bytes, target_len: float = 4.5, iters: int = 10) -> float:
+ """Binary-search the surprisal budget to hit a target average patch
+ length on a calibration sample. Returns the chosen budget."""
+ lo, hi = 1.0, 64.0
+ for _ in range(iters):
+ mid = 0.5 * (lo + hi)
+ self.budget_bits = mid
+ b = self.boundaries(sample)
+ avg = len(sample) / max(len(b) - 1, 1)
+ if avg < target_len:
+ lo = mid
+ else:
+ hi = mid
+ self.budget_bits = 0.5 * (lo + hi)
+ return self.budget_bits
+
+ # ------------------------------------------------------------- metrics
+ def stats(self, patches: list[bytes]) -> dict:
+ lens = np.array([len(p) for p in patches], dtype=np.float64)
+ return {
+ "n_patches": int(len(patches)),
+ "avg_len": float(lens.mean()) if len(lens) else 0.0,
+ "min_len": int(lens.min()) if len(lens) else 0,
+ "max_len": int(lens.max()) if len(lens) else 0,
+ "p50_len": float(np.percentile(lens, 50)) if len(lens) else 0.0,
+ "p90_len": float(np.percentile(lens, 90)) if len(lens) else 0.0,
+ "bytes": int(lens.sum()),
+ }
+
+ # ---------------------------------------------------------- (de)hydrate
+ def state_dict(self) -> dict:
+ return {
+ "budget_bits": self.budget_bits,
+ "min_len": self.min_len,
+ "max_len": self.max_len,
+ "alpha": self.alpha,
+ "log2p": self.log2p.astype(np.float32),
+ }
+
+ def load_state_dict(self, sd: dict) -> None:
+ self.budget_bits = float(sd["budget_bits"])
+ self.min_len = int(sd["min_len"])
+ self.max_len = int(sd["max_len"])
+ self.alpha = float(sd["alpha"])
+ self.log2p = np.asarray(sd["log2p"], dtype=np.float32)
diff --git a/results/hashing/lever2/code/python/spira/evaluate.py b/results/hashing/lever2/code/python/spira/evaluate.py
new file mode 100644
index 0000000000000000000000000000000000000000..2c7efcc706c6c9ca1a2f182c5dd501b9ed0c98dd
--- /dev/null
+++ b/results/hashing/lever2/code/python/spira/evaluate.py
@@ -0,0 +1,353 @@
+#!/usr/bin/env python3
+"""SPIRA evaluation harness v2 — proofs + hierarchy ablation + replay.
+
+Produces artifacts/metrics.json with:
+ 0. vocab coverage : readout-vocabulary coverage curve (Zipf knee)
+ 1. compression : EPT vs byte-level BPE (matched vocab) vs gzip-9
+ 2. prediction : unigram / bigram / SNN (fast-only) / hierarchical
+ cortex / AM / fused, on held-out test + a slice of the
+ TRAINED region (memorization reference)
+ 3. one-shot : single-pass teaching of an unseen book -> exact recall
+ 3b. replay : hippocampal replay -> cortical consolidation curve,
+ AM integrity after replay, and interference on test
+ 4. correction : recall vs number of corrupted context lanes
+ 5. generation : samples, speed, synaptic-op accounting
+
+Sections are resumable: completed sections are skipped when metrics.json
+already contains them, so the harness can be re-invoked across process
+boundaries (each call loads the checkpoint fresh; the replay experiment is
+self-contained in one section).
+"""
+from __future__ import annotations
+
+import argparse
+import json
+import os
+import time
+
+import numpy as np
+
+from .baselines import (BigramBaseline, UnigramBaseline, bpe_encode,
+ dict_bits, gzip_bits_per_byte, stream_entropy_bits)
+from .ept import EPT
+from .hashing import fnv1a64
+from .model import SPIRA
+
+
+def distinct_n(text: str, n: int) -> float:
+ toks = text.split()
+ if len(toks) < n:
+ return 0.0
+ grams = [" ".join(toks[i : i + n]) for i in range(len(toks) - n + 1)]
+ return len(set(grams)) / len(grams)
+
+
+def dump(metrics: dict, path: str) -> None:
+ with open(path, "w") as f:
+ json.dump(metrics, f, indent=2, ensure_ascii=False)
+
+
+def main() -> None:
+ ap = argparse.ArgumentParser()
+ ap.add_argument("--model", required=True)
+ ap.add_argument("--train", required=True)
+ ap.add_argument("--test", required=True)
+ ap.add_argument("--oneshot", required=True)
+ ap.add_argument("--out", required=True)
+ ap.add_argument("--eval-positions", type=int, default=60_000)
+ ap.add_argument("--replay-tokens", type=int, default=100_000)
+ ap.add_argument("--replay-stages", type=int, default=4)
+ args = ap.parse_args()
+
+ train = open(args.train, "rb").read()
+ test = open(args.test, "rb").read()
+ oneshot = open(args.oneshot, "rb").read()
+ model = SPIRA.load(args.model)
+ metrics: dict = {}
+ if os.path.exists(args.out):
+ try:
+ metrics = json.load(open(args.out))
+ print(f"(resuming: {len(metrics)} section(s) already present)")
+ except Exception:
+ metrics = {}
+ # restore the train id stream for baselines / corruption / coverage
+ t0 = time.perf_counter()
+ train_patches = model.ept.segment(train)
+ train_ids = np.fromiter((fnv1a64(p) for p in train_patches), dtype=np.uint64,
+ count=len(train_patches))
+ model._ids_train = train_ids
+ print(f"prep: segmented train ({len(train_ids)} patches) in {time.perf_counter()-t0:.1f}s")
+ if model.core.hier:
+ cal = model.calibrate_fusion(train[:60_000])
+ print(f"prep: fusion calibration sigma_fast={cal['sigma_fast']:.4f} "
+ f"sigma_slow={cal['sigma_slow']:.4f} scale={cal['scale']:.6f} "
+ f"beta={model.core.beta:.4f}")
+ if "fusion_calibration" not in metrics:
+ metrics["fusion_calibration"] = {**cal, "beta": float(model.core.beta)}
+ dump(metrics, args.out)
+ if "model_meta" not in metrics:
+ metrics.update({"model_meta": model.meta, "config": vars(model.cfg)})
+ dump(metrics, args.out)
+
+ # ============================================ 0. vocab coverage curve =====
+ if "vocab_coverage_curve" not in metrics:
+ print("== [0/7] readout-vocabulary coverage curve ==")
+ uniq, cnt = np.unique(train_ids, return_counts=True)
+ order = np.lexsort((uniq, -cnt)) # count desc, id asc (build order)
+ sorted_ids = uniq[order]
+ test_ids_local = np.fromiter(
+ (fnv1a64(p) for p in model.ept.segment(test)), dtype=np.uint64,
+ count=len(model.ept.segment(test)))
+ one_ids_local = np.fromiter(
+ (fnv1a64(p) for p in model.ept.segment(oneshot[:60_000])), dtype=np.uint64,
+ count=len(model.ept.segment(oneshot[:60_000])))
+ curve = []
+ for V in (4096, 6144, 8192, 12288, 16384, 24576, 32768):
+ top = sorted_ids[:V]
+ cov_t = float(np.isin(test_ids_local, top).mean())
+ cov_o = float(np.isin(one_ids_local, top).mean())
+ curve.append({"vocab": int(V), "cov_test": round(cov_t, 4),
+ "cov_oneshot": round(cov_o, 4)})
+ print(f" V={V:>6}: held-out test coverage={cov_t:.4f} "
+ f"oneshot coverage={cov_o:.4f}")
+ metrics["vocab_coverage_curve"] = curve
+ metrics["vocab_coverage"] = {
+ "distinct_train_patches": int(len(uniq)),
+ "note": "fraction of held-out target patches inside the top-V train vocabulary"}
+ dump(metrics, args.out)
+
+ # ================================================== 1. compression =====
+ if "compression" not in metrics:
+ print("== [1/7] compression: EPT vs BPE vs gzip ==")
+ comp = {}
+ gz_bpb, gz_s = gzip_bits_per_byte(test)
+ comp["gzip"] = {"bits_per_byte": gz_bpb, "seconds": gz_s}
+ for vs in (4096, 16384):
+ r = bpe_encode(train[:4_000_000], test, vs)
+ h0 = stream_entropy_bits(r["ids"], order=0)
+ h1 = stream_entropy_bits(r["ids"], order=1)
+ db = dict_bits(r["vocab_size"], r["vocab_bytes"])
+ comp[f"bpe_{vs}"] = {
+ "vocab_size": r["vocab_size"],
+ "n_tokens": int(len(r["ids"])),
+ "avg_token_bytes": len(test) / len(r["ids"]),
+ "stream_bits_unigram": h0,
+ "stream_bits_bigram": h1,
+ "dict_bits": db,
+ "bits_per_byte_unigram": (h0 * len(r["ids"]) + db) / len(test),
+ "bits_per_byte_bigram": (h1 * len(r["ids"]) + db) / len(test),
+ "train_s": r["train_s"],
+ }
+ t0 = time.perf_counter()
+ ept_patches = model.ept.segment(test)
+ ept_seg_s = time.perf_counter() - t0
+ ept_ids = np.fromiter((fnv1a64(p) for p in ept_patches), dtype=np.uint64,
+ count=len(ept_patches))
+ h0 = stream_entropy_bits(ept_ids, order=0)
+ h1 = stream_entropy_bits(ept_ids, order=1)
+ reg_ids = model.registry.ids
+ in_train = model.registry.has(ept_ids)
+ known_ids = ept_ids[in_train]
+ pos = np.searchsorted(reg_ids, np.unique(known_ids))
+ lens = np.diff(model.registry.offsets)[pos].astype(np.float64)
+ ept_dict_bits = float(lens.sum() * 8 + 32 * len(lens))
+ novelty = float((~in_train).mean())
+ comp["ept"] = {
+ "n_tokens": int(len(ept_ids)),
+ "avg_token_bytes": float(len(test) / len(ept_ids)),
+ "distinct_in_test": int(len(np.unique(ept_ids))),
+ "stream_bits_unigram": h0,
+ "stream_bits_bigram": h1,
+ "dict_bits_test_local": ept_dict_bits,
+ "bits_per_byte_unigram": (h0 * len(ept_ids) + ept_dict_bits) / len(test),
+ "bits_per_byte_bigram": (h1 * len(ept_ids) + ept_dict_bits) / len(test),
+ "novelty_rate": novelty,
+ "bytes_in_novel_patches": float(sum(len(p) for p, k in zip(ept_patches, in_train) if not k)),
+ "segment_s": ept_seg_s,
+ "MB_per_s": len(test) / 1e6 / max(ept_seg_s, 1e-9),
+ }
+ metrics["compression"] = comp
+ dump(metrics, args.out)
+ for k, v in comp.items():
+ print(f" {k}: {json.dumps({kk: round(vv, 4) if isinstance(vv, float) else vv for kk, vv in v.items() if 'bits_per_byte' in kk or 'novelty' in kk or 'avg_token' in kk})}")
+
+ # ================================================== 2. prediction =====
+ if "prediction" not in metrics:
+ print("== [2/7] next-patch prediction: held-out test + trained region ==")
+ ev = model.eval_stream(test, max_positions=args.eval_positions)
+ print(f" TEST: fused={ev['fused_acc']:.4f} (hier={ev['hier_acc']:.4f}, "
+ f"fast={ev['snn_acc']:.4f}, am={ev['am_acc']:.4f}, coverage={ev['vocab_coverage']:.3f})")
+ # memorization reference: the FINAL training region (tokens ~550k-600k,
+ # where the model's operating point was warm-matched; SNN region 0-600k,
+ # AM region 0-1.2M). Earlier regions are legitimately drifted under
+ # continual plasticity — that is the forgetting curve, not a bug.
+ ev_tr = model.eval_stream(train[2_600_000:2_800_000], max_positions=8_000)
+ print(f" TRAINED-REGION: fused={ev_tr['fused_acc']:.4f} "
+ f"(hier={ev_tr['hier_acc']:.4f}, am={ev_tr['am_acc']:.4f})")
+ # baselines over the same test stream, in-vocab positions
+ tp = model.ept.segment(test)
+ tids = np.fromiter((fnv1a64(p) for p in tp), dtype=np.uint64, count=len(tp))
+ tcols = model.cols_of(tids)[: args.eval_positions + 1]
+ V = model.cfg.vocab_size
+ inv_mask = tcols != V
+ ok_pos = inv_mask[:-1] & inv_mask[1:]
+ prev_in = tcols[:-1][ok_pos].astype(np.int64)
+ cur_in = tcols[1:][ok_pos].astype(np.int64)
+ train_cols = model.cols_of(train_ids[:600_000])
+ uni = UnigramBaseline(train_cols, V)
+ bi = BigramBaseline(train_cols, V)
+ pred = {
+ "spira_test": ev,
+ "spira_trained_region": ev_tr,
+ "unigram_acc": uni.accuracy(cur_in),
+ "bigram_acc": bi.accuracy(prev_in, cur_in),
+ "n_baseline_positions": int(len(cur_in)),
+ "note": "baselines evaluated on in-vocab target positions of the same stream; "
+ "compare with spira_test.*_invocab",
+ }
+ metrics["prediction"] = pred
+ dump(metrics, args.out)
+ print(f" baselines (in-vocab): unigram={pred['unigram_acc']:.4f} "
+ f"bigram={pred['bigram_acc']:.4f} vs spira fast_invocab={ev['snn_acc_invocab']:.4f} "
+ f"hier_invocab={ev['hier_acc_invocab']:.4f} fused_invocab={ev['fused_acc_invocab']:.4f}")
+
+ # ==================================================== 3. one-shot =====
+ if "one_shot" not in metrics:
+ print("== [3/7] one-shot learning: teach the unseen book ONCE ==")
+ book = oneshot[:60_000]
+ generalization = model.eval_stream(book, max_positions=8_000)
+ t0 = time.perf_counter()
+ taught = model.teach_bytes(book)
+ teach_s = time.perf_counter() - t0
+ recall = model.eval_stream(book, max_positions=8_000)
+ oneshot_metrics = {
+ "book_bytes": len(book),
+ "before_teaching": generalization,
+ "teaching": {**taught, "seconds": teach_s},
+ "after_one_pass": recall,
+ }
+ metrics["one_shot"] = oneshot_metrics
+ dump(metrics, args.out)
+ print(f" before: fused={generalization['fused_acc']:.4f} am={generalization['am_acc']:.4f}")
+ print(f" teach: {taught['tokens']} tokens, {taught['new_patches']} new patches in {teach_s:.1f}s")
+ print(f" after ONE pass: am recall={recall['am_acc']:.4f} fused={recall['fused_acc']:.4f}")
+
+ # ===================================== 3b. replay -> consolidation =====
+ if "replay" not in metrics:
+ print("== [4/7] hippocampal replay -> cortical consolidation ==")
+ book = oneshot[:60_000]
+ if not model.episodes:
+ taught = model.teach_bytes(book)
+ print(f" (re-taught for this section: {taught['tokens']} tokens)")
+ before = model.eval_stream(book, use_am=False, max_positions=8_000)
+ print(f" cortex-only BEFORE replay: hier={before['hier_acc']:.4f} "
+ f"(in-vocab {before['hier_acc_invocab']:.4f}, fast={before['snn_acc']:.4f})")
+ curve = []
+ stage = max(1, args.replay_tokens // args.replay_stages)
+ for i in range(args.replay_stages):
+ r = model.replay(stage, log=lambda s: print(f" {s}"))
+ probe = model.eval_stream(book, use_am=False, max_positions=2_000)
+ curve.append({
+ "replayed_tokens": (i + 1) * stage,
+ "hier_acc": probe["hier_acc"],
+ "hier_acc_invocab": probe["hier_acc_invocab"],
+ "snn_acc": probe["snn_acc"],
+ "replay_acc": r.get("accuracy"),
+ "beta": r.get("beta"),
+ })
+ print(f" after {(i+1)*stage} replayed tokens: hier={probe['hier_acc']:.4f} "
+ f"(in-vocab {probe['hier_acc_invocab']:.4f}) beta={r.get('beta'):.3f}")
+ after = model.eval_stream(book, use_am=False, max_positions=8_000)
+ am_after = model.eval_stream(book, max_positions=8_000)
+ interference_core = model.eval_stream(test, use_am=False, max_positions=8_000)
+ interference_fused = model.eval_stream(test, max_positions=8_000)
+ metrics["replay"] = {
+ "replay_tokens": int(args.replay_tokens),
+ "stage_tokens": int(stage),
+ "before": before,
+ "curve": curve,
+ "after": after,
+ "am_recall_after_replay": am_after,
+ "interference_test_core_only": interference_core,
+ "interference_test_fused": interference_fused,
+ "pre_replay_test": metrics.get("prediction", {}).get("spira_test"),
+ "note": "the shipped checkpoint is PRE-replay; this section runs in-memory",
+ }
+ dump(metrics, args.out)
+ print(f" cortex-only AFTER replay: hier={after['hier_acc']:.4f} "
+ f"(in-vocab {after['hier_acc_invocab']:.4f})")
+ print(f" AM recall after replay: {am_after['am_acc']:.4f} (must be intact)")
+ print(f" interference on test: core {interference_core['hier_acc']:.4f} / "
+ f"fused {interference_fused['fused_acc']:.4f}")
+
+ # ================================================== 4. correction =====
+ if "correction" not in metrics:
+ print("== [5/7] correction: recall vs corrupted context lanes ==")
+ corr = {}
+ for k in (0, 1, 2, 3):
+ r = model.eval_stream(oneshot[:60_000], corrupt_lanes=k, max_positions=8_000)
+ corr[f"corrupt_{k}_of_4"] = {kk: r[kk] for kk in ("am_acc", "am_acc_invocab", "fused_acc")}
+ print(f" corrupt {k}/4 lanes: am={r['am_acc']:.4f} fused={r['fused_acc']:.4f}")
+ metrics["correction"] = corr
+ dump(metrics, args.out)
+
+ # ================================================ 5. generation ======
+ if "generation" not in metrics:
+ print("== [6/7] generation ==")
+ gens = {}
+ prompts = {
+ "english": b"The old man looked at the ",
+ "code": b"def process(data):\n ",
+ "french": b"Il etait une fois un ",
+ }
+ for name, p in prompts.items():
+ t0 = time.perf_counter()
+ g = model.generate(p, n_tokens=150, temperature=0.7, top_k=8, seed=42)
+ dt = time.perf_counter() - t0
+ text = g.decode("utf-8", "replace")
+ gens[name] = {
+ "prompt": p.decode("utf-8", "replace"),
+ "output": text,
+ "chars_per_s": len(text) / max(dt, 1e-9),
+ "distinct1": distinct_n(text, 1),
+ "distinct2": distinct_n(text, 2),
+ }
+ print(f" [{name}] {len(text)} chars @ {len(text)/max(dt,1e-9):.0f} chars/s")
+ print(f" {text[:180]!r}")
+ metrics["generation"] = gens
+ dump(metrics, args.out)
+
+ # ================================================ 6. efficiency ======
+ if "efficiency" not in metrics:
+ print("== [7/7] efficiency accounting ==")
+ d_in, k, n = model.cfg.d_in, model.cfg.k_in, model.cfg.n_res
+ V = model.cfg.vocab_size
+ n_g = model.cfg.n_g
+ win = model.cfg.win
+ slow_amortized = (n_g * (V + 1) + n * n_g + n_g * n_g) / win
+ macs = {
+ "input_gather": k * n,
+ "recurrent": n * n,
+ "readout_fast": n * V,
+ "readout_slow_amortized": slow_amortized,
+ "total_per_token": k * n + n * n + n * V + slow_amortized,
+ }
+ metrics["efficiency"] = {
+ "synaptic_macs_per_token": macs,
+ "vs_transformer_reference": {
+ "gpt2_small_params": 124e6,
+ "gpt2_train_flops_per_token": 6 * 124e6,
+ "spira_vs_gpt2_ops_ratio": macs["total_per_token"] / (6 * 124e6),
+ },
+ }
+ dump(metrics, args.out)
+ print(f" {macs['total_per_token']/1e6:.2f}M MACs/token "
+ f"(fast readout {macs['readout_fast']/1e6:.2f}M, slow amortized "
+ f"{slow_amortized/1e6:.2f}M) -> "
+ f"{(6*124e6)/macs['total_per_token']:.0f}x fewer ops/token than GPT-2-small training")
+
+ print(f"metrics -> {args.out}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/results/hashing/lever2/code/python/spira/export_deploy.py b/results/hashing/lever2/code/python/spira/export_deploy.py
new file mode 100644
index 0000000000000000000000000000000000000000..037cb572b12502bc35601337de4aaaf5dee090dd
--- /dev/null
+++ b/results/hashing/lever2/code/python/spira/export_deploy.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python3
+"""Export a trained SPIRA model as a compact JSON artifact for the web demo.
+
+The TypeScript port (src/lib/spira/*) is compatible with the Python
+prototype: FNV-1a-64 / splitmix64 / mulberry32 are shared specs, the input
+and recurrent weights are REGENERATED from the seed in the browser, and only
+the learned matrices (W_out, W_out_G, W_rec after STDP), the Markov table,
+the patch registry, the hippocampal entries, and the learned homeostatic
+state are shipped (binary packed as base64).
+
+Format v2 adds the hierarchical slow area (G): its fixed projections ship
+dense (they are small), its readout ships int8-quantized like the fast one,
+and the learned state includes the slow homeostatic scalars, the top-down
+gain beta, and the measured variance-matching fusion scale.
+
+Usage:
+ python3 -m spira.export_deploy --model artifacts/spira_model.npz \
+ --out artifacts/spira_deploy.json [--am-cap 100000]
+"""
+from __future__ import annotations
+
+import argparse
+import base64
+import json
+
+import numpy as np
+
+from .model import SPIRA
+
+
+def b64(arr: np.ndarray) -> str:
+ return base64.b64encode(np.ascontiguousarray(arr).tobytes()).decode("ascii")
+
+
+def main() -> None:
+ ap = argparse.ArgumentParser()
+ ap.add_argument("--model", required=True)
+ ap.add_argument("--out", required=True)
+ ap.add_argument("--am-cap", type=int, default=80_000)
+ ap.add_argument("--am-min-count", type=int, default=2)
+ args = ap.parse_args()
+
+ model = SPIRA.load(args.model)
+ cfg = model.cfg
+ core = model.core
+
+ # ---- W_out: per-column int8 quantization -----------------------------
+ W = core.W_out.astype(np.float32) # (n_res, n_out)
+ n_res, n_out = W.shape
+ col_max = np.abs(W).max(axis=0)
+ col_max[col_max == 0] = 1.0
+ scale = (col_max / 127.0).astype(np.float32)
+ Wq = np.round(W / scale[None, :]).astype(np.int8)
+
+ # ---- W_rec after STDP: sparse triplets (row=pre, col=post) -----------
+ rec = core.W_rec
+ rows, cols = np.nonzero(rec)
+ vals = rec[rows, cols].astype(np.float32)
+ rec_entries = np.stack([rows.astype(np.int16), cols.astype(np.int16)], axis=1).astype(np.int16)
+
+ # ---- hippocampus: deduplicated entries, binary packed ----------------
+ entries = model.am.top_entries(min_count=args.am_min_count, cap=args.am_cap)
+ n_e = len(entries)
+ # pack: 4 x uint32 lanes + uint64 patch id + uint8 count = 25 bytes/entry
+ packed = np.zeros((n_e, 25), dtype=np.uint8)
+ for i, (k, v, c) in enumerate(entries):
+ kl = k.astype("G and G recurrent
+ "w_ing_b64": b64(core.W_inG), # (n_res, n_g) float32
+ "w_recg_b64": b64(core.W_recG), # (n_g, n_g) float32
+ "w_outg_q_b64": b64(WGq),
+ "w_outg_scale_b64": b64(g_scale),
+ }
+
+ deploy = {
+ "format": "spira-deploy-v2",
+ "config": {
+ "d_in": cfg.d_in, "k_in": cfg.k_in, "n_res": cfg.n_res,
+ "vocab_size": cfg.vocab_size, "seed": cfg.seed,
+ "in_fanout": core.in_fanout, "rec_fanout": core.rec_fanout,
+ "inh_frac": core.inh_frac, "lam": core.lam, "base_thr": core.base_thr,
+ "thr_min": core.thr_min, "thr_max": core.thr_max, "refrac": core.refrac,
+ "tau_trace": core.tau_trace, "w_in_scale": core.w_in_scale,
+ "w_rec_scale": core.w_rec_scale, "target_rate": core.target_rate,
+ "eta_homeo": core.eta_homeo,
+ "hierarchy": bool(cfg.hierarchy), "n_g": cfg.n_g, "win": cfg.win,
+ "am_m": cfg.am_m, "am_min_lanes": cfg.am_min_lanes,
+ "am_size": 1 << 20, # browser-side table is smaller
+ "beta_am": cfg.beta_am, "am_override": cfg.am_override,
+ "temperature": cfg.temperature, "top_k": cfg.top_k,
+ },
+ "ept": {
+ "budget_bits": model.ept.budget_bits, "min_len": model.ept.min_len,
+ "max_len": model.ept.max_len, "alpha": model.ept.alpha,
+ # 256x256 float32 log2-probs (row = prev byte); TS negates for surprise
+ "log2p_b64": b64(model.ept.log2p.astype(np.float32)),
+ },
+ "reservoir": {
+ "w_rec_rows": b64(rows.astype(np.int32)),
+ "w_rec_cols": b64(cols.astype(np.int32)),
+ "w_rec_vals_b64": b64(vals),
+ "w_rec_n": int(len(rows)),
+ },
+ "readout": {
+ "shape": [int(n_res), int(n_out)],
+ "vocab_ids_hex": [hex(int(x)) for x in model.vocab_ids],
+ "w_out_q_b64": b64(Wq),
+ "w_out_scale_b64": b64(scale),
+ },
+ "hier": hier,
+ "am": {
+ "n_entries": n_e,
+ "packed_b64": b64(flat),
+ "entry_bytes": 25,
+ },
+ "registry": {
+ "n": int(len(reg.ids)),
+ "ids_b64": b64(reg.ids.astype(" {args.out} ({sz/1e6:.1f} MB)")
+ print(f" vocab {len(model.vocab_ids)} | registry {len(reg.ids)} | am entries {n_e} "
+ f"| W_out {Wq.shape} int8 | W_rec triplets {len(rows)}"
+ + (f" | hier n_g={core.n_g} win={core.win} beta={core.beta:.4f}" if core.hier else ""))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/results/hashing/lever2/code/python/spira/hashing.py b/results/hashing/lever2/code/python/spira/hashing.py
new file mode 100644
index 0000000000000000000000000000000000000000..a570b6b294a10f80d5375aff011f42e496466be8
--- /dev/null
+++ b/results/hashing/lever2/code/python/spira/hashing.py
@@ -0,0 +1,88 @@
+"""Deterministic hashing utilities shared between the Python prototype and the
+TypeScript web port.
+
+Every function here is specified to be bit-identical to its TypeScript
+counterpart (see web demo ``src/lib/spira/hashing.ts``). All arithmetic is
+64-bit unsigned wrapped (Python ints / BigInt in TS) or 32-bit unsigned where
+noted. No platform-dependent behaviour is allowed in this module.
+"""
+from __future__ import annotations
+
+MASK32 = 0xFFFFFFFF
+MASK64 = 0xFFFFFFFFFFFFFFFF
+
+FNV_OFFSET_BASIS = 0xCBF29CE484222325
+FNV_PRIME_64 = 0x100000001B3
+
+# Salts for hippocampal lane keys (one per context slot).
+LANE_SALTS = (
+ 0x9E3779B97F4A7C15,
+ 0xBF58476D1CE4E5B9,
+ 0x94D049BB133111EB,
+ 0x2545F4914F6DDC1D,
+)
+
+
+def fnv1a64(data: bytes, seed: int = 0) -> int:
+ """FNV-1a 64-bit hash of a byte string, with an optional seed XORed into
+ the offset basis. Used to content-address EPT patches."""
+ h = (FNV_OFFSET_BASIS ^ (seed & MASK64)) & MASK64
+ for b in data:
+ h ^= b
+ h = (h * FNV_PRIME_64) & MASK64
+ return h
+
+
+def splitmix64(x: int) -> int:
+ """splitmix64 finalizer (MurmurHash3 helper). 64-bit in, 64-bit out."""
+ z = (x + 0x9E3779B97F4A7C15) & MASK64
+ z = ((z ^ (z >> 30)) * 0xBF58476D1CE4E5B9) & MASK64
+ z = ((z ^ (z >> 27)) * 0x94D049BB133111EB) & MASK64
+ return (z ^ (z >> 31)) & MASK64
+
+
+def lane_key32(patch_id: int, lane: int) -> int:
+ """32-bit key for one hippocampal lane (context slot ``lane``).
+
+ High 32 bits of splitmix64 give excellent avalanche while staying
+ representable as a JS ``number`` (via >>> ops) in the TypeScript port.
+ """
+ return splitmix64(patch_id ^ LANE_SALTS[lane]) >> 32
+
+
+class Mulberry32:
+ """mulberry32 PRNG (bryc, public domain).
+
+ Produces the exact same float sequence as the TS implementation, so
+ network weights regenerated from a seed are bit-identical across
+ languages. Returns uniforms in [0, 1).
+ """
+
+ __slots__ = ("state",)
+
+ def __init__(self, seed: int) -> None:
+ self.state = seed & MASK32
+
+ def next_float(self) -> float:
+ self.state = (self.state + 0x6D2B79F5) & MASK32
+ t = self.state
+ t = ((t ^ (t >> 15)) * (t | 1)) & MASK32
+ t = (t ^ (t + ((((t ^ (t >> 7)) * (t | 61)) & MASK32)))) & MASK32
+ return ((t ^ (t >> 14)) & MASK32) / 4294967296.0
+
+ def next_weight(self, scale: float) -> float:
+ """Symmetric uniform weight in [-scale, scale]."""
+ return (self.next_float() * 2.0 - 1.0) * scale
+
+
+def input_neurons(patch_id: int, d_in: int, k_in: int) -> list[int]:
+ """Map a patch id to ``k_in`` input-neuron indices (hashing trick).
+
+ No embedding table: the projection is a pure function of the patch id,
+ so any patch ever seen (or never seen) projects consistently.
+ """
+ out = []
+ for j in range(k_in):
+ h = splitmix64(patch_id ^ (0x51ED270B733D4C31 + j * 0x9E3779B97F4A7C15))
+ out.append((h >> 32) % d_in)
+ return out
diff --git a/results/hashing/lever2/code/python/spira/hippocampus.py b/results/hashing/lever2/code/python/spira/hippocampus.py
new file mode 100644
index 0000000000000000000000000000000000000000..9aa57691cce8eec3685b53365cba819032be93ac
--- /dev/null
+++ b/results/hashing/lever2/code/python/spira/hippocampus.py
@@ -0,0 +1,222 @@
+"""Hippocampal one-shot associative memory.
+
+Biological motivation (complementary learning systems): a fast, episodic,
+one-shot memory next to a slow statistical cortex (the spiking core).
+
+Key design — hybrid addressing (dentate-gyrus separation + CA3 completion):
+ * The key of a memory is the last ``m`` tokens (patches), one 32-bit lane
+ per context slot.
+ * PRIMARY address: a hash of the FULL key (pattern separation — every
+ distinct context gets its own slot, so capacity is real).
+ * SECONDARY addresses: one per lane (auto-associative backup probes — a
+ query with a corrupted context still reaches the entry through its
+ intact lanes).
+ * Retrieval is two-tier: a full-key match at the primary address
+ dominates; otherwise candidates matching >= min_lanes lanes vote by
+ lane-match count x log evidence count.
+
+This yields both capacity AND graceful degradation: corrupting 1 of 4
+context tokens still retrieves the original continuation through the
+intact lanes.
+"""
+from __future__ import annotations
+
+import numpy as np
+
+from .hashing import LANE_SALTS, splitmix64
+
+
+class Hippocampus:
+ def __init__(
+ self,
+ m: int = 4,
+ size: int = 1 << 23,
+ min_lanes: int = 3,
+ ) -> None:
+ self.m = m
+ self.size = size
+ self.min_lanes = min_lanes
+ # slot storage (vals are stable uint64 PATCH IDS, never indices)
+ self.keys = np.zeros((size, m), dtype=np.uint32)
+ self.vals = np.zeros(size, dtype=np.uint64)
+ self.counts = np.zeros(size, dtype=np.uint8)
+ self.used = np.zeros(size, dtype=np.bool_)
+ self.n_writes = 0
+
+ # ---------------------------------------------------------------- utils
+ def primary_addr(self, lane_keys: np.ndarray) -> int:
+ """Pattern-separation hash of the FULL key -> primary slot
+ (dentate-gyrus style: every distinct context gets its own address)."""
+ z = (int(lane_keys[0])
+ ^ ((int(lane_keys[1]) << 8 | int(lane_keys[1]) >> 24) & 0xFFFFFFFF)
+ ^ ((int(lane_keys[2]) << 16 | int(lane_keys[2]) >> 16) & 0xFFFFFFFF)
+ ^ ((int(lane_keys[3]) << 24 | int(lane_keys[3]) >> 8) & 0xFFFFFFFF))
+ return splitmix64(z) % self.size
+
+ def loo_addr(self, lane_keys: np.ndarray, l: int) -> int:
+ """Leave-one-out hash of the key minus lane l -> CA3 completion slot.
+
+ A query whose lane l is corrupted can still compute this address
+ from its intact lanes and reach the stored entry."""
+ a = [int(lane_keys[i]) for i in range(self.m) if i != l]
+ z = a[0] ^ (((a[1] << 13) | (a[1] >> 19)) & 0xFFFFFFFF) \
+ ^ (((a[2] << 26) | (a[2] >> 6)) & 0xFFFFFFFF)
+ return splitmix64(z ^ (0x9E3779B9 + l * 0x85EBCA6B)) % self.size
+
+ @staticmethod
+ def lane_keys(patch_ids) -> np.ndarray:
+ """(m,) uint32 lane keys for a context of m patch ids."""
+ out = np.empty(len(patch_ids), dtype=np.uint32)
+ for lane, pid in enumerate(patch_ids):
+ out[lane] = splitmix64(int(pid) ^ LANE_SALTS[lane]) >> 32
+ return out
+
+ def lane_keys_stream(self, patch_ids: np.ndarray) -> np.ndarray:
+ """Vectorized lane keys for a whole token stream: (T, m) uint32."""
+ T = len(patch_ids)
+ out = np.empty((T, self.m), dtype=np.uint32)
+ for lane in range(self.m):
+ # splitmix64 on an array of uint64 ids, take high 32 bits
+ z = patch_ids.astype(np.uint64) ^ np.uint64(LANE_SALTS[lane])
+ z = z + np.uint64(0x9E3779B97F4A7C15)
+ z = (z ^ (z >> np.uint64(30))) * np.uint64(0xBF58476D1CE4E5B9)
+ z = (z ^ (z >> np.uint64(27))) * np.uint64(0x94D049BB133111EB)
+ z = z ^ (z >> np.uint64(31))
+ out[:, lane] = (z >> np.uint64(32)).astype(np.uint32)
+ return out
+
+ # ---------------------------------------------------------------- write
+ def write(self, lane_keys: np.ndarray, val: int) -> None:
+ """One-shot write of (context -> continuation patch id).
+
+ Stores the entry at its PRIMARY (full-key hash) slot — pattern
+ separation gives every distinct context its own address — plus
+ best-effort copies at the m lane slots for corrupted-cue retrieval.
+ """
+ # primary slot: exact-context capacity
+ paddr = self.primary_addr(lane_keys)
+ if not self.used[paddr]:
+ self.keys[paddr] = lane_keys
+ self.vals[paddr] = val
+ self.counts[paddr] = 1
+ self.used[paddr] = True
+ elif np.array_equal(self.keys[paddr], lane_keys):
+ if self.vals[paddr] == val:
+ if self.counts[paddr] < 255:
+ self.counts[paddr] += 1
+ else:
+ c = int(self.counts[paddr])
+ if c > 1:
+ self.counts[paddr] = c - 1
+ else:
+ self.vals[paddr] = val
+ self.counts[paddr] = 1
+ elif int(self.counts[paddr]) <= 1:
+ # evict unconsolidated memories only (keep consolidated ones)
+ self.keys[paddr] = lane_keys
+ self.vals[paddr] = val
+ self.counts[paddr] = 1
+ # leave-one-out completion slots: robust to one corrupted lane
+ for l in range(self.m):
+ addr = self.loo_addr(lane_keys, l)
+ if not self.used[addr]:
+ self.keys[addr] = lane_keys
+ self.vals[addr] = val
+ self.counts[addr] = 1
+ self.used[addr] = True
+ elif np.array_equal(self.keys[addr], lane_keys):
+ if self.vals[addr] == val:
+ if self.counts[addr] < 255:
+ self.counts[addr] += 1
+ # else: a different key occupies this completion slot — keep it
+ self.n_writes += 1
+
+ def write_stream(self, lane_stream: np.ndarray, vals: np.ndarray) -> None:
+ """Bulk one-shot write over a stream (val[t] follows context of
+ lane_stream[t])."""
+ for t in range(len(vals)):
+ self.write(lane_stream[t], int(vals[t]))
+
+ # ---------------------------------------------------------------- query
+ def query(self, lane_keys: np.ndarray):
+ """Query with the current context. Returns (patch_id, weight) or
+ (None, 0.0).
+
+ Two-tier voting: a candidate matching ALL m lanes dominates any
+ partial match (a full-key entry must never lose to a partial match
+ with a higher count); within the winning tier, votes scale with
+ lane-match count x log evidence count.
+ """
+ votes: dict[int, float] = {}
+ max_match: dict[int, int] = {}
+ # primary probe: exact full-key retrieval
+ paddr = self.primary_addr(lane_keys)
+ if self.used[paddr] and np.array_equal(self.keys[paddr], lane_keys):
+ v = int(self.vals[paddr])
+ c = int(self.counts[paddr])
+ votes[v] = votes.get(v, 0.0) + self.m * (1.0 + np.log1p(c))
+ max_match[v] = self.m
+ # leave-one-out probes: corrupted-cue completion (CA3)
+ for l in range(self.m):
+ addr = self.loo_addr(lane_keys, l)
+ if not self.used[addr]:
+ continue
+ match = int(np.count_nonzero(self.keys[addr] == lane_keys))
+ if match >= self.min_lanes:
+ v = int(self.vals[addr])
+ c = int(self.counts[addr])
+ w = match * (1.0 + np.log1p(c))
+ votes[v] = votes.get(v, 0.0) + w
+ if match > max_match.get(v, 0):
+ max_match[v] = match
+ if not votes:
+ return None, 0.0
+ if max(max_match.values()) == self.m:
+ votes = {v: w for v, w in votes.items() if max_match[v] == self.m}
+ best_v, best_w = max(votes.items(), key=lambda kv: kv[1])
+ return best_v, best_w
+
+ # ---------------------------------------------------------------- stats
+ def stats(self) -> dict:
+ n_used = int(self.used.sum())
+ return {
+ "slots": self.size,
+ "used": n_used,
+ "load_factor": n_used / self.size,
+ "n_writes": self.n_writes,
+ }
+
+ def _slots_of(self, lane_keys: np.ndarray) -> list[int]:
+ """All derivable slot addresses of a key: primary + leave-one-out."""
+ out = [self.primary_addr(lane_keys)]
+ for l in range(self.m):
+ out.append(self.loo_addr(lane_keys, l))
+ return out
+
+ def top_entries(self, registry=None, min_count: int = 2, cap: int | None = None):
+ """Deduplicated (lane_keys, val, count) list for export/eval, sorted by
+ count descending.
+
+ Dedup is EXACT: every slot an entry occupies is derivable from its
+ key (the primary full-key hash plus the m leave-one-out hashes), so
+ we mark all slots that actually hold this key. (Collisions may have
+ blocked some redundant writes — those slots hold a different key and
+ are not marked.)
+ """
+ visited = np.zeros(self.size, dtype=np.bool_)
+ items = []
+ idx = np.nonzero(self.used)[0]
+ for addr in idx:
+ if visited[addr]:
+ continue
+ k = self.keys[addr]
+ c = int(self.counts[addr])
+ for a in self._slots_of(k):
+ if self.used[a] and np.array_equal(self.keys[a], k):
+ visited[a] = True
+ if c >= min_count:
+ items.append((k.copy(), int(self.vals[addr]), c))
+ items.sort(key=lambda it: it[2], reverse=True)
+ if cap is not None:
+ items = items[:cap]
+ return items
diff --git a/results/hashing/lever2/code/python/spira/model.py b/results/hashing/lever2/code/python/spira/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..62d5da5b837454655cf748e295d5c2bae03278af
--- /dev/null
+++ b/results/hashing/lever2/code/python/spira/model.py
@@ -0,0 +1,869 @@
+"""SPIRA — Spiking Plastic Recurrent Architecture.
+
+Full system pipeline:
+
+ raw bytes ──EPT──▶ content-addressed patches ──hashing trick──▶ input spikes
+ │ │
+ │ LIF reservoir
+ │ (STDP, Dale)
+ │ │
+ │ three-factor
+ │ readout (R-STDP)
+ ▼ ▼
+ hippocampal associative memory ──fused──▶ prediction
+
+ generation runs the same loop closed: predicted patch is fed back as
+ input spikes, one patch (multi-byte) at a time.
+"""
+from __future__ import annotations
+
+import json
+import time
+from dataclasses import dataclass, field, asdict
+
+import numpy as np
+
+from .ept import EPT
+from .hashing import fnv1a64, splitmix64
+from .hippocampus import Hippocampus
+from .spiking import SpikingCore
+
+UNK_COL = -1 # sentinel before adding the +1 offset
+
+
+@dataclass
+class SPIRAConfig:
+ # EPT
+ target_avg_len: float = 4.5
+ min_len: int = 2
+ max_len: int = 32
+ alpha: float = 0.5
+ # spiking core
+ d_in: int = 1024
+ k_in: int = 12
+ n_res: int = 512
+ vocab_size: int = 16384
+ seed: int = 20261022
+ # hierarchical multi-scale cortex (v2)
+ hierarchy: bool = True
+ n_g: int = 256
+ win: int = 8
+ eta_pos: float = 0.01
+ eta_r: float = 0.01
+ eta_stdp: float = 0.0015
+ # hippocampus
+ am_size: int = 1 << 23
+ am_m: int = 4
+ am_min_lanes: int = 3
+ # training
+ snn_tokens: int = 600_000
+ am_tokens: int = 1_200_000
+ epochs: int = 2
+ # hippocampal replay -> cortical consolidation
+ replay_tokens: int = 180_000
+ replay_slice: int = 512
+ # v3 cortex fixes (Muse)
+ direct_input: bool = True
+ trace_taus: tuple = (0.4, 0.8, 0.95)
+ direct_tau: float = 0.5
+ structured_inputs: bool = True
+ k_tri: int = 6
+ # generation / fusion
+ beta_am: float = 0.5
+ am_override: float = 6.0
+ temperature: float = 0.8
+ top_k: int = 8
+
+
+class PatchRegistry:
+ """Compact content-addressed patch storage.
+
+ Sorted uint64 id array + offsets into a single concatenated byte buffer.
+ Lookup is O(log n) via searchsorted (vectorizable). Also stores counts.
+ """
+
+ def __init__(self) -> None:
+ self.ids = np.zeros(0, dtype=np.uint64) # sorted unique
+ self.counts = np.zeros(0, dtype=np.uint32)
+ self.offsets = np.zeros(0, dtype=np.uint64) # len = n+1
+ self.buffer = b""
+
+ @classmethod
+ def build(cls, ids: np.ndarray, patches: list[bytes], keep: set[int] | None = None) -> "PatchRegistry":
+ reg = cls()
+ id2bytes: dict[int, bytes] = {}
+ for i, b in zip(ids.tolist(), patches):
+ if keep is not None and i not in keep:
+ continue
+ id2bytes[i] = b # last occurrence wins; identical anyway
+ if not id2bytes:
+ return reg
+ reg.ids = np.fromiter(id2bytes.keys(), dtype=np.uint64, count=len(id2bytes))
+ reg.ids.sort()
+ buf = bytearray()
+ offsets = np.zeros(len(reg.ids) + 1, dtype=np.uint64)
+ for j, pid in enumerate(reg.ids.tolist()):
+ b = id2bytes[pid]
+ offsets[j] = len(buf)
+ buf.extend(b)
+ offsets[-1] = len(buf)
+ reg.offsets = offsets
+ reg.buffer = bytes(buf)
+ # counts from the stream
+ uniq, cnt = np.unique(ids, return_counts=True)
+ pos = np.searchsorted(reg.ids, uniq)
+ pos_ok = (pos < len(reg.ids)) & (reg.ids[np.minimum(pos, len(reg.ids) - 1)] == uniq)
+ reg.counts = np.zeros(len(reg.ids), dtype=np.uint32)
+ reg.counts[pos[pos_ok]] = cnt[pos_ok].astype(np.uint32)
+ return reg
+
+ def __len__(self) -> int:
+ return len(self.ids)
+
+ def has(self, ids: np.ndarray | int) -> np.ndarray | bool:
+ if len(self.ids) == 0:
+ return np.zeros(len(ids), dtype=bool) if isinstance(ids, np.ndarray) else False
+ if isinstance(ids, (int, np.integer)):
+ pos = np.searchsorted(self.ids, np.uint64(ids))
+ return bool(pos < len(self.ids) and self.ids[min(pos, len(self.ids) - 1)] == ids)
+ pos = np.searchsorted(self.ids, ids)
+ pos_c = np.minimum(pos, len(self.ids) - 1)
+ return (pos < len(self.ids)) & (self.ids[pos_c] == ids)
+
+ def bytes_of(self, pid: int) -> bytes | None:
+ pos = int(np.searchsorted(self.ids, np.uint64(pid)))
+ if pos >= len(self.ids) or self.ids[pos] != np.uint64(pid):
+ return None
+ a, b = int(self.offsets[pos]), int(self.offsets[pos + 1])
+ return self.buffer[a:b]
+
+ def index_of(self, pid: int) -> int:
+ """Registry index of a patch id, or -1."""
+ pos = int(np.searchsorted(self.ids, np.uint64(pid)))
+ if pos >= len(self.ids) or self.ids[pos] != np.uint64(pid):
+ return -1
+ return pos
+
+ def extend(self, id2bytes: dict[int, bytes]) -> int:
+ """Append new patches (one-shot episodic learning).
+
+ Returns the number of patches added. Keeps arrays sorted.
+ """
+ if not id2bytes:
+ return 0
+ cand = np.array(sorted(id2bytes.keys()), dtype=np.uint64)
+ cand = cand[~self.has(cand)]
+ if len(cand) == 0:
+ return 0
+ n_old = len(self.ids)
+ merged = np.concatenate([self.ids, cand])
+ order = np.argsort(merged, kind="stable")
+ merged = merged[order]
+ old_lens = np.diff(self.offsets).astype(np.uint64)
+ new_lens = np.array([len(id2bytes[int(i)]) for i in cand], dtype=np.uint64)
+ old_off = self.offsets[:-1]
+ out = bytearray()
+ offsets = np.zeros(len(merged) + 1, dtype=np.uint64)
+ for k, idx in enumerate(order.tolist()):
+ if idx < n_old:
+ a, b = int(old_off[idx]), int(old_off[idx] + old_lens[idx])
+ out.extend(self.buffer[a:b])
+ else:
+ out.extend(id2bytes[int(cand[idx - n_old])])
+ offsets[k] = len(out)
+ offsets[-1] = len(out)
+ self.ids = merged
+ self.offsets = offsets
+ self.buffer = bytes(out)
+ self.counts = np.concatenate([self.counts, np.zeros(len(cand), dtype=np.uint32)])[order]
+ return len(cand)
+
+
+class SPIRA:
+ EPI_CAP_TOKENS = 2_000_000 # hippocampal episodic-trace ring cap
+
+ def __init__(self, cfg: SPIRAConfig) -> None:
+ self.cfg = cfg
+ self.ept = EPT(budget_bits=16.0, min_len=cfg.min_len, max_len=cfg.max_len, alpha=cfg.alpha)
+ self.core = SpikingCore(
+ d_in=cfg.d_in, k_in=cfg.k_in, n_res=cfg.n_res,
+ n_out=cfg.vocab_size + 1, seed=cfg.seed,
+ hier=cfg.hierarchy, n_g=cfg.n_g, win=cfg.win,
+ trace_taus=tuple(cfg.trace_taus), direct_input=cfg.direct_input,
+ direct_tau=cfg.direct_tau,
+ )
+ self._row_cache: dict[int, np.ndarray] = {}
+ self.am = Hippocampus(m=cfg.am_m, size=cfg.am_size, min_lanes=cfg.am_min_lanes)
+ self.registry = PatchRegistry()
+ self.vocab_ids: np.ndarray = np.zeros(0, dtype=np.uint64) # col -> id
+ self.n_out = cfg.vocab_size + 1
+ self.meta: dict = {}
+ # inference-time fusion calibration (variance matching): the raw slow
+ # readout operates at a different score scale than the fast one, so the
+ # top-down prior is rescaled by sigma_fast/sigma_slow — measured once
+ # on a reference stream (calibrate_fusion), never trained.
+ self.fusion: dict = {"scale": 1.0, "sigma_fast": None, "sigma_slow": None}
+ # episodic traces retained for hippocampal replay (CA3-style sequence
+ # store; the AM itself only keeps hashed associations)
+ self.episodes: list[np.ndarray] = []
+
+ # ================================================================ build
+ @classmethod
+ def build(cls, train_bytes: bytes, cfg: SPIRAConfig, log=print) -> "SPIRA":
+ m = cls(cfg)
+ fit_slice = train_bytes[: 2_000_000]
+ calib_slice = train_bytes[2_000_000: 2_400_000]
+ log("[spira] fitting EPT byte-level Markov model ...")
+ m.ept.fit(fit_slice)
+ if calib_slice:
+ budget = m.ept.calibrate(calib_slice, target_len=cfg.target_avg_len)
+ log(f"[spira] calibrated surprisal budget = {budget:.2f} bits "
+ f"(target avg patch len {cfg.target_avg_len})")
+ log("[spira] segmenting full train stream ...")
+ t0 = time.perf_counter()
+ patches = m.ept.segment(train_bytes)
+ ids = np.fromiter((fnv1a64(p) for p in patches), dtype=np.uint64, count=len(patches))
+ seg_s = time.perf_counter() - t0
+ st = m.ept.stats(patches)
+ log(f"[spira] {st['n_patches']} patches, avg len {st['avg_len']:.2f} B "
+ f"({st['bytes']/1e6:.1f} MB segmented in {seg_s:.1f}s, "
+ f"{st['bytes']/1e6/max(seg_s,1e-9):.2f} MB/s)")
+ uniq, cnt = np.unique(ids, return_counts=True)
+ log(f"[spira] distinct patches in train: {len(uniq)}")
+ # vocabulary: top-V by count (deterministic tie-break: larger id first)
+ order = np.lexsort((uniq, -cnt))[: cfg.vocab_size]
+ m.vocab_ids = np.sort(uniq[order]).astype(np.uint64)
+ # registry: vocab + anything with count >= 2 (repeatable content)
+ keep = set(m.vocab_ids.tolist()) | set(uniq[cnt >= 2].tolist())
+ log(f"[spira] building patch registry ({len(keep)} ids) ...")
+ m.registry = PatchRegistry.build(ids, patches, keep=keep)
+ m.meta = {
+ "train_bytes": len(train_bytes),
+ "n_patches": st["n_patches"],
+ "avg_patch_len": st["avg_len"],
+ "distinct_patches": int(len(uniq)),
+ "registry_size": len(m.registry),
+ "budget_bits": m.ept.budget_bits,
+ "segmentation_MB_per_s": st["bytes"] / 1e6 / max(seg_s, 1e-9),
+ }
+ m._ids_train = ids
+ m._patches_train = None # registry carries everything; free ~100MB
+ return m
+
+ # =========================================================== array prep
+ @staticmethod
+ def input_neurons_stream(ids: np.ndarray, d_in: int, k_in: int) -> np.ndarray:
+ """Vectorized input-neuron projection: (T, k_in) int32."""
+ T = len(ids)
+ out = np.empty((T, k_in), dtype=np.int32)
+ u64 = ids.astype(np.uint64)
+ for j in range(k_in):
+ salt = (0x51ED270B733D4C31 + j * 0x9E3779B97F4A7C15) & 0xFFFFFFFFFFFFFFFF
+ z = u64 ^ np.uint64(salt)
+ z = z + np.uint64(0x9E3779B97F4A7C15)
+ z = (z ^ (z >> np.uint64(30))) * np.uint64(0xBF58476D1CE4E5B9)
+ z = (z ^ (z >> np.uint64(27))) * np.uint64(0x94D049BB133111EB)
+ z = z ^ (z >> np.uint64(31))
+ out[:, j] = ((z >> np.uint64(32)) % np.uint64(d_in)).astype(np.int32)
+ return out
+
+ def cols_of(self, ids: np.ndarray) -> np.ndarray:
+ """Vocabulary column per patch id (UNK -> last column)."""
+ V = self.cfg.vocab_size
+ pos = np.searchsorted(self.vocab_ids, ids)
+ pos_c = np.minimum(pos, V - 1)
+ ok = (pos < V) & (self.vocab_ids[pos_c] == ids)
+ cols = np.where(ok, pos_c, V).astype(np.int64) # V = UNK column
+ return cols
+
+ # ------------------------------------------------------- v3 input rows
+ def _structured_row(self, pid: int, pbytes: bytes | None) -> np.ndarray:
+ """Input-neuron row for one patch: (k_in - k_tri) whole-patch hash
+ neurons + k_tri byte-trigram hash neurons. Patches sharing trigrams
+ share input neurons, so similar contexts produce similar reservoir
+ states (v1/v2 rows were pure whole-patch hashes: fully orthogonal).
+ Falls back to the v2 row when the patch bytes are unknown."""
+ from .hashing import fnv1a64, input_neurons, splitmix64
+ cfg = self.cfg
+ if not cfg.structured_inputs or pbytes is None:
+ return np.asarray(input_neurons(pid, cfg.d_in, cfg.k_in), dtype=np.int32)
+ k_whole = cfg.k_in - cfg.k_tri
+ row = list(input_neurons(pid, cfg.d_in, k_whole))
+ grams: set[bytes] = set()
+ if len(pbytes) >= 3:
+ grams = {pbytes[i:i + 3] for i in range(len(pbytes) - 2)}
+ elif len(pbytes) == 2:
+ grams = {pbytes}
+ cand = sorted({splitmix64(fnv1a64(g)) % cfg.d_in for g in grams})
+ tri = cand[: cfg.k_tri]
+ while len(tri) < cfg.k_tri: # short patches: fill from whole-hash salts
+ tri.append(int(input_neurons(pid, cfg.d_in, cfg.k_tri + len(tri))[-1]))
+ return np.asarray(row + tri, dtype=np.int32)
+
+ def neuron_rows(self, ids: np.ndarray, patches: list[bytes] | None = None) -> np.ndarray:
+ """(T, k_in) input rows; structured when enabled, v2-identical else."""
+ cfg = self.cfg
+ if not cfg.structured_inputs:
+ return self.input_neurons_stream(ids, cfg.d_in, cfg.k_in)
+ by_id: dict[int, bytes] = {}
+ if patches is not None:
+ for pid, pb in zip(ids.tolist(), patches):
+ by_id.setdefault(pid, pb)
+ rows = np.empty((len(ids), cfg.k_in), dtype=np.int32)
+ cache = self._row_cache
+ for t, pid in enumerate(ids.tolist()):
+ r = cache.get(pid)
+ if r is None:
+ pb = by_id.get(pid)
+ if pb is None:
+ pb = self.registry.bytes_of(pid)
+ r = self._structured_row(pid, pb)
+ cache[pid] = r
+ rows[t] = r
+ return rows
+
+ def prepare(self) -> None:
+ """Precompute training arrays for the SNN and AM subsets only."""
+ cfg = self.cfg
+ ids = self._ids_train
+ n_snn = min(cfg.snn_tokens, len(ids) - 1)
+ n_am = min(cfg.am_tokens, len(ids) - 1)
+ log = print
+ log(f"[spira] precomputing projections for {n_snn} SNN + {n_am} AM tokens ...")
+ t0 = time.perf_counter()
+ self._neurons = self.neuron_rows(ids[:n_snn])
+ self._cols = self.cols_of(ids[: n_snn + 1])
+ # AM: val = registry index of the NEXT token (skip unregistered)
+ am_ids = ids[:n_am]
+ reg_idx = np.full(n_am, -1, dtype=np.int64)
+ pos = np.searchsorted(self.registry.ids, am_ids)
+ pos_c = np.minimum(pos, len(self.registry.ids) - 1)
+ ok = (pos < len(self.registry.ids)) & (self.registry.ids[pos_c] == am_ids)
+ reg_idx[ok] = pos_c[ok]
+ self._reg_idx = reg_idx
+ ls = self.am.lane_keys_stream(am_ids)
+ # AM contexts (diagonal keys): ctx[r, l] = lane key of token r+l at
+ # slot l; the context ending at t = r+m-1 continues with token r+m.
+ m = self.am.m
+ n_ctx = len(ls) - m
+ ctx = np.empty((n_ctx, m), dtype=np.uint32)
+ for lane in range(m):
+ ctx[:, lane] = ls[lane : lane + n_ctx, lane]
+ self._am_ctx = ctx
+ log(f" done in {time.perf_counter()-t0:.1f}s")
+
+ # ================================================================ train
+ def train(self, log_fn=print, ckpt_path: str | None = None) -> dict:
+ cfg = self.cfg
+ n_snn = len(self._neurons)
+ n_ctx_am = len(self._am_ctx)
+ history = {"epochs": []}
+ for ep in range(cfg.epochs):
+ log_fn(f"[spira] === SNN epoch {ep+1}/{cfg.epochs} ({n_snn} ticks) ===")
+ res = self.core.train_pass(
+ self._neurons[:n_snn], self._cols[1 : n_snn + 1],
+ log_every=10_000,
+ log_fn=lambda d, ep=ep: log_fn(
+ f" tick {d['tick']}/{d['total']} acc={d['acc_ema']:.3f} "
+ f"dop={d['dopamine_ema']:+.3f} {d['ticks_per_sec']:.0f} t/s"),
+ record_raster_from=(n_snn - 1500 if ep == cfg.epochs - 1 else None),
+ )
+ raster = res.pop("raster", None)
+ if raster and ckpt_path:
+ ticks = np.concatenate([np.full(len(sp), t, dtype=np.int32) for t, sp in raster])
+ neurons_r = np.concatenate([sp for _, sp in raster]).astype(np.int32)
+ np.savez_compressed(ckpt_path + ".raster.npz", ticks=ticks, neurons=neurons_r)
+ history["epochs"].append({k: v for k, v in res.items()})
+ if ckpt_path:
+ self.save(ckpt_path)
+ # hippocampal one-shot pass over the (larger) AM stream
+ log_fn(f"[spira] === hippocampus one-shot write pass ({n_ctx_am} contexts) ===")
+ t0 = time.perf_counter()
+ m = self.am.m
+ ctx = self._am_ctx[:n_ctx_am]
+ vals = self._ids_train[m : m + n_ctx_am].astype(np.uint64)
+ self.am.write_stream(ctx, vals)
+ log_fn(f" wrote {n_ctx_am} associations in "
+ f"{time.perf_counter()-t0:.1f}s; {self.am.stats()}")
+ history["am"] = self.am.stats()
+ if ckpt_path:
+ self.save(ckpt_path)
+ return history
+
+ # =============================================================== predict
+ def _scores(self, x: np.ndarray) -> np.ndarray:
+ """Behavioural scores: fast readout + variance-matched top-down slow
+ prior (if the hierarchical cortex is active). No hippocampal vote."""
+ u = (x - self.core.x_mean) @ self.core.W_out
+ if self.core.hier:
+ u = u + np.float32(self.core.beta * self.fusion["scale"]) * self.core.u_slow
+ return u
+
+ def calibrate_fusion(self, data: bytes, n_tokens: int = 3000) -> dict:
+ """Measure fast/slow readout score scales on a reference stream and set
+ the fusion normalization sigma_fast/sigma_slow.
+
+ The slow readout's raw scores live at a different (much larger) scale
+ than the fast one; fusing them raw lets even a tiny beta swamp the fast
+ argmax. Variance matching bounds the top-down prior's contribution to
+ beta * sigma_fast — the same units the fast readout itself uses. Pure
+ measurement, no plasticity (same spirit as the EPT budget calibration).
+ """
+ patches = self.ept.segment(data)
+ ids = np.fromiter((fnv1a64(p) for p in patches), dtype=np.uint64,
+ count=len(patches))[: n_tokens + 1]
+ neurons = self.neuron_rows(ids[:-1], patches[:-1])
+ snap = self.core.snapshot()
+ w_rec_snap = self.core.W_rec.copy()
+ self.core.reset_dynamics()
+ self._win_count = 0
+ sig_f: list[float] = []
+ sig_s: list[float] = []
+ for t in range(len(ids) - 1):
+ x = self.core.step(neurons[t])
+ if self.core.hier:
+ self._win_count += 1
+ if self._win_count % self.core.win == 0:
+ self.core.step_G()
+ if len(sig_s) < 400 or len(sig_s) % 8 == 0:
+ sig_s.append(float(np.std(self.core.u_slow)))
+ u_fast = (x - self.core.x_mean) @ self.core.W_out
+ if len(sig_f) < 400 or len(sig_f) % 8 == 0:
+ sig_f.append(float(np.std(u_fast)))
+ self.core.restore(snap)
+ self.core.W_rec = w_rec_snap
+ sf = float(np.mean(sig_f)) if sig_f else 1.0
+ ss = float(np.mean(sig_s)) if sig_s else 1.0
+ self.fusion = {"scale": sf / max(ss, 1e-9), "sigma_fast": sf, "sigma_slow": ss}
+ return dict(self.fusion)
+
+ def _feed(self, pid: int) -> np.ndarray:
+ """Feed one token: fast step (+ slow step at window boundaries)."""
+ x = self.core.step(self._neuron_row(pid))
+ if self.core.hier:
+ self._win_count += 1
+ if self._win_count % self.core.win == 0:
+ self.core.step_G()
+ return x
+
+ def _col_of_id(self, pid: int) -> int | None:
+ """Vocab column of a patch id, or None if out of vocabulary."""
+ V = self.cfg.vocab_size
+ col = int(np.searchsorted(self.vocab_ids, np.uint64(pid)))
+ if col < V and self.vocab_ids[col] == np.uint64(pid):
+ return col
+ return None
+
+ def fuse_scores(self, x: np.ndarray, last_ids: list[int]):
+ """Combine behavioural scores (fast + top-down slow prior) with a
+ hippocampal vote.
+
+ Returns (fused_scores, am_val, am_weight, bypass_id).
+ """
+ u = self._scores(x)
+ am_val, am_w = None, 0.0
+ bypass_id = None
+ if len(last_ids) >= self.am.m:
+ lanes = self.am.lane_keys(last_ids[-self.am.m :])
+ am_val, am_w = self.am.query(lanes)
+ if am_val is None:
+ return u, am_val, am_w, None
+ pid = int(am_val)
+ col = self._col_of_id(pid)
+ if col is not None:
+ fused = u.copy()
+ fused[col] += self.cfg.beta_am * am_w
+ return fused, am_val, am_w, None
+ if am_w >= self.cfg.am_override and self.registry.bytes_of(pid) is not None:
+ bypass_id = pid # strong episodic recall outside vocabulary
+ return u, am_val, am_w, bypass_id
+
+ def generate(self, prompt: bytes, n_tokens: int = 120, temperature: float | None = None,
+ top_k: int | None = None, use_am: bool = True, seed: int | None = None,
+ on_token=None) -> bytes:
+ """Closed-loop generation: predicted patches are fed back as spikes."""
+ cfg = self.cfg
+ temperature = cfg.temperature if temperature is None else temperature
+ top_k = cfg.top_k if top_k is None else top_k
+ rng = np.random.default_rng(seed if seed is not None else int(time.time_ns() & 0x7FFFFFFF))
+ self.core.reset_dynamics()
+ self._win_count = 0
+ patches = self.ept.segment(prompt)
+ if not patches:
+ return prompt
+ ids = [fnv1a64(p) for p in patches]
+ out = bytearray(prompt)
+ V = cfg.vocab_size
+ UNK = V # UNK column index
+ # warm-up: feed the entire prompt (state now reflects the last patch)
+ x = np.zeros(self.core.n_res, dtype=np.float32)
+ for pid in ids:
+ x = self._feed(pid)
+ for step in range(n_tokens):
+ if use_am:
+ fused, am_val, am_w, bypass_id = self.fuse_scores(x, ids)
+ else:
+ fused, bypass_id = self._scores(x), None
+ if bypass_id is not None:
+ chosen_id = bypass_id
+ else:
+ scores = np.asarray(fused, dtype=np.float64).copy()
+ scores[UNK] = -np.inf # cannot emit UNK bytes
+ k = max(1, min(top_k, V))
+ top = np.argpartition(scores, -k)[-k:]
+ z = (scores[top] - scores[top].max()) / max(temperature, 1e-6)
+ w = np.exp(z)
+ w /= w.sum()
+ pick = int(top[rng.choice(len(top), p=w)])
+ chosen_id = int(self.vocab_ids[pick])
+ b = self.registry.bytes_of(chosen_id)
+ if b is None:
+ break # unknown emission: stop rather than corrupt
+ out.extend(b)
+ ids.append(chosen_id)
+ x = self._feed(chosen_id)
+ if on_token is not None:
+ on_token(step, b)
+ return bytes(out)
+
+ def _neuron_row(self, pid: int) -> np.ndarray:
+ r = self._row_cache.get(pid)
+ if r is None:
+ r = self._structured_row(pid, self.registry.bytes_of(pid))
+ self._row_cache[pid] = r
+ return r
+
+ # ============================================================= one-shot
+ def teach_bytes(self, data: bytes) -> dict:
+ """ONE-SHOT episodic teaching: segment, register unseen patches, and
+ write every context -> continuation into the hippocampus — a single
+ pass, no gradients, no epochs, no repetition."""
+ patches = self.ept.segment(data)
+ ids = np.fromiter((fnv1a64(p) for p in patches), dtype=np.uint64, count=len(patches))
+ return self.teach_ids(ids, patches)
+
+ def teach_ids(self, ids: np.ndarray, patches: list[bytes] | None = None,
+ episodic: bool = True) -> dict:
+ n = len(ids)
+ # 0) retain the episodic trace for hippocampal replay (the sequence
+ # the cortex will re-run during "sleep") — only for genuinely
+ # episodic teaching, not for the corpus baseline fill
+ if episodic:
+ self._remember_episode(ids)
+ # 1) register unseen patches so continuations are always storable
+ known = self.registry.has(ids)
+ if patches is not None:
+ new_map: dict[int, bytes] = {}
+ for i, b in zip(ids[~known].tolist(), (p for p, k in zip(patches, known) if not k)):
+ if i not in new_map:
+ new_map[i] = b
+ n_new = self.registry.extend(new_map)
+ else:
+ n_new = 0
+ # 2) write associations (vals are stable patch ids)
+ lane = self.am.lane_keys_stream(ids)
+ m = self.am.m
+ n_ctx = n - m
+ ctx = np.empty((n_ctx, m), dtype=np.uint32)
+ for li in range(m):
+ ctx[:, li] = lane[li : li + n_ctx, li]
+ vals = ids[m : m + n_ctx].astype(np.uint64)
+ self.am.write_stream(ctx, vals)
+ return {
+ "tokens": int(n),
+ "new_patches": int(n_new),
+ "associations": int(n_ctx),
+ "episode_tokens": int(n),
+ }
+
+ # ================================================================ replay
+ def _remember_episode(self, ids: np.ndarray) -> None:
+ """Append to the hippocampal episodic trace (ring-capped)."""
+ if len(ids) < 2:
+ return
+ self.episodes.append(np.asarray(ids, dtype=np.uint64))
+ total = sum(len(e) for e in self.episodes)
+ while total > self.EPI_CAP_TOKENS and len(self.episodes) > 1:
+ total -= len(self.episodes[0])
+ self.episodes.pop(0)
+
+ def replay(self, n_tokens: int | None = None, slice_len: int | None = None,
+ seed: int = 0, log=print) -> dict:
+ """Hippocampal replay -> cortical consolidation (closing the loop).
+
+ Random slices of the episodic traces retained by the hippocampus are
+ re-run through the cortex in full training mode: the same local rules
+ (three-factor readout delta, modulated recurrent STDP, dopaminergic
+ RPE, slow-area learning) now act on material the cortex never saw
+ externally. One-shot memories are gradually consolidated into slow
+ cortical weights — the complementary-systems loop, closed.
+
+ Biologically this is Sharpewave-ripple-like offline replay: the cortex
+ does not re-run isolated (context -> continuation) pairs but short
+ SEQUENCES, so reservoir state statistics match the awake stream.
+ """
+ cfg = self.cfg
+ n_tokens = cfg.replay_tokens if n_tokens is None else n_tokens
+ slice_len = cfg.replay_slice if slice_len is None else slice_len
+ if not self.episodes:
+ return {"replayed_tokens": 0, "note": "no episodic traces to replay"}
+ rng = np.random.default_rng(seed)
+ weights = np.array([len(e) for e in self.episodes], dtype=np.float64)
+ weights /= weights.sum()
+ chunks: list[np.ndarray] = []
+ got = 0
+ while got < n_tokens:
+ e = self.episodes[int(rng.choice(len(self.episodes), p=weights))]
+ start = int(rng.integers(0, max(1, len(e) - slice_len)))
+ take = min(slice_len, len(e) - start)
+ chunks.append(e[start : start + take])
+ got += take
+ ids = np.concatenate(chunks)
+ neurons = self.neuron_rows(ids[:-1])
+ cols = self.cols_of(ids)[1:]
+ log(f"[replay] re-running {len(ids)} cortical tokens sampled from "
+ f"{len(self.episodes)} episodic trace(s) (slice {slice_len})")
+ res = self.core.train_pass(
+ neurons, cols, log_every=25_000,
+ log_fn=lambda d: log(f" tick {d['tick']}/{d['total']} acc={d['acc_ema']:.3f} "
+ f"beta={d.get('beta')} {d['ticks_per_sec']:.0f} t/s"),
+ )
+ res.pop("raster", None)
+ return {"replayed_tokens": int(len(ids)), **res}
+
+ # ================================================================ eval
+ def eval_stream(self, data: bytes, use_am: bool = True, teach_am_first: bool = False,
+ corrupt_lanes: int = 0, seed: int = 0, max_positions: int | None = None) -> dict:
+ """Evaluate next-patch prediction on a byte stream.
+
+ Metrics for the SNN readout alone, the hippocampus alone, and the
+ fused system — both over all positions and over in-vocab targets only
+ (targets outside the readout vocabulary cannot be predicted by the
+ readout, but the hippocampus can still retrieve them).
+ """
+ from .hashing import lane_key32
+ patches = self.ept.segment(data)
+ ids = np.fromiter((fnv1a64(p) for p in patches), dtype=np.uint64, count=len(patches))
+ n = len(ids)
+ cols = self.cols_of(ids)
+ V = self.cfg.vocab_size
+ if teach_am_first:
+ # ONE-SHOT teaching pass (registers new patches too)
+ taught = self.teach_ids(ids, patches)
+ # SNN inference pass in the TRAINING regime: the reservoir keeps its
+ # modulated-STDP plasticity (the operating point is part of the
+ # learned system) while the readout stays frozen for measurement.
+ snap = self.core.snapshot()
+ w_rec_snap = self.core.W_rec.copy()
+ neurons = self.neuron_rows(ids, patches)
+ lane = self.am.lane_keys_stream(ids)
+ # diagonal context-key stream: ctxq[r] = key of context tokens r..r+m-1
+ m_ctx = self.am.m
+ n_ctxq = n - m_ctx + 1
+ ctxq = np.empty((n_ctxq, m_ctx), dtype=np.uint32)
+ for li in range(m_ctx):
+ ctxq[:, li] = lane[li : li + n_ctxq, li]
+ rng = np.random.default_rng(seed)
+ train_ids = self._ids_train if hasattr(self, "_ids_train") else ids
+ tot = inv = 0
+ snn_ok = snn_ok_inv = am_ok = am_ok_inv = fused_ok = fused_ok_inv = 0
+ hier_ok = hier_ok_inv = 0
+ stop = n - 1 if max_positions is None else min(n - 1, max_positions)
+ x = np.zeros(self.core.n_res, dtype=np.float32)
+ for t in range(stop):
+ x = self.core.step(neurons[t])
+ target_col = int(cols[t + 1])
+ target_id = int(ids[t + 1])
+ u_fast = (x - self.core.x_mean) @ self.core.W_out
+ if self.core.hier:
+ u = u_fast + np.float32(self.core.beta * self.fusion["scale"]) * self.core.u_slow
+ hier_pred = int(np.argmax(u[:V])) # cortex (fast + top-down)
+ else:
+ u = u_fast
+ hier_pred = None
+ pred = int(np.argmax(u_fast[:V])) # fast-area-only ablation
+ # keep training-regime reservoir dynamics (readout frozen)
+ self.core.learn_reservoir(hier_pred if hier_pred is not None else pred,
+ target_col, x, u=u_fast)
+ if self.core.hier and (t + 1) % self.core.win == 0:
+ self.core.step_G()
+ # hippocampal query with optional context corruption
+ am_val, am_w = None, 0.0
+ if use_am and t >= m_ctx - 1:
+ ctx_lane = ctxq[t - m_ctx + 1].copy()
+ if corrupt_lanes > 0:
+ pidxs = rng.choice(m_ctx, size=min(corrupt_lanes, m_ctx), replace=False)
+ for pidx in pidxs:
+ rand_id = int(train_ids[rng.integers(0, len(train_ids))])
+ ctx_lane[pidx] = lane_key32(rand_id, int(pidx))
+ am_val, am_w = self.am.query(ctx_lane)
+ am_id = int(am_val) if am_val is not None else None
+ am_hit = am_id == target_id
+ # fused prediction (hierarchical cortex + hippocampal vote)
+ fused_pred, bypass = (hier_pred if hier_pred is not None else pred), False
+ if am_id is not None:
+ col = self._col_of_id(am_id)
+ if col is not None:
+ fused = u.copy()
+ fused[col] += self.cfg.beta_am * am_w
+ fused_pred = int(np.argmax(fused))
+ elif am_w >= self.cfg.am_override:
+ bypass = True
+ fused_hit = am_hit if bypass else (fused_pred == target_col)
+ tot += 1
+ if target_col != V:
+ inv += 1
+ if pred == target_col:
+ snn_ok_inv += 1
+ if hier_pred is not None and hier_pred == target_col:
+ hier_ok_inv += 1
+ if am_hit:
+ am_ok_inv += 1
+ if fused_hit:
+ fused_ok_inv += 1
+ if pred == target_col:
+ snn_ok += 1
+ if hier_pred is not None and hier_pred == target_col:
+ hier_ok += 1
+ if am_hit:
+ am_ok += 1
+ if fused_hit:
+ fused_ok += 1
+ self.core.restore(snap)
+ self.core.W_rec = w_rec_snap
+ return {
+ "n_positions": tot,
+ "vocab_coverage": inv / max(tot, 1),
+ "snn_acc": snn_ok / max(tot, 1),
+ "hier_acc": hier_ok / max(tot, 1),
+ "am_acc": am_ok / max(tot, 1),
+ "fused_acc": fused_ok / max(tot, 1),
+ "snn_acc_invocab": snn_ok_inv / max(inv, 1),
+ "hier_acc_invocab": hier_ok_inv / max(inv, 1),
+ "am_acc_invocab": am_ok_inv / max(inv, 1),
+ "fused_acc_invocab": fused_ok_inv / max(inv, 1),
+ "corrupt_lanes": corrupt_lanes,
+ }
+
+ # =========================================================== save/load
+ def save(self, path: str, am_cap: int = 1_500_000) -> None:
+ """Checkpoint everything. ALL hippocampal entries are packed (a
+ one-shot episodic memory must persist single-occurrence traces!) in a
+ single memory-frugal pass.
+
+ AM packing dedups EXACTLY: every slot an entry occupies is derivable
+ from its key (primary full-key hash + leave-one-out hashes), so each
+ logical entry is packed once with its surviving copies marked.
+ """
+ from array import array
+ cfg = self.cfg
+ am = self.am
+ visited = np.zeros(am.size, dtype=np.bool_)
+ keys_buf = array("I")
+ vals_buf = array("Q")
+ counts_buf = array("B")
+ for addr in np.nonzero(am.used)[0]:
+ if visited[addr]:
+ continue
+ k = am.keys[addr]
+ c = int(am.counts[addr])
+ for a in am._slots_of(k):
+ if am.used[a] and np.array_equal(am.keys[a], k):
+ visited[a] = True
+ keys_buf.extend(k.tolist())
+ vals_buf.append(int(am.vals[addr]))
+ counts_buf.append(min(c, 255))
+ if len(vals_buf) >= am_cap:
+ break
+ n_e = len(vals_buf)
+ if n_e == 0:
+ am_keys = np.zeros((0, am.m), dtype=np.uint32)
+ am_vals = np.zeros(0, dtype=np.uint64)
+ am_counts = np.zeros(0, dtype=np.uint8)
+ else:
+ am_keys = np.frombuffer(keys_buf, dtype=np.uint32).reshape(n_e, am.m).copy()
+ am_vals = np.frombuffer(vals_buf, dtype=np.uint64).copy()
+ am_counts = np.frombuffer(counts_buf, dtype=np.uint8).copy()
+ np.savez_compressed(
+ path,
+ config=json.dumps(asdict(cfg)),
+ meta=json.dumps(self.meta),
+ fusion=json.dumps(self.fusion),
+ log2p=self.ept.log2p,
+ ept_params=np.array([self.ept.budget_bits, self.ept.min_len, self.ept.max_len, self.ept.alpha]),
+ W_rec=self.core.W_rec, W_out=self.core.W_out,
+ W_out_G=(self.core.W_outG if self.core.hier
+ else np.zeros((0, 0), dtype=np.float32)),
+ inhibitory=self.core.inhibitory,
+ vocab_ids=self.vocab_ids,
+ reg_ids=self.registry.ids, reg_offsets=self.registry.offsets,
+ reg_counts=self.registry.counts,
+ reg_buffer=np.frombuffer(self.registry.buffer, dtype=np.uint8),
+ am_keys=am_keys, am_vals=am_vals, am_counts=am_counts,
+ core_state=json.dumps({
+ k: (v if isinstance(v, float) else v.tolist())
+ for k, v in self.core.snapshot().items()
+ }),
+ )
+
+ @classmethod
+ def load(cls, path: str) -> "SPIRA":
+ z = np.load(path, allow_pickle=False)
+ cfg = SPIRAConfig(**json.loads(str(z["config"])))
+ m = cls(cfg)
+ if "fusion" in z:
+ m.fusion = json.loads(str(z["fusion"]))
+ m.ept.log2p = z["log2p"].astype(np.float32)
+ p = z["ept_params"]
+ m.ept.budget_bits, m.ept.min_len, m.ept.max_len, m.ept.alpha = (float(p[0]), int(p[1]), int(p[2]), float(p[3]))
+ m.core.W_rec = z["W_rec"].astype(np.float32)
+ m.core.W_out = z["W_out"].astype(np.float32)
+ m.core.inhibitory = z["inhibitory"].astype(np.bool_)
+ w_rec_max = 3.0 * m.core.w_rec_scale
+ m.core._rec_lo = np.where(m.core.inhibitory, -w_rec_max, 0.0).astype(np.float32)
+ m.core._rec_hi = np.where(m.core.inhibitory, 0.0, w_rec_max).astype(np.float32)
+ if "W_out_G" in z and cfg.hierarchy and z["W_out_G"].size > 0:
+ m.core.W_outG = z["W_out_G"].astype(np.float32)
+ else:
+ # v1 checkpoint: hierarchy absent — disable the slow area
+ cfg.hierarchy = False
+ m.core.hier = False
+ m.core.W_outG = None
+ m.core.reset()
+ if "core_state" in z:
+ st = json.loads(str(z["core_state"]))
+ restored = {}
+ for k, v in st.items():
+ if k in ("baseline", "beta"):
+ restored[k] = float(v)
+ else:
+ restored[k] = np.asarray(v, dtype=np.float32 if k not in ("refr",) else np.int8)
+ m.core.restore(restored)
+ m.vocab_ids = z["vocab_ids"].astype(np.uint64)
+ m.registry.ids = z["reg_ids"].astype(np.uint64)
+ m.registry.offsets = z["reg_offsets"].astype(np.uint64)
+ m.registry.counts = z["reg_counts"].astype(np.uint32)
+ m.registry.buffer = z["reg_buffer"].tobytes()
+ m.meta = json.loads(str(z["meta"]))
+ # rebuild hippocampus from packed entries: each entry returns to its
+ # derivable slots (primary full-key + leave-one-out), with the same
+ # best-effort collision policy as a live write — entries whose slots
+ # are taken by a different key are simply not redundantly copied.
+ keys = z["am_keys"]; vals = z["am_vals"]; counts = z["am_counts"]
+ am = m.am
+ for i in range(len(vals)):
+ k, v, c = keys[i], int(vals[i]), int(counts[i])
+ paddr = am.primary_addr(k)
+ if not am.used[paddr] or np.array_equal(am.keys[paddr], k):
+ am.keys[paddr] = k
+ am.vals[paddr] = v
+ am.counts[paddr] = c
+ am.used[paddr] = True
+ for lane in range(am.m):
+ addr = am.loo_addr(k, lane)
+ if not am.used[addr]:
+ am.keys[addr] = k
+ am.vals[addr] = v
+ am.counts[addr] = c
+ am.used[addr] = True
+ return m
diff --git a/results/hashing/lever2/code/python/spira/spiking.py b/results/hashing/lever2/code/python/spira/spiking.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ef5d95bae9f5c3a683ee1d5af4e857331ad0eea
--- /dev/null
+++ b/results/hashing/lever2/code/python/spira/spiking.py
@@ -0,0 +1,599 @@
+"""Spiking core: LIF reservoir + reward-modulated (three-factor) readout.
+
+Paradigm properties — no backpropagation, no gradients, no autodiff:
+ * Leaky integrate-and-fire (LIF) neurons with refractory periods and
+ homeostatic adaptive thresholds;
+ * Dale's law: each reservoir neuron is permanently excitatory or
+ inhibitory (20% inhibitory);
+ * Readout learning is a three-factor rule: eligibility (Hebbian pre/post
+ coincidence = reservoir trace x outcome) gated by a dopaminergic reward
+ prediction error d = r - baseline(r);
+ * Recurrent synapses follow a light reward-modulated STDP (trace-based),
+ sign-constrained to respect Dale's law;
+ * One simulation tick = one token (event-time, not wall-clock ms).
+
+All weights are constructed deterministically from a seeded mulberry32 PRNG
+so the TypeScript port regenerates bit-identical connectivity.
+"""
+from __future__ import annotations
+
+import numpy as np
+
+from .hashing import Mulberry32
+
+
+class SpikingCore:
+ def __init__(
+ self,
+ d_in: int = 1024,
+ k_in: int = 12,
+ n_res: int = 512,
+ n_out: int = 4097, # 4096 vocab + 1 UNK column
+ seed: int = 20261022,
+ in_fanout: int = 8,
+ rec_fanout: int = 24,
+ inh_frac: float = 0.50,
+ lam: float = 0.85, # membrane leak
+ base_thr: float = 1.0,
+ thr_min: float = 0.4,
+ thr_max: float = 8.0,
+ refrac: int = 2, # ticks
+ tau_trace: float = 0.40, # reservoir spike-trace decay
+ w_in_scale: float = 3.0,
+ w_rec_scale: float = 0.25,
+ w_clip: float = 4.0,
+ eta_delta: float = 0.5, # local Rescorla-Wagner delta rate (LMS-normalized)
+ eta_stdp: float = 0.0015, # recurrent modulated STDP rate
+ eta_homeo: float = 0.002, # adaptive-threshold rate
+ target_rate: float = 0.06, # target per-neuron firing probability/tick
+ baseline_momentum: float = 0.995,
+ # ---- hierarchical slow area G (multi-scale cortex, v2) ----
+ hier: bool = True,
+ n_g: int = 256, # slow-area neurons
+ win: int = 8, # fast ticks per slow step
+ w_g_scale: float = 6.0, # L -> G feedforward weight scale
+ w_recg_scale: float = 0.15, # G recurrent scale (fixed, no STDP)
+ lam_g: float = 0.6, # slow-area membrane leak
+ tau_trace_g: float = 0.5, # slow-area spike-trace decay
+ target_rate_g: float = 0.10, # target firing per slow step
+ eta_homeo_g: float = 0.01,
+ eta_delta_g: float = 2.0, # slow-readout delta rate (8x fewer updates)
+ eta_beta: float = 0.02, # top-down gain learning rate
+ beta_init: float = 0.25,
+ beta_max: float = 2.0,
+ # ---- v3 (Muse): multi-timescale traces + direct input pathway ----
+ trace_taus: tuple = (0.4,), # reservoir trace decays; readout sees ALL banks
+ direct_input: bool = False, # readout also sees a decayed trace of the
+ # exact input-neuron pattern (ESN-standard
+ # [state; input] readout, omitted in v1/v2)
+ direct_tau: float = 0.5, # decay of the direct input trace
+ direct_gain: float = 1.0,
+ ) -> None:
+ self.d_in, self.k_in, self.n_res, self.n_out = d_in, k_in, n_res, n_out
+ self.seed = seed
+ self.in_fanout, self.rec_fanout = in_fanout, rec_fanout
+ self.inh_frac = inh_frac
+ self.lam, self.base_thr = lam, base_thr
+ self.thr_min, self.thr_max = thr_min, thr_max
+ self.refrac = refrac
+ self.tau_trace = tau_trace
+ self.w_in_scale, self.w_rec_scale = w_in_scale, w_rec_scale
+ self.w_clip = w_clip
+ self.eta_delta, self.eta_stdp = eta_delta, eta_stdp
+ self.eta_homeo, self.target_rate = eta_homeo, target_rate
+ self.baseline_momentum = baseline_momentum
+ self.hier = hier
+ self.n_g, self.win = n_g, win
+ self.w_g_scale, self.w_recg_scale = w_g_scale, w_recg_scale
+ self.lam_g, self.tau_trace_g = lam_g, tau_trace_g
+ self.target_rate_g, self.eta_homeo_g = target_rate_g, eta_homeo_g
+ self.eta_delta_g = eta_delta_g
+ self.eta_beta, self.beta0, self.beta_max = eta_beta, beta_init, beta_max
+ # v3 structural params
+ self.trace_taus = tuple(float(t) for t in trace_taus)
+ self.direct_input = bool(direct_input)
+ self.direct_tau, self.direct_gain = float(direct_tau), float(direct_gain)
+ self.n_banks = len(self.trace_taus)
+ self.n_state = self.n_res * self.n_banks + (self.d_in if self.direct_input else 0)
+
+ # ------------------------------------------------ deterministic wiring
+ rng = Mulberry32(seed)
+ # Input -> reservoir: sparse fan-out per input neuron, dense storage.
+ self.W_in = np.zeros((d_in, n_res), dtype=np.float32)
+ for i in range(d_in):
+ for _ in range(in_fanout):
+ t = int(rng.next_float() * n_res)
+ self.W_in[i, t] += rng.next_weight(w_in_scale)
+ # Reservoir recurrent: sparse fan-out per source, Dale's law by source.
+ self.W_rec = np.zeros((n_res, n_res), dtype=np.float32)
+ self.inhibitory = np.zeros(n_res, dtype=np.bool_)
+ w_rec_max = 3.0 * w_rec_scale
+ for j in range(n_res):
+ is_inh = rng.next_float() < inh_frac
+ self.inhibitory[j] = is_inh
+ sign = -1.0 if is_inh else 1.0
+ for _ in range(rec_fanout):
+ t = int(rng.next_float() * n_res)
+ self.W_rec[j, t] += sign * abs(rng.next_weight(w_rec_scale))
+ # Keep Dale's law under plasticity:
+ # excitatory rows clipped to [0, w_rec_max], inhibitory to [-w_rec_max, 0]
+ self._rec_lo = np.where(self.inhibitory, -w_rec_max, 0.0).astype(np.float32)
+ self._rec_hi = np.where(self.inhibitory, 0.0, w_rec_max).astype(np.float32)
+ self.W_rec = np.clip(self.W_rec, self._rec_lo[:, None], self._rec_hi[:, None])
+
+ # Readout: small seeded init, learned by the three-factor rule.
+ rng2 = Mulberry32(seed + 1)
+ self.W_out = np.zeros((self.n_state, n_out), dtype=np.float32) # v3: n_state rows
+ # sparse-ish init: each column connected from a random 25% of neurons
+ for c in range(n_out):
+ for _ in range(n_res // 4):
+ r = int(rng2.next_float() * n_res)
+ self.W_out[r, c] += rng2.next_weight(0.05)
+
+ # ------------------------------------------ slow area G (hierarchy)
+ # Wired from SEPARATE PRNG streams (seed+2 / seed+3) so the fast-area
+ # sequences above are byte-identical to v1 — the TS port depends on
+ # the exact call order.
+ if hier:
+ rng3 = Mulberry32(seed + 2)
+ # L -> G: per fast-source fanout 2. Sign follows Dale's law of the
+ # PRESYNAPTIC fast neuron: excitatory cells excite G, inhibitory
+ # cells inhibit it (G sees the pooled fast spike volley).
+ self.W_inG = np.zeros((n_res, n_g), dtype=np.float32)
+ for i in range(n_res):
+ sign = -1.0 if self.inhibitory[i] else 1.0
+ for _ in range(2):
+ t = int(rng3.next_float() * n_g)
+ self.W_inG[i, t] += sign * abs(rng3.next_weight(w_g_scale))
+ # G recurrent: sparse, Dale by source, FIXED (slower areas
+ # plasticize slower — G plasticity lives in its readout only)
+ self.W_recG = np.zeros((n_g, n_g), dtype=np.float32)
+ g_rec_max = 3.0 * w_recg_scale
+ self.inhibitory_g = np.zeros(n_g, dtype=np.bool_)
+ for j in range(n_g):
+ is_inh = rng3.next_float() < 0.5
+ self.inhibitory_g[j] = is_inh
+ sign = -1.0 if is_inh else 1.0
+ for _ in range(8):
+ t = int(rng3.next_float() * n_g)
+ self.W_recG[j, t] += sign * abs(rng3.next_weight(w_recg_scale))
+ self._recg_lo = np.where(self.inhibitory_g, -g_rec_max, 0.0).astype(np.float32)
+ self._recg_hi = np.where(self.inhibitory_g, 0.0, g_rec_max).astype(np.float32)
+ self.W_recG = np.clip(self.W_recG, self._recg_lo[:, None], self._recg_hi[:, None])
+ # G readout: same seeded sparse init pattern as the fast readout
+ rng4 = Mulberry32(seed + 3)
+ self.W_outG = np.zeros((n_g, n_out), dtype=np.float32)
+ for c in range(n_out):
+ for _ in range(n_g // 4):
+ r = int(rng4.next_float() * n_g)
+ self.W_outG[r, c] += rng4.next_weight(0.05)
+
+ self.reset()
+
+ # ----------------------------------------------------------------- state
+ def reset(self) -> None:
+ self.v = np.zeros(self.n_res, dtype=np.float32)
+ self.thr = np.full(self.n_res, self.base_thr, dtype=np.float32)
+ self.rhat = np.full(self.n_res, self.target_rate, dtype=np.float32)
+ self.refr = np.zeros(self.n_res, dtype=np.int8)
+ self.x = np.zeros(self.n_state, dtype=np.float32) # v3: augmented readout state
+ self.x_prev = np.zeros(self.n_res, dtype=np.float32) # reservoir trace t-1 (STDP)
+ self.x_mean = np.zeros(self.n_state, dtype=np.float32)
+ self.x_eff = np.zeros(self.n_state, dtype=np.float32)
+ self._banks = np.zeros((self.n_banks, self.n_res), dtype=np.float32)
+ self._direct = np.zeros(self.d_in if self.direct_input else 0, dtype=np.float32)
+ self.s = np.zeros(self.n_res, dtype=np.float32) # last spike vector
+ self.baseline = 0.0
+ self.tick = 0
+ if self.hier:
+ self.v_G = np.zeros(self.n_g, dtype=np.float32)
+ self.thr_G = np.full(self.n_g, self.base_thr, dtype=np.float32)
+ self.rhat_G = np.full(self.n_g, self.target_rate_g, dtype=np.float32)
+ self.x_G = np.zeros(self.n_g, dtype=np.float32)
+ self.x_mean_G = np.zeros(self.n_g, dtype=np.float32)
+ self.s_G = np.zeros(self.n_g, dtype=np.float32)
+ self.win_spikes = np.zeros(self.n_res, dtype=np.float32)
+ self.u_slow = np.zeros(self.n_out, dtype=np.float32)
+ self.beta = self.beta0
+
+ # ------------------------------------------------------------- snapshots
+ def snapshot(self) -> dict:
+ """Full dynamical state (the homeostatic scalars are LEARNED state —
+ thresholds and the trace mean co-adapt with the readout)."""
+ d = {
+ "v": self.v.copy(), "thr": self.thr.copy(), "rhat": self.rhat.copy(),
+ "refr": self.refr.copy(), "x": self.x.copy(), "x_prev": self.x_prev.copy(),
+ "x_mean": self.x_mean.copy(), "s": self.s.copy(), "baseline": self.baseline,
+ "banks": self._banks.copy(), "direct": self._direct.copy(),
+ }
+ if self.hier:
+ d.update({
+ "v_G": self.v_G.copy(), "thr_G": self.thr_G.copy(),
+ "rhat_G": self.rhat_G.copy(), "x_G": self.x_G.copy(),
+ "x_mean_G": self.x_mean_G.copy(), "s_G": self.s_G.copy(),
+ "win_spikes": self.win_spikes.copy(), "u_slow": self.u_slow.copy(),
+ "beta": self.beta,
+ })
+ return d
+
+ def restore(self, st: dict) -> None:
+ self.v = st["v"].copy()
+ self.thr = st["thr"].copy()
+ self.rhat = st["rhat"].copy()
+ self.refr = st["refr"].copy()
+ self.x = st["x"].copy()
+ self.x_prev = st["x_prev"].copy()
+ self.x_mean = st["x_mean"].copy()
+ self.s = st["s"].copy()
+ self.baseline = st["baseline"]
+ if "banks" in st:
+ self._banks = st["banks"].copy()
+ self._direct = st["direct"].copy()
+ else: # reconstruct banks from the composed state vector
+ nb = self.n_banks * self.n_res
+ self._banks = self.x[:nb].reshape(self.n_banks, self.n_res).copy()
+ if self.direct_input:
+ self._direct = self.x[nb:].copy()
+ if self.hier and "v_G" in st:
+ self.v_G = st["v_G"].copy()
+ self.thr_G = st["thr_G"].copy()
+ self.rhat_G = st["rhat_G"].copy()
+ self.x_G = st["x_G"].copy()
+ self.x_mean_G = st["x_mean_G"].copy()
+ self.s_G = st["s_G"].copy()
+ self.win_spikes = st["win_spikes"].copy()
+ self.u_slow = st["u_slow"].copy()
+ self.beta = st["beta"]
+
+ def reset_dynamics(self) -> None:
+ """Reset transient dynamics but KEEP learned homeostatic scalars
+ (thresholds, rate estimates, trace mean, top-down gain) — used before
+ generation."""
+ thr, rhat, x_mean = self.thr, self.rhat, self.x_mean
+ if self.hier:
+ thr_G, rhat_G, x_mean_G, beta = self.thr_G, self.rhat_G, self.x_mean_G, self.beta
+ self.reset()
+ self.thr, self.rhat, self.x_mean = thr, rhat, x_mean
+ if self.hier:
+ self.thr_G, self.rhat_G, self.x_mean_G, self.beta = thr_G, rhat_G, x_mean_G, beta
+
+ # ------------------------------------------------------------- inference
+ def step(self, input_idx) -> np.ndarray:
+ """Advance one tick with the given active input neurons.
+
+ Returns the post-synaptic trace ``x`` (the state used for readout).
+ """
+ W_in, W_rec = self.W_in, self.W_rec
+ I = W_in[input_idx].sum(axis=0, dtype=np.float32)
+ I += self.s @ W_rec
+ v = self.lam * self.v + I
+ can = self.refr == 0
+ v[~can] = 0.0
+ spikes = (v >= self.thr) & can
+ v[spikes] = 0.0
+ np.subtract(self.refr, 1, out=self.refr, where=self.refr > 0)
+ self.refr[spikes] = self.refrac
+ self.v = v
+ self.s = spikes.astype(np.float32)
+ # homeostatic threshold via EMA firing-rate estimate
+ self.rhat += 0.02 * (self.s - self.rhat)
+ self.thr += self.eta_homeo * (self.rhat - self.target_rate)
+ np.clip(self.thr, self.thr_min, self.thr_max, out=self.thr)
+ # traces (v3): x_prev keeps the BANK-0 (fast) reservoir trace for STDP;
+ # the readout state x is the concatenation of all trace banks plus the
+ # direct input trace — context older than one tick survives in the
+ # slow banks and in the direct trace's decayed identity history.
+ self.x_prev = self._banks[0].copy()
+ for i, tau in enumerate(self.trace_taus):
+ if i == 0:
+ self._banks[i] = tau * self._banks[i] + self.s
+ else:
+ # slow banks are NORMALIZED traces (decay-weighted averages):
+ # a raw tau=0.95 sum would sit at ~20x the fast bank's scale
+ # and swamp both the readout geometry and the LMS rate.
+ self._banks[i] = tau * self._banks[i] + (1.0 - tau) * self.s
+ if self.direct_input:
+ self._direct *= np.float32(self.direct_tau)
+ np.add.at(self._direct, input_idx, np.float32(self.direct_gain))
+ self.x = np.concatenate([*self._banks, self._direct])
+ elif self.n_banks > 1:
+ self.x = np.concatenate([*self._banks])
+ else:
+ self.x = self._banks[0]
+ # slow EMA of the trace: homeostatic "synaptic scaling" analogue used
+ # to mean-center the readout input (kills the shared dense background
+ # that otherwise dominates column norms)
+ self.x_mean = 0.999 * self.x_mean + 0.001 * self.x
+ self.x_eff = self.x - self.x_mean
+ self.tick += 1
+ if self.hier:
+ self.win_spikes += self.s
+ return self.x
+
+ def scores(self, x: np.ndarray) -> np.ndarray:
+ """Readout scores from a (raw) trace — centers with the EMA mean."""
+ return (x - self.x_mean) @ self.W_out
+
+ # ------------------------------------------------- slow area (hierarchy)
+ def step_G(self) -> None:
+ """Advance the slow area one slow step (one window of ``win`` fast
+ ticks).
+
+ Input: the pooled fast-area spike volley over the window (bottom-up,
+ sign-preserving). Output: the cached slow readout ``u_slow``, used as
+ a top-down prior fused into the fast prediction with gain ``beta``.
+ Pure inference dynamics (homeostasis included, same regime as the
+ fast area); learning happens in ``learn_G``.
+ """
+ c = self.win_spikes * np.float32(1.0 / self.win)
+ I = c @ self.W_inG
+ I += self.s_G @ self.W_recG
+ v = self.lam_g * self.v_G + I
+ spikes = v >= self.thr_G
+ v[spikes] = 0.0
+ self.v_G = v
+ self.s_G = spikes.astype(np.float32)
+ self.rhat_G += 0.05 * (self.s_G - self.rhat_G)
+ self.thr_G += self.eta_homeo_g * (self.rhat_G - self.target_rate_g)
+ np.clip(self.thr_G, self.thr_min, self.thr_max, out=self.thr_G)
+ self.x_G = self.tau_trace_g * self.x_G + self.s_G
+ self.x_mean_G = 0.999 * self.x_mean_G + 0.001 * self.x_G
+ self.win_spikes[:] = 0.0
+ self.u_slow = (self.x_G - self.x_mean_G) @ self.W_outG
+
+ def learn_G(self, target: int, d: float) -> int:
+ """Delta-rule update on the SLOW readout, gated by the same dopaminergic
+ RPE that gates the fast one (a global neuromodulator broadcasts to both
+ areas — each readout computes its own local error from its own
+ activity). ``target`` is the majority vocabulary column of the NEXT
+ window. Returns 1 if the slow readout's own top prediction matches it.
+ """
+ x_effG = self.x_G - self.x_mean_G
+ u = self.u_slow
+ V = self.n_out - 1
+ own_pred = int(np.argmax(u[:V]))
+ correct = 1 if own_pred == target else 0
+ nx = 1.0 / (float(x_effG @ x_effG) + 1e-6)
+ k = min(16, V)
+ act = np.argpartition(u[:V], -k)[-k:]
+ if target < V:
+ cols = np.concatenate([act, np.array([target], dtype=np.int64)])
+ desired = np.zeros(len(cols), dtype=np.float32)
+ desired[-1] = 1.0
+ else:
+ cols = act
+ desired = np.zeros(len(cols), dtype=np.float32)
+ errs = u[cols] - desired
+ gate = float(np.clip(1.0 + d, 0.25, 2.0))
+ eta = np.float32(self.eta_delta_g * gate * nx)
+ W = self.W_outG
+ W[:, cols] -= eta * errs[None, :] * x_effG[:, None]
+ W[:, cols] = np.clip(W[:, cols], -self.w_clip, self.w_clip)
+ return correct
+
+ # ------------------------------------------------------------- learning
+ def learn(self, pred: int, target: int, x: np.ndarray,
+ u: np.ndarray | None = None, active_k: int = 16) -> tuple[int, float, float]:
+ """Local delta-rule readout update (Rescorla-Wagner) gated by a
+ dopaminergic reward-prediction error, + modulated recurrent STDP.
+
+ Each readout unit computes its OWN prediction error from its own
+ activity (no gradients, no chain rule, no backprop): units in the
+ active top-k set and the instructive target unit move their weights
+ to reduce (score - desired). The learning rate is gated by dopamine
+ d = reward - baseline (RPE), the classical Rescorla-Wagner / TD
+ account of neuromodulation.
+
+ Returns (correct, reward, dopamine).
+ """
+ correct = 1 if pred == target else 0
+ reward = float(correct)
+ self.baseline = self.baseline_momentum * self.baseline + (1 - self.baseline_momentum) * reward
+ d = reward - self.baseline # dopaminergic RPE
+
+ W_out = self.W_out
+ x_eff = x - self.x_mean
+ nx = 1.0 / (float(x_eff @ x_eff) + 1e-6) # LMS normalization
+ V = self.n_out - 1
+ if u is None:
+ u = x_eff @ W_out
+ # active set: top-k scored columns (+ target if in vocabulary)
+ k = min(active_k, V)
+ act = np.argpartition(u[:V], -k)[-k:]
+ if target < V:
+ cols = np.concatenate([act, np.array([target], dtype=np.int64)])
+ else:
+ cols = act
+ desired = np.zeros(len(cols), dtype=np.float32)
+ if target < V:
+ desired[-1] = 1.0 # one-hot with margin 1
+ errs = u[cols] - desired
+ # dopamine gates plasticity amplitude (dips shrink, bursts amplify)
+ gate = float(np.clip(1.0 + d, 0.25, 2.0))
+ eta = np.float32(self.eta_delta * gate * nx)
+ W_out[:, cols] -= eta * errs[None, :] * x_eff[:, None]
+ # clip in place (fancy-indexed views need explicit writeback)
+ W_out[:, cols] = np.clip(W_out[:, cols], -self.w_clip, self.w_clip)
+
+ # light reward-modulated STDP on recurrent synapses of spiked neurons
+ if self.s.any():
+ spiked = np.nonzero(self.s)[0]
+ W_rec = self.W_rec
+ delta = np.float32(self.eta_stdp * d)
+ # pre-trace (x_prev) paired with post spikes, gated by dopamine
+ W_rec[:, spiked] += delta * self.x_prev[:, None]
+ np.clip(W_rec[:, spiked], self._rec_lo[:, None], self._rec_hi[:, None],
+ out=W_rec[:, spiked])
+ # top-down gain: TRUST dynamics, gated by the same RPE (a
+ # noradrenergic gain-modulation analogue) with counterfactual credit:
+ # fused right + fast wrong -> the slow prior SAVED the choice -> trust builds (additive)
+ # fused wrong + fast right -> the slow prior CORRUPTED it -> trust decays (multiplicative)
+ # Trust building slowly and decaying fast (loss aversion) lets the
+ # system keep a genuinely informative slow area while driving a
+ # noise- or frequency-prior-dominated one to beta ~ 0.
+ if self.hier and target < V:
+ pred_fast = int(np.argmax(u[:V]))
+ if pred_fast != target and correct: # slow saved it
+ self.beta = min(self.beta + self.eta_beta * gate, self.beta_max)
+ elif pred_fast == target and not correct: # slow corrupted it
+ self.beta *= float(0.98) ** gate
+ if self.beta < 1e-4:
+ self.beta = 0.0
+ else:
+ us_t = float(self.u_slow[target])
+ us_p = float(self.u_slow[pred_fast])
+ norm = abs(us_t) + abs(us_p) + 1e-6
+ margin = float(np.tanh(3.0 * (us_t - us_p) / norm))
+ self.beta = float(np.clip(
+ self.beta + 0.25 * self.eta_beta * gate * margin,
+ 0.0, self.beta_max))
+ return correct, reward, d
+
+ def learn_reservoir(self, pred: int, target: int, x: np.ndarray,
+ u: np.ndarray | None = None) -> tuple[int, float, float]:
+ """Training-regime dynamics WITHOUT readout plasticity: same reward,
+ same dopaminergic RPE, same recurrent STDP — only the W_out delta
+ update is skipped. Used at inference so the reservoir runs in its
+ training operating regime (continual plasticity, frozen readout)."""
+ correct = 1 if pred == target else 0
+ reward = float(correct)
+ self.baseline = self.baseline_momentum * self.baseline + (1 - self.baseline_momentum) * reward
+ d = reward - self.baseline
+ if self.s.any():
+ spiked = np.nonzero(self.s)[0]
+ W_rec = self.W_rec
+ delta = np.float32(self.eta_stdp * d)
+ W_rec[:, spiked] += delta * self.x_prev[:, None]
+ W_rec[:, spiked] = np.clip(W_rec[:, spiked], self._rec_lo[:, None], self._rec_hi[:, None])
+ return correct, reward, d
+
+ # ------------------------------------------------------- training driver
+ def train_pass(
+ self,
+ neurons: np.ndarray, # (T, k_in) int32 active input neurons per tick
+ cols: np.ndarray, # (T,) int64 target column per tick (col of token t+1)
+ log_every: int = 5000,
+ log_fn=None,
+ decay_every: int = 1024,
+ decay: float = 1e-4,
+ record_raster_from: int | None = None,
+ ) -> dict:
+ """One epoch over a token stream (teacher forcing on the next token).
+
+ ``neurons[t]`` drives the reservoir at tick t; the prediction made
+ from the resulting state is scored against ``cols[t]``.
+ """
+ self.reset()
+ T = len(cols)
+ acc_ema = None
+ d_ema = 0.0
+ n_correct = 0
+ n_correct_fast = 0
+ raster: list[tuple[int, np.ndarray]] = []
+ V_vocab = self.n_out - 1 # UNK occupies the last column
+ import time
+ t0 = time.perf_counter()
+ for t in range(T):
+ x = self.step(neurons[t])
+ u = (x - self.x_mean) @ self.W_out
+ if self.hier:
+ # behavioural prediction = fast readout + top-down slow prior
+ fused = u + np.float32(self.beta) * self.u_slow
+ pred = int(np.argmax(fused[:V_vocab]))
+ else:
+ pred = int(np.argmax(u[:V_vocab])) # vocabulary-only prediction
+ correct, reward, d = self.learn(pred, int(cols[t]), x, u=u)
+ n_correct += correct
+ if self.hier:
+ pred_fast = int(np.argmax(u[:V_vocab]))
+ if pred_fast == int(cols[t]):
+ n_correct_fast += 1
+ if (t + 1) % self.win == 0:
+ self.step_G()
+ if t + 1 < T:
+ seg = cols[t + 1 : min(t + 1 + self.win, T)]
+ g_target = int(np.bincount(seg).argmax())
+ self.learn_G(g_target, d)
+ acc_ema = reward if acc_ema is None else 0.999 * acc_ema + 0.001 * reward
+ d_ema = 0.999 * d_ema + 0.001 * d
+ if record_raster_from is not None and t >= record_raster_from:
+ raster.append((t, np.nonzero(self.s)[0].astype(np.int16)))
+ if (t + 1) % log_every == 0 and log_fn is not None:
+ dt = time.perf_counter() - t0
+ log_fn({
+ "tick": t + 1, "total": T,
+ "acc_ema": round(acc_ema, 4),
+ "acc_fast_ema": (round(0.999 * (n_correct_fast / max(t + 1, 1)), 4)
+ if self.hier else None),
+ "beta": (round(self.beta, 3) if self.hier else None),
+ "dopamine_ema": round(d_ema, 4),
+ "ticks_per_sec": round((t + 1) / max(dt, 1e-9), 1),
+ "elapsed_s": round(dt, 1),
+ })
+ if (t + 1) % decay_every == 0:
+ self.W_out *= np.float32(1.0 - decay)
+ if self.hier:
+ self.W_outG *= np.float32(1.0 - decay)
+ dt = time.perf_counter() - t0
+ return {
+ "ticks": T,
+ "accuracy": n_correct / max(T, 1),
+ "accuracy_fast_only": (n_correct_fast / max(T, 1)) if self.hier else None,
+ "beta": float(self.beta) if self.hier else None,
+ "acc_ema_final": acc_ema,
+ "elapsed_s": dt,
+ "ticks_per_sec": T / max(dt, 1e-9),
+ "raster": raster,
+ }
+
+ # ------------------------------------------------------------ (de)hydrate
+ def state_dict(self) -> dict:
+ sd = {
+ "config": {
+ "d_in": self.d_in, "k_in": self.k_in, "n_res": self.n_res,
+ "n_out": self.n_out, "seed": self.seed,
+ "in_fanout": self.in_fanout, "rec_fanout": self.rec_fanout,
+ "inh_frac": self.inh_frac, "lam": self.lam,
+ "base_thr": self.base_thr, "refrac": self.refrac,
+ "tau_trace": self.tau_trace,
+ "w_in_scale": self.w_in_scale, "w_rec_scale": self.w_rec_scale,
+ "w_clip": self.w_clip, "eta_delta": self.eta_delta, "eta_stdp": self.eta_stdp,
+ "eta_homeo": self.eta_homeo,
+ "target_rate": self.target_rate,
+ "hier": self.hier, "n_g": self.n_g, "win": self.win,
+ "w_g_scale": self.w_g_scale, "w_recg_scale": self.w_recg_scale,
+ "lam_g": self.lam_g, "tau_trace_g": self.tau_trace_g,
+ "target_rate_g": self.target_rate_g, "eta_homeo_g": self.eta_homeo_g,
+ "eta_delta_g": self.eta_delta_g,
+ "eta_beta": self.eta_beta, "beta_init": self.beta0, "beta_max": self.beta_max,
+ "trace_taus": list(self.trace_taus), "direct_input": self.direct_input,
+ "direct_tau": self.direct_tau, "direct_gain": self.direct_gain,
+ },
+ "W_rec": self.W_rec.astype(np.float32),
+ "W_out": self.W_out.astype(np.float32),
+ "inhibitory": self.inhibitory,
+ }
+ if self.hier:
+ sd["W_out_G"] = self.W_outG.astype(np.float32)
+ return sd
+
+ def load_state_dict(self, sd: dict) -> None:
+ cfg = sd["config"]
+ self.__dict__.update(cfg)
+ # v3 derived structure (defaults reproduce v2 for old checkpoints)
+ self.trace_taus = tuple(float(t) for t in getattr(self, "trace_taus", (self.tau_trace,)))
+ self.direct_input = bool(getattr(self, "direct_input", False))
+ self.n_banks = len(self.trace_taus)
+ self.n_state = int(sd["W_out"].shape[0])
+ self.W_rec = np.asarray(sd["W_rec"], dtype=np.float32)
+ self.W_out = np.asarray(sd["W_out"], dtype=np.float32)
+ self.inhibitory = np.asarray(sd["inhibitory"], dtype=np.bool_)
+ w_rec_max = 3.0 * self.w_rec_scale
+ self._rec_lo = np.where(self.inhibitory, -w_rec_max, 0.0).astype(np.float32)
+ self._rec_hi = np.where(self.inhibitory, 0.0, w_rec_max).astype(np.float32)
+ if "W_out_G" in sd and self.hier:
+ self.W_outG = np.asarray(sd["W_out_G"], dtype=np.float32)
+ else:
+ # v1 checkpoint without the slow area
+ self.hier = False
+ self.reset()
diff --git a/results/hashing/lever2/code/python/spira/train.py b/results/hashing/lever2/code/python/spira/train.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b5362f318f92ef7e6cd9f4116e6d6e3c17b3b4e
--- /dev/null
+++ b/results/hashing/lever2/code/python/spira/train.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python3
+"""SPIRA training CLI.
+
+Usage:
+ python3 -m spira.train --data data/train.bin \
+ --out artifacts/spira_model.npz \
+ [--snn-tokens 600000] [--am-tokens 1200000] [--epochs 2] [--quick]
+
+Writes:
+ : model checkpoint (npz)
+ .train_log.jsonl : tick-level progress log
+ .history.json : final training history
+"""
+from __future__ import annotations
+
+import argparse
+import json
+import sys
+import time
+
+from .model import SPIRA, SPIRAConfig
+
+
+def main() -> None:
+ ap = argparse.ArgumentParser()
+ ap.add_argument("--data", required=True)
+ ap.add_argument("--out", required=True)
+ ap.add_argument("--snn-tokens", type=int, default=600_000)
+ ap.add_argument("--am-tokens", type=int, default=1_200_000)
+ ap.add_argument("--epochs", type=int, default=2)
+ ap.add_argument("--vocab", type=int, default=4096)
+ ap.add_argument("--n-res", type=int, default=512)
+ ap.add_argument("--target-avg-len", type=float, default=4.5)
+ ap.add_argument("--quick", action="store_true", help="tiny smoke-test run")
+ args = ap.parse_args()
+
+ cfg = SPIRAConfig(
+ vocab_size=args.vocab,
+ n_res=args.n_res,
+ snn_tokens=args.snn_tokens,
+ am_tokens=args.am_tokens,
+ epochs=args.epochs,
+ target_avg_len=args.target_avg_len,
+ )
+ if args.quick:
+ cfg.snn_tokens, cfg.am_tokens, cfg.epochs = 20_000, 20_000, 1
+
+ data = open(args.data, "rb").read()
+ t0 = time.perf_counter()
+
+ log_path = args.out + ".train_log.jsonl"
+ log_f = open(log_path, "w")
+
+ def log(msg: str) -> None:
+ print(msg, flush=True)
+ log_f.write(json.dumps({"t": round(time.perf_counter() - t0, 1), "msg": msg}) + "\n")
+ log_f.flush()
+
+ def tick_log(d: dict) -> None:
+ log_f.write(json.dumps({"t": round(time.perf_counter() - t0, 1), **d}) + "\n")
+ log_f.flush()
+
+ model = SPIRA.build(data, cfg, log=log)
+ model.prepare()
+ # free the patch list — the registry carries everything we need
+ model._patches_train = None
+
+ log("[spira] training starts")
+ history = model.train(
+ log_fn=lambda msg: tick_log({"msg": msg}) or print(msg, flush=True),
+ ckpt_path=args.out,
+ )
+ history["build_meta"] = model.meta
+ history["config"] = {k: v for k, v in vars(cfg).items()}
+ history["wall_clock_s"] = time.perf_counter() - t0
+ with open(args.out + ".history.json", "w") as f:
+ json.dump(history, f, indent=2)
+ model.save(args.out)
+ log(f"[spira] DONE in {history['wall_clock_s']:.0f}s -> {args.out}")
+ log_f.close()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/results/hashing/lever2/code/relay_entry.md b/results/hashing/lever2/code/relay_entry.md
new file mode 100644
index 0000000000000000000000000000000000000000..031af6684b4b50e40de294641fd9ee7ca1e15216
--- /dev/null
+++ b/results/hashing/lever2/code/relay_entry.md
@@ -0,0 +1,9 @@
+
+## 2026-10-24 02:43:29 EDT — SPIRA Hashing — levier 2 (anti-mémorisation), version COURTE old_local_v1 : résultat
+Règle locale, sans gradient ni perte globale : inhibition latérale anti-hebbienne (Földiák) sur la trace rapide y (bank 0, tau 0.4) du réservoir. Courant I_j -= Σ_i Q_ij·y_prev_i ; mise à jour à chaque tick d'entraînement Q_ij += eta_ah·(y_i·y_j − rho²), i≠j, Q∈[0, 0.5], rho=0.1 ; Q figé en calibration/éval. Décodage/fusion inchangés.
+Bras à budget égal : CMSPIRA (v3 + Count-Min d24/4096, cfg repo par défaut) sur broad/old_local_v1 complet, seule réduction commune snn_tokens=24000 × 2 époques, AM 1,2 M, même seed ; ref = eta_ah 0 (pas identique au step du repo). Réglages pré-déclarés : AH1 eta_ah=1e-3, AH2 eta_ah=1e-2. Fenêtres (4000 positions chacune) : seen = train[:200000] (dans le préfixe SNN), fc2, fresh_en, fresh_fr, test20k ; neither_code exclu. Comparaison McNemar v4.1 (fused_hit & invocab, binomial exact, appariement par patch, même tokenizer vérifié via tgt_start) + IC bootstrap seed 0, B=10000, blocs 512 o. Critère : RETENU seulement si significativement meilleur sur vu ET au moins une fenêtre fraîche sans aucune fenêtre fraîche significativement pire.
+
+
+Verdicts : AH1: ÉCHEC du run/comparaison (Command '['/workspace/SPIRA-venv/bin/python', '/tmp/spira_hashing_lever2/compare.py', '/workspace/spira_shared/hashing_gen/lever2/short_old', 'ref', 'AH1']' returned non-zero exit status 1.); AH2: ÉCHEC du run/comparaison (Command '['/workspace/SPIRA-venv/bin/python', '/tmp/spira_hashing_lever2/compare.py', '/workspace/spira_shared/hashing_gen/lever2/short_old', 'ref', 'AH2']' returned non-zero exit status 1.)
+Code : /tmp/spira_hashing_lever2/{antihebb.py,run_l2.py,compare.py,finalize.py,chain.sh}. Logs/hits : /workspace/spira_shared/hashing_gen/lever2/short_old/ (results.jsonl, *.npz, mcnemar_*.json, short_old.*.log). broad_gutenberg_v1 seulement si RETENU.
+— SPIRA Hashing
diff --git a/results/hashing/lever2/code/test_compare_mcnemar.py b/results/hashing/lever2/code/test_compare_mcnemar.py
new file mode 100644
index 0000000000000000000000000000000000000000..0ba20943d233b352aceb4ad42607aa15421de4a3
--- /dev/null
+++ b/results/hashing/lever2/code/test_compare_mcnemar.py
@@ -0,0 +1,12 @@
+"""Test du correctif compare.py : p McNemar contre verdict_AH1.json / verdict_AH2.json (b,c,p) + cas connus."""
+import json, sys; sys.path.insert(0, "/workspace/spira_shared/hashing_gen/lever2/code"); from compare import mcnemar_exact, mcnemar_2tail
+ok = True
+for v in ("verdict_AH1.json", "verdict_AH2/verdict_AH2.json"):
+ R = json.load(open(f"/workspace/spira_shared/hashing_gen/lever2/{v}"))["per_window"]
+ for w, r in R.items():
+ b, c, p = r["b_ref_only"], r["c_cand_only"], r["mcnemar_p"]; p1 = mcnemar_exact(c, b); p2 = mcnemar_2tail(c, b)
+ good = abs(p1 - p) <= 1e-12 * max(1, p) and abs(p2 - p) <= 1e-12 * max(1, p); ok &= good
+ print(f"{v:30s} {w:9s} b/c={b}/{c} verdict p={p:.10g} compare p={p1:.10g} 2tail={p2:.10g} {'OK' if good else 'ÉCART'}")
+for g, l, exp in ((10, 24, 0.0243), (0, 0, 1.0), (5, 5, 1.0), (0, 10, 2/1024)):
+ p = mcnemar_exact(g, l); good = abs(p - exp) < 5e-5; ok &= good; print(f"cas {g}/{l}: p={p:.6g} attendu {exp:.6g} {'OK' if good else 'ÉCART'}")
+print("TOUS OK" if ok else "ÉCHEC DU TEST"); sys.exit(0 if ok else 1)
diff --git a/results/hashing/lever2/short_old/mcnemar_AH1_vs_ref.json b/results/hashing/lever2/short_old/mcnemar_AH1_vs_ref.json
new file mode 100644
index 0000000000000000000000000000000000000000..a370bffd503b9d5507e9f2467cc8470a51052530
--- /dev/null
+++ b/results/hashing/lever2/short_old/mcnemar_AH1_vs_ref.json
@@ -0,0 +1,77 @@
+{
+ "seen": {
+ "n": 4000,
+ "n_blocks": 42,
+ "ref_pct": 64.0,
+ "new_pct": 64.0,
+ "new_only": 0,
+ "ref_only": 0,
+ "p": 1.0,
+ "p_2tail": 1.0,
+ "delta_pt": 0.0,
+ "ci95": [
+ 0.0,
+ 0.0
+ ]
+ },
+ "fc2": {
+ "n": 4000,
+ "n_blocks": 37,
+ "ref_pct": 5.25,
+ "new_pct": 4.9,
+ "new_only": 10,
+ "ref_only": 24,
+ "p": 0.024306510109454393,
+ "p_2tail": 0.024306510109454393,
+ "delta_pt": -0.35,
+ "ci95": [
+ -0.708,
+ -0.025
+ ]
+ },
+ "fresh_en": {
+ "n": 4000,
+ "n_blocks": 35,
+ "ref_pct": 0.875,
+ "new_pct": 0.8,
+ "new_only": 8,
+ "ref_only": 11,
+ "p": 0.6476058959960938,
+ "p_2tail": 0.6476058959960938,
+ "delta_pt": -0.075,
+ "ci95": [
+ -0.297,
+ 0.148
+ ]
+ },
+ "fresh_fr": {
+ "n": 4000,
+ "n_blocks": 30,
+ "ref_pct": 0.0,
+ "new_pct": 0.0,
+ "new_only": 0,
+ "ref_only": 0,
+ "p": 1.0,
+ "p_2tail": 1.0,
+ "delta_pt": 0.0,
+ "ci95": [
+ 0.0,
+ 0.0
+ ]
+ },
+ "test20k": {
+ "n": 4000,
+ "n_blocks": 35,
+ "ref_pct": 0.575,
+ "new_pct": 0.525,
+ "new_only": 2,
+ "ref_only": 4,
+ "p": 0.6875,
+ "p_2tail": 0.6875,
+ "delta_pt": -0.05,
+ "ci95": [
+ -0.175,
+ 0.075
+ ]
+ }
+}
\ No newline at end of file
diff --git a/results/hashing/lever2/short_old/results.jsonl b/results/hashing/lever2/short_old/results.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..018e6c40fa71106756e4f48dc10c451094b78b5c
--- /dev/null
+++ b/results/hashing/lever2/short_old/results.jsonl
@@ -0,0 +1,15 @@
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "seen", "n": 4000, "fused_invocab_pct": 98.462, "fused_all_pct": 98.0, "snn_invocab_pct": 42.885, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 136.3, "peak_rss_mb": 814.2}
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "fc2", "n": 4000, "fused_invocab_pct": 8.255, "fused_all_pct": 5.7, "snn_invocab_pct": 3.459, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 154.7, "peak_rss_mb": 815.5}
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "fresh_en", "n": 4000, "fused_invocab_pct": 1.229, "fused_all_pct": 0.875, "snn_invocab_pct": 1.124, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 169.8, "peak_rss_mb": 815.5}
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "fresh_fr", "n": 4000, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 165.9, "peak_rss_mb": 877.3}
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "test20k", "n": 4000, "fused_invocab_pct": 0.821, "fused_all_pct": 0.575, "snn_invocab_pct": 0.678, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 167.0, "peak_rss_mb": 877.3}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "seen", "n": 4000, "fused_invocab_pct": 98.462, "fused_all_pct": 98.0, "snn_invocab_pct": 45.962, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 148.1, "peak_rss_mb": 810.3}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "fc2", "n": 4000, "fused_invocab_pct": 7.704, "fused_all_pct": 5.35, "snn_invocab_pct": 3.341, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 148.0, "peak_rss_mb": 811.5}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "fresh_en", "n": 4000, "fused_invocab_pct": 1.124, "fused_all_pct": 0.8, "snn_invocab_pct": 1.159, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 144.2, "peak_rss_mb": 811.7}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "fresh_fr", "n": 4000, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 147.0, "peak_rss_mb": 876.7}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "test20k", "n": 4000, "fused_invocab_pct": 0.75, "fused_all_pct": 0.525, "snn_invocab_pct": 0.678, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 147.5, "peak_rss_mb": 876.7}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "seen", "n": 4000, "fused_invocab_pct": 98.462, "fused_all_pct": 98.0, "snn_invocab_pct": 42.115, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 142.9, "peak_rss_mb": 810.2}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "fc2", "n": 4000, "fused_invocab_pct": 7.822, "fused_all_pct": 5.425, "snn_invocab_pct": 3.184, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 139.7, "peak_rss_mb": 810.8}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "fresh_en", "n": 4000, "fused_invocab_pct": 1.054, "fused_all_pct": 0.75, "snn_invocab_pct": 1.089, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 140.6, "peak_rss_mb": 811.1}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "fresh_fr", "n": 4000, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 138.7, "peak_rss_mb": 876.1}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "test20k", "n": 4000, "fused_invocab_pct": 0.785, "fused_all_pct": 0.55, "snn_invocab_pct": 0.75, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 142.8, "peak_rss_mb": 876.1}
diff --git a/results/hashing/lever2/short_old/summary_fr.md b/results/hashing/lever2/short_old/summary_fr.md
new file mode 100644
index 0000000000000000000000000000000000000000..ee496b89080a137e9380121dd4a7f7ae0a7a4136
--- /dev/null
+++ b/results/hashing/lever2/short_old/summary_fr.md
@@ -0,0 +1,3 @@
+
+
+Verdicts : AH1: ÉCHEC du run/comparaison (Command '['/workspace/SPIRA-venv/bin/python', '/tmp/spira_hashing_lever2/compare.py', '/workspace/spira_shared/hashing_gen/lever2/short_old', 'ref', 'AH1']' returned non-zero exit status 1.); AH2: ÉCHEC du run/comparaison (Command '['/workspace/SPIRA-venv/bin/python', '/tmp/spira_hashing_lever2/compare.py', '/workspace/spira_shared/hashing_gen/lever2/short_old', 'ref', 'AH2']' returned non-zero exit status 1.)
\ No newline at end of file
diff --git a/results/hashing/lever2/verdict_AH1/expected_sha.txt b/results/hashing/lever2/verdict_AH1/expected_sha.txt
new file mode 100644
index 0000000000000000000000000000000000000000..da252d65b187504e7d35b6ed130635924291c878
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/expected_sha.txt
@@ -0,0 +1,30 @@
+fcb845bde6b58ccd6006c64421289e5f5570af6a950b51fdebe92b4e98894bec verdict_AH1.md
+3b7b980184c06834a2b74b737c1ff99a6e87fff435294e4c257fcca6b397d483 verdict_AH1.json
+cc6ac84e2fb5b2e69b490a5841d1c533d36345a5f6e323874dcab53aab42fde3 verdict_AH1/verdict_AH1.py
+ff295fd751a4bd4e28109894d169f9c6db3fe65291bcea1cd7ddbe240c456ba9 verdict_AH1/verdict_AH1.log
+e0cc570b17d4c905f41f162f3a04a39bdfcee48b23a0b9e089d881627f50cb47 verdict_AH1/mask_oldtest_strict.py
+50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178 verdict_AH1/mask_oldtest_strict.npz
+aec3b4712d4f25b9829781119d6712277eaa637a77446892e2c162a92a35af77 verdict_AH1/mask_oldtest_strict.json
+7d9c2aa23ebd20ba1b63227430c646887b40d3b69cf2025f436477fef17258c4 verdict_AH1/mask_oldtest_strict.log
+004f17539a104fe27f61de314623c56cc0aabccddda6649348a5e8b6039ff4d6 verdict_AH1/gate.sh
+7517b9deb6ec2c79f2e9ace199d875cd919efc7a62e6cc10550787fc4c4591ec code/antihebb.py
+5642eba16edc563484d95e4f9ac15c80af5fa1eac796054e143dc3d83699def4 code/run_l2.py
+ec82ee5479b5cee747e8910104bdcd32611b5f35a7659ff4fb608f614f86deb4 code/countmin.py
+3b5df2a906fc327a83541bac786695451dfa56d8f507992c4a9d4f043b77c808 code/compare.py
+8e461d216fd729109b61b9b7767557ce08a4fcf51e25ce27096bd17a786c88b3 code/finalize.py
+d04549496ae89b1a44eb5c11d4ba7e136ece21ab57511ac0f322388481c40c7b code/chain.sh
+d2d86aeb0c515b66c33509f1327167e0530f27ea56fb79a161ea90cabc163f43 code/final.sh
+31b8e2b3643ac4cc056070efc671ccaa68a83c832161f0c7eb989a1254b71f6b code/REPO_COMMIT
+95fb11feed7708c95801d251ad9f4e01646b309de4c4b8c92d0cff93868dce5c verdict_AH1/results_ref_AH1.jsonl
+8b67c53136e95381d1282d3e3a2321a358bf4a0772e726824dfc82831e58e848 short_old.ref.log
+1730acf08c3ce41f8eaea8672b3a0fb7fce3e4c57c0b2ddb37c3813bb82543c4 short_old.AH1.log
+50ee8648bba55b661a87f850078a6fbac7f3edde95ba0621081c046fad4e89b3 short_old/AH1__fc2.npz
+8ae4cbd7ccb335eb702b77e14193fc29962daea196e28d7436471a833f1dab3d short_old/AH1__fresh_en.npz
+0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c short_old/AH1__fresh_fr.npz
+a8f2e55db3debd594f07eb4df826bd41bcfcfd54cf685b69946a7ccdb94f9108 short_old/AH1__seen.npz
+6a64e0ea7498e0e83e1521cf1d273751fcfad5e2f0207490dc1c271a564e8faf short_old/AH1__test20k.npz
+73ac8b9f777a42e223852450ef3c795122651893358407d53632f277f41f6003 short_old/ref__fc2.npz
+e2563d51b3677e4521e579c7e95afde18924ba8a7cee05c24f8ced0976b7817e short_old/ref__fresh_en.npz
+0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c short_old/ref__fresh_fr.npz
+a508542b6c6d1f4aafcb3c94fed843be7b4d5f4d136aeefca81cdee31d62eac8 short_old/ref__seen.npz
+3c304dcbb48c6907b519fd42cf95bd817f52343dc588d478aa4273292d99fd4d short_old/ref__test20k.npz
diff --git a/results/hashing/lever2/verdict_AH1/gate.sh b/results/hashing/lever2/verdict_AH1/gate.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ea2b80ed49a9c1b2decf1a4c4006ffd423d205bc
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/gate.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# attend MemAvailable >= 5,2 Go (décimal), sondage toutes les 2 min, puis exécute la commande en nice 10
+while [ $(awk '/MemAvailable/{printf "%d", $2*1024}' /proc/meminfo) -lt 5200000000 ]; do echo "$(TZ=America/Toronto date '+%F %T %Z') porte: MemAvailable $(awk '/MemAvailable/{printf "%.2f", $2*1024/1e9}' /proc/meminfo) Go < 5,2" ; sleep 120; done
+echo "$(TZ=America/Toronto date '+%F %T %Z') porte ouverte: MemAvailable $(awk '/MemAvailable/{printf "%.2f", $2*1024/1e9}' /proc/meminfo) Go"
+export OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0
+exec nice -n 10 "$@"
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/REPO_COMMIT b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/REPO_COMMIT
new file mode 100644
index 0000000000000000000000000000000000000000..baf4e912b97bf6eda69543bd279099001de16461
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/REPO_COMMIT
@@ -0,0 +1 @@
+6923c5191049ee488d9418c7002f108abd9e8ea1
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/antihebb.py b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/antihebb.py
new file mode 100644
index 0000000000000000000000000000000000000000..273ac20db855dd47570b63740b70a1b6060611c1
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/antihebb.py
@@ -0,0 +1,52 @@
+"""Lever 2 — local anti-Hebbian lateral decorrelation of fast reservoir traces (Foldiak 1990 style).
+No gradient, no global loss. Per tick, with y = bank-0 (fast) trace AFTER the step (y_prev = before):
+ lateral current I_j -= sum_i Q_ij * y_prev_i (Q >= 0, diag 0: learned inhibition)
+ local update Q_ij += eta_ah * (y_i * y_j - rho^2) (i != j), clip Q to [0, q_max]
+Q learns only during training (train_pass), frozen at eval/calibration. eta_ah=0 => exactly the reference step."""
+import numpy as np
+def install(core, eta_ah, rho=0.1, q_max=0.5):
+ core.eta_ah, core.rho2, core.q_max = np.float32(eta_ah), np.float32(rho*rho), np.float32(q_max)
+ core.Q = np.zeros((core.n_res, core.n_res), np.float32); core.ah_learn = False
+ orig_train_pass = core.train_pass
+ def train_pass(*a, **k):
+ core.ah_learn = True
+ try: return orig_train_pass(*a, **k)
+ finally: core.ah_learn = False
+ core.train_pass = train_pass
+ def step(input_idx):
+ self = core
+ I = self.W_in[input_idx].sum(axis=0, dtype=np.float32)
+ I += self.s @ self.W_rec
+ if self.eta_ah > 0: I -= self._banks[0] @ self.Q # lateral anti-Hebbian inhibition
+ v = self.lam * self.v + I
+ can = self.refr == 0
+ v[~can] = 0.0
+ spikes = (v >= self.thr) & can
+ v[spikes] = 0.0
+ np.subtract(self.refr, 1, out=self.refr, where=self.refr > 0)
+ self.refr[spikes] = self.refrac
+ self.v = v
+ self.s = spikes.astype(np.float32)
+ self.rhat += 0.02 * (self.s - self.rhat)
+ self.thr += self.eta_homeo * (self.rhat - self.target_rate)
+ np.clip(self.thr, self.thr_min, self.thr_max, out=self.thr)
+ self.x_prev = self._banks[0].copy()
+ for i, tau in enumerate(self.trace_taus):
+ if i == 0: self._banks[i] = tau * self._banks[i] + self.s
+ else: self._banks[i] = tau * self._banks[i] + (1.0 - tau) * self.s
+ if self.eta_ah > 0 and self.ah_learn:
+ y = self._banks[0]
+ self.Q += self.eta_ah * (np.outer(y, y) - self.rho2)
+ np.fill_diagonal(self.Q, 0.0); np.clip(self.Q, 0.0, self.q_max, out=self.Q)
+ if self.direct_input:
+ self._direct *= np.float32(self.direct_tau)
+ np.add.at(self._direct, input_idx, np.float32(self.direct_gain))
+ self.x = np.concatenate([*self._banks, self._direct])
+ elif self.n_banks > 1: self.x = np.concatenate([*self._banks])
+ else: self.x = self._banks[0]
+ self.x_mean = 0.999 * self.x_mean + 0.001 * self.x
+ self.x_eff = self.x - self.x_mean
+ self.tick += 1
+ if self.hier: self.win_spikes += self.s
+ return self.x
+ core.step = step
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/chain.sh b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/chain.sh
new file mode 100644
index 0000000000000000000000000000000000000000..883316b8acbd6fe668bd1220500fbb4005d784b1
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/chain.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+L=/tmp/spira_hashing_lever2; S=/workspace/spira_shared/hashing_gen/lever2; ST=$S/STATUS; OD=$S/short_old
+ts(){ TZ=America/Toronto date '+%F %T %Z'; }
+mem(){ awk '/MemAvailable/{print int($2/1048576)}' /proc/meminfo; }
+export OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0
+while kill -0 21098 2>/dev/null; do echo "$(ts) lever2: attente fin PID 21098 (mem $(mem) Go)" >> /tmp/spira_hashing.md; sleep 120; done
+for spec in "ref 0" "AH1 1e-3" "AH2 1e-2"; do set -- $spec
+ need=4; [ $1 = ref ] && need=5
+ while [ $(mem) -lt $need ]; do echo "$(ts) | lever2 $1: attente MemAvailable>=${need}Go (now $(mem))" >> $ST; sleep 60; done
+ nice -n 10 /workspace/SPIRA-venv/bin/python $L/run_l2.py $1 $2 24000 4000 $OD > $OD.$1.log 2>&1 &
+ P=$!; echo "$(ts) | lever2 $1 lancé PID $P (eta_ah=$2), ETA ~1h30 (train 48k ticks + eval 20k pos, box chargée)" >> $ST
+ if [ $1 = ref ]; then
+ flock /workspace/spira_shared/spira_relay.lock -c "printf '\n## %s — SPIRA Hashing — levier 2 lancé\nRun court old_local_v1 (bras ref puis AH1, AH2 en série), PID ref %s, 1 cœur nice 10. ETA fin des 3 bras ~4-5 h. Code /tmp/spira_hashing_lever2, logs /workspace/spira_shared/hashing_gen/lever2/.\n— SPIRA Hashing\n' \"$(ts)\" $P >> /workspace/spira_shared/spira_relay.md"
+ fi
+ while kill -0 $P 2>/dev/null; do echo "$(ts) lever2 $1 PID $P: $(tail -c 150 $OD.$1.log | tr '\n' ' ')" >> /tmp/spira_hashing.md; sleep 120; done
+ wait $P; echo "$(ts) | lever2 $1 fini rc=$? $(grep -c DONE $OD.$1.log)" >> $ST
+done
+echo "$(ts) | lever2: 3 bras finis, comparaison à faire" >> $ST
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/compare.py b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/compare.py
new file mode 100644
index 0000000000000000000000000000000000000000..4f173979d1302bdec36f095214f7f9f90156ada6
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/compare.py
@@ -0,0 +1,18 @@
+"""McNemar v4.1 (fused_hit & invocab, exact binomial, same tokenizer => patch-level pairing) + bootstrap seed0 B=10000 over 512-byte blocks."""
+import sys, json, numpy as np
+from scipy.stats import binomtest
+D, ref, new = sys.argv[1:4]; out = {}
+for w in ("seen","fc2","fresh_en","fresh_fr","test20k"):
+ a = np.load(f"{D}/{ref}__{w}.npz"); b = np.load(f"{D}/{new}__{w}.npz")
+ assert str(a["window_sha256"]) == str(b["window_sha256"]) and (a["tgt_start"] == b["tgt_start"]).all()
+ ha = a["fused_hit"] & a["invocab"]; hb = b["fused_hit"] & b["invocab"]; g = int((hb & ~ha).sum()); l = int((ha & ~hb).sum())
+ blk = a["tgt_start"] // 512; ub, inv = np.unique(blk, return_inverse=True)
+ sa = np.bincount(inv, ha); sb = np.bincount(inv, hb); cn = np.bincount(inv); rng = np.random.default_rng(0); nb = len(ub)
+ bs = np.empty(10000)
+ for i in range(10000):
+ k = rng.integers(0, nb, nb); bs[i] = 100 * (sb[k].sum() - sa[k].sum()) / cn[k].sum()
+ out[w] = dict(n=len(ha), n_blocks=nb, ref_pct=round(100*ha.mean(),3), new_pct=round(100*hb.mean(),3), new_only=g, ref_only=l,
+ p=binomtest(g, g+l, 0.5).pvalue if g+l else 1.0, delta_pt=round(100*(hb.mean()-ha.mean()),3),
+ ci95=[round(np.percentile(bs,2.5),3), round(np.percentile(bs,97.5),3)])
+ print(w, json.dumps(out[w]))
+json.dump(out, open(f"{D}/mcnemar_{new}_vs_{ref}.json","w"), indent=1)
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/countmin.py b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/countmin.py
new file mode 100644
index 0000000000000000000000000000000000000000..f474312930d572284606aa10f573354d498f946a
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/countmin.py
@@ -0,0 +1,129 @@
+"""RECONSTRUIT, À RE-VÉRIFIER (Hashing, 2026-10-23, après la perte de /tmp).
+Projection sémantique Count-Min MinHash, figée et déterministe, sans backprop.
+- Co-occurrences des colonnes de vocabulaire dans une fenêtre de ±W (W=2), comptées sur le train.
+- PPMI, puis les top-K (K=16) contextes par colonne.
+- d=24 fonctions MinHash sur cet ensemble de contextes -> 24 neurons dans un bloc sémantique
+ de largeur 4096, décalé après les d_in de base (v3 : 1024). Ligne finale = 12 neurones v3 + 24.
+Les choix de mise en page (bloc décalé, d_in total = 1024+4096) sont des HYPOTHÈSES :
+la mise en page de l'original n'est pas connue.
+"""
+from __future__ import annotations
+import json, sys
+import numpy as np
+sys.path.insert(0, "/tmp/spira_hashing_lever2/python")
+from spira import SPIRA, SPIRAConfig
+from spira.hashing import splitmix64
+
+M64 = 0xFFFFFFFFFFFFFFFF
+
+def cooc_ppmi_topk(cols: np.ndarray, V: int, window: int = 2, topk: int = 16) -> np.ndarray:
+ """cols: (T,) vocab cols, V == UNK (masked). Returns (V, topk) int64 context cols, -1 pad."""
+ keys = []
+ for o in range(1, window + 1):
+ a, b = cols[:-o], cols[o:]
+ ok = (a < V) & (b < V)
+ a, b = a[ok], b[ok]
+ keys.append(a * V + b); keys.append(b * V + a)
+ k, c = np.unique(np.concatenate(keys), return_counts=True)
+ w, ctx = k // V, k % V
+ c = c.astype(np.float64)
+ tot = c.sum()
+ rw = np.bincount(w, weights=c, minlength=V); rc = np.bincount(ctx, weights=c, minlength=V)
+ pmi = np.log(c * tot / (rw[w] * rc[ctx]))
+ pp = np.maximum(pmi, 0.0)
+ order = np.lexsort((ctx, -pp, w)) # par mot, PPMI décroissante, départage déterministe
+ w, ctx, pp = w[order], ctx[order], pp[order]
+ out = np.full((V, topk), -1, dtype=np.int64)
+ start = np.searchsorted(w, np.arange(V))
+ end = np.searchsorted(w, np.arange(V), side="right")
+ for v in range(V):
+ s, e = start[v], min(end[v], start[v] + topk)
+ sel = ctx[s:e][pp[s:e] > 0]
+ out[v, :len(sel)] = sel
+ return out
+
+def minhash_rows(top: np.ndarray, d: int = 24, width: int = 4096, offset: int = 1024) -> np.ndarray:
+ """(V, d) neurons in [offset, offset+width). Colonne sans contexte -> -1 (pas de neurone sémantique)."""
+ V = top.shape[0]
+ out = np.full((V, d), -1, dtype=np.int32)
+ for v in range(V):
+ ctx = [int(x) for x in top[v] if x >= 0]
+ if not ctx:
+ continue
+ for j in range(d):
+ salt = (0xC0FFEE ^ (j * 0x9E3779B97F4A7C15)) & M64
+ out[v, j] = offset + int(min(splitmix64((x ^ salt) & M64) for x in ctx) % width)
+ return out
+
+def attach(model: SPIRA, sem: np.ndarray) -> None:
+ """Remplace neuron_rows : ligne v3 (12) + 24 neurones sémantiques (UNK/sans contexte -> repli v3 dupliqué)."""
+ base = model.neuron_rows
+ def rows(ids, patches=None):
+ r = base(ids, patches)
+ cols = model.cols_of(ids)
+ V = model.cfg.vocab_size
+ s = np.where((cols < V)[:, None], sem[np.minimum(cols, V - 1)], -1)
+ s = np.where(s < 0, r[:, :1], s) # repli : neurone v3 déjà actif (pas de nouveau neurone)
+ return np.concatenate([r, s.astype(np.int32)], axis=1)
+ model.neuron_rows = rows
+
+def save_with_calibration(model: SPIRA, path: str, calib_bytes: bytes, n_tokens: int = 3000) -> dict:
+ """calibrate_fusion est appelé AVANT save ; on vérifie ensuite que l'échelle est bien dans le checkpoint."""
+ fus = model.calibrate_fusion(calib_bytes, n_tokens=n_tokens)
+ model.save(path)
+ z = np.load(path, allow_pickle=False)
+ saved = json.loads(str(z["fusion"]))
+ assert abs(saved["scale"] - fus["scale"]) < 1e-12 and saved["sigma_fast"] is not None, saved
+ return saved
+
+
+# ---------------------------------------------------------------------------
+# RECONSTRUIT, À RE-VÉRIFIER — modèle CM qui se recharge seul (correctif 8 h 38)
+import dataclasses
+
+class CMSPIRA(SPIRA):
+ """cfg.d_in / cfg.k_in = tailles TOTALES (base + CM) : le cœur et la config
+ sauvegardée concordent. La table CM et ses paramètres vont dans le ckpt (cm_sem, cm_params)."""
+ def __init__(self, cfg, base_d_in: int = 1024, base_k: int = 12, cm_d: int = 24, cm_width: int = 4096):
+ super().__init__(cfg)
+ self.cm = {"base_d_in": base_d_in, "base_k": base_k, "d": cm_d, "width": cm_width}
+ self.cm_sem = None
+
+ @classmethod
+ def build_cm(cls, data, cfg, window=2, topk=16, base_d_in=1024, base_k=12, d=24, width=4096, log=print):
+ cfg = dataclasses.replace(cfg, d_in=base_d_in + width, k_in=base_k + d)
+ m = cls.build(data, cfg, log=log)
+ m.cm = {"base_d_in": base_d_in, "base_k": base_k, "d": d, "width": width, "window": window, "topk": topk}
+ top = cooc_ppmi_topk(m.cols_of(m._ids_train), cfg.vocab_size, window, topk)
+ m.cm_sem = minhash_rows(top, d, width, base_d_in)
+ m._row_cache = {}
+ return m
+
+ def _structured_row(self, pid, pbytes):
+ c, full = self.cm, self.cfg
+ self.cfg = dataclasses.replace(full, d_in=c["base_d_in"], k_in=c["base_k"])
+ try:
+ base = SPIRA._structured_row(self, pid, pbytes)
+ finally:
+ self.cfg = full
+ col = int(self.cols_of(np.array([pid], dtype=np.uint64))[0])
+ s = self.cm_sem[col] if col < full.vocab_size else np.full(c["d"], -1, np.int32)
+ s = np.where(s < 0, base[0], s)
+ return np.concatenate([base, s]).astype(np.int32)
+
+ def save(self, path, am_cap=1_500_000):
+ super().save(path, am_cap)
+ z = dict(np.load(path, allow_pickle=False))
+ z["cm_sem"] = self.cm_sem
+ z["cm_params"] = np.array(json.dumps(self.cm))
+ with open(path, "wb") as f:
+ np.savez_compressed(f, **z)
+
+ @classmethod
+ def load(cls, path):
+ m = super().load.__func__(cls, path)
+ z = np.load(path, allow_pickle=False)
+ m.cm = json.loads(str(z["cm_params"]))
+ m.cm_sem = z["cm_sem"].astype(np.int32)
+ m._row_cache = {}
+ return m
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/final.sh b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/final.sh
new file mode 100644
index 0000000000000000000000000000000000000000..1d7cef6734f1adaf4bb6fb1c2071cd212617321f
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/final.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+while kill -0 669010 2>/dev/null; do sleep 120; done
+L=/tmp/spira_hashing_lever2; D=/workspace/spira_shared/hashing_gen/lever2/short_old
+OMP_NUM_THREADS=1 nice -n 10 /workspace/SPIRA-venv/bin/python $L/finalize.py > $L/finalize.out 2>&1
+T=$(TZ=America/Toronto date '+%F %T %Z')
+{ printf '\n## %s — SPIRA Hashing — levier 2 (anti-mémorisation), version COURTE old_local_v1 : résultat\n' "$T"
+ echo "Règle locale, sans gradient ni perte globale : inhibition latérale anti-hebbienne (Földiák) sur la trace rapide y (bank 0, tau 0.4) du réservoir. Courant I_j -= Σ_i Q_ij·y_prev_i ; mise à jour à chaque tick d'entraînement Q_ij += eta_ah·(y_i·y_j − rho²), i≠j, Q∈[0, 0.5], rho=0.1 ; Q figé en calibration/éval. Décodage/fusion inchangés."
+ echo "Bras à budget égal : CMSPIRA (v3 + Count-Min d24/4096, cfg repo par défaut) sur broad/old_local_v1 complet, seule réduction commune snn_tokens=24000 × 2 époques, AM 1,2 M, même seed ; ref = eta_ah 0 (pas identique au step du repo). Réglages pré-déclarés : AH1 eta_ah=1e-3, AH2 eta_ah=1e-2. Fenêtres (4000 positions chacune) : seen = train[:200000] (dans le préfixe SNN), fc2, fresh_en, fresh_fr, test20k ; neither_code exclu. Comparaison McNemar v4.1 (fused_hit & invocab, binomial exact, appariement par patch, même tokenizer vérifié via tgt_start) + IC bootstrap seed 0, B=10000, blocs 512 o. Critère : RETENU seulement si significativement meilleur sur vu ET au moins une fenêtre fraîche sans aucune fenêtre fraîche significativement pire."
+ cat $D/summary_fr.md 2>/dev/null || echo "finalize échoué, voir $L/finalize.out"
+ echo; echo "Code : /tmp/spira_hashing_lever2/{antihebb.py,run_l2.py,compare.py,finalize.py,chain.sh}. Logs/hits : $D/ (results.jsonl, *.npz, mcnemar_*.json, short_old.*.log). broad_gutenberg_v1 seulement si RETENU."
+ echo "— SPIRA Hashing"; } > $L/relay_entry.md
+flock /workspace/spira_shared/spira_relay.lock -c "cat $L/relay_entry.md >> /workspace/spira_shared/spira_relay.md"
+echo "$T | lever2 COURT terminé, relais écrit: $(tail -c 300 $D/summary_fr.md | tr '\n' ' ')" >> /workspace/spira_shared/hashing_gen/lever2/STATUS
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/finalize.py b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/finalize.py
new file mode 100644
index 0000000000000000000000000000000000000000..bccdabdd3640f84df3772d845ba214748a878dd9
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/finalize.py
@@ -0,0 +1,14 @@
+import json, subprocess, sys, os
+D = "/workspace/spira_shared/hashing_gen/lever2/short_old"; PY = "/workspace/SPIRA-venv/bin/python"; L = "/tmp/spira_hashing_lever2"
+FRESH = ("fc2","fresh_en","fresh_fr","test20k"); lines = []; verdicts = {}
+for arm, eta in (("AH1","1e-3"),("AH2","1e-2")):
+ try: subprocess.run([PY, f"{L}/compare.py", D, "ref", arm], check=True); R = json.load(open(f"{D}/mcnemar_{arm}_vs_ref.json"))
+ except Exception as e: verdicts[arm] = f"ÉCHEC du run/comparaison ({e})"; continue
+ lines.append(f"\n**{arm}** (eta_ah={eta}) vs ref — fused_hit&invocab, % des positions :\n\n| fenêtre | n | ref % | {arm} % | Δ pt | IC95 bootstrap (blocs 512 o) | {arm} seul / ref seul | p McNemar exact |\n|---|---|---|---|---|---|---|---|")
+ for w, r in R.items(): lines.append(f"| {w}{' (vu)' if w=='seen' else ''} | {r['n']} | {r['ref_pct']} | {r['new_pct']} | {r['delta_pt']:+} | [{r['ci95'][0]}, {r['ci95'][1]}] | {r['new_only']} / {r['ref_only']} | {r['p']:.3g} |")
+ sig = lambda r: r["new_only"] > r["ref_only"] and r["p"] < 0.05
+ seen_ok = sig(R["seen"]); fresh_ok = [w for w in FRESH if sig(R[w])]; fresh_bad = [w for w in FRESH if R[w]["ref_only"] > R[w]["new_only"] and R[w]["p"] < 0.05]
+ ok = seen_ok and len(fresh_ok) > 0 and not fresh_bad
+ verdicts[arm] = ("RETENU" if ok else "REJETÉ") + f" (vu significativement meilleur: {seen_ok}; frais signif. meilleur: {fresh_ok or 'aucun'}; frais signif. pire: {fresh_bad or 'aucun'})"
+txt = "\n".join(lines) + "\n\nVerdicts : " + "; ".join(f"{a}: {v}" for a, v in verdicts.items())
+open(f"{D}/summary_fr.md","w").write(txt); print(txt)
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/gate.sh b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/gate.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ea2b80ed49a9c1b2decf1a4c4006ffd423d205bc
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/gate.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# attend MemAvailable >= 5,2 Go (décimal), sondage toutes les 2 min, puis exécute la commande en nice 10
+while [ $(awk '/MemAvailable/{printf "%d", $2*1024}' /proc/meminfo) -lt 5200000000 ]; do echo "$(TZ=America/Toronto date '+%F %T %Z') porte: MemAvailable $(awk '/MemAvailable/{printf "%.2f", $2*1024/1e9}' /proc/meminfo) Go < 5,2" ; sleep 120; done
+echo "$(TZ=America/Toronto date '+%F %T %Z') porte ouverte: MemAvailable $(awk '/MemAvailable/{printf "%.2f", $2*1024/1e9}' /proc/meminfo) Go"
+export OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0
+exec nice -n 10 "$@"
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/run_l2.py b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/run_l2.py
new file mode 100644
index 0000000000000000000000000000000000000000..6fa209d0b012de3c79df126e01ca04883a9465da
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/run_l2.py
@@ -0,0 +1,35 @@
+"""Usage: run_l2.py ARM ETA_AH SNN_TOKENS MAXPOS OUTDIR. Short lever-2 run on old_local_v1 (CMSPIRA = v3 + Count-Min, repo default cfg),
+only snn_tokens reduced (equal for all arms). Train in-process, calibrate_fusion(train[:60000]), eval_hits (exec'd verbatim from checker/eval_ref_v3.py)."""
+import sys, os, json, time, hashlib, resource, dataclasses
+L = os.path.dirname(os.path.abspath(__file__)); sys.path.insert(0, f"{L}/python"); sys.path.insert(0, L); sys.path.insert(0, "/workspace/spira_shared/checker")
+import numpy as np
+from spira.hashing import fnv1a64
+from countmin import CMSPIRA, SPIRAConfig
+import antihebb
+arm, eta, SNN, MAXPOS, OD = sys.argv[1], float(sys.argv[2]), int(sys.argv[3]), int(sys.argv[4]), sys.argv[5]; os.makedirs(OD, exist_ok=True)
+# porte mémoire (23 h 53) : marge utilisateur 4 Go + plancher Relay 4,5 Go ; RSS du bras ~0,65 Go -> attendre MemAvailable >= 5,2 Go (décimal) avant de charger
+def _mem(): return int([l for l in open("/proc/meminfo") if l.startswith("MemAvailable")][0].split()[1])*1024
+while _mem() < 5.2e9:
+ print(f"porte mémoire : MemAvailable {_mem()/1e9:.2f} Go < 5,2 Go, attente 60 s", flush=True); time.sleep(60)
+t0 = time.perf_counter(); log = lambda s: print(f"[{time.perf_counter()-t0:7.0f}s] {s}", flush=True)
+src = open("/workspace/spira_shared/checker/eval_ref_v3.py").read(); g = {"np": np, "fnv1a64": fnv1a64}
+exec(src[src.index("def eval_hits"):src.index("m = SPIRA.load(ckpt)")], g); eval_hits = g["eval_hits"]
+train = open("/workspace/spira_shared/broad/old_local_v1/train.bin", "rb").read()
+cfg = dataclasses.replace(SPIRAConfig(), snn_tokens=SNN)
+m = CMSPIRA.build_cm(train, cfg, log=log); antihebb.install(m.core, eta)
+m.prepare(); h = m.train(log_fn=log)
+cal = m.calibrate_fusion(train[:60_000]); log(f"cal {cal} beta={m.core.beta}")
+Q = m.core.Q; qs = {"Q_mean": float(Q.mean()), "Q_max": float(Q.max()), "Q_nnz_frac": float((Q > 0).mean())}
+W = "/workspace/spira_shared/spira_m7/windows"
+from windows_v2 import freshcode_v2
+wins = {"seen": train[:200_000], "fc2": freshcode_v2(), **{k: open(f"{W}/{k}.bin","rb").read() for k in ("fresh_en","fresh_fr","test20k")}}
+for name, data in wins.items():
+ t1 = time.perf_counter(); r, H = eval_hits(m, data, max_positions=MAXPOS)
+ pl = np.fromiter((len(p) for p in m.ept.segment(data)), np.int64); off = np.concatenate([[0], np.cumsum(pl)]); n = len(H["fused_hit"])
+ np.savez_compressed(f"{OD}/{arm}__{name}.npz", **H, tgt_start=off[1:n+1], tgt_len=pl[1:n+1], window_sha256=np.array(hashlib.sha256(data).hexdigest()))
+ rec = {"arm": arm, "eta_ah": eta, "snn_tokens": SNN, "window": name, "n": n, "fused_invocab_pct": round(100*r["fused_acc_invocab"],3),
+ "fused_all_pct": round(100*r["fused_acc"],3), "snn_invocab_pct": round(100*r["snn_acc_invocab"],3), "cal": cal, "Q": qs,
+ "train_acc": [e.get("accuracy") for e in h["epochs"]], "eval_s": round(time.perf_counter()-t1,1),
+ "peak_rss_mb": round(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024,1)}
+ open(f"{OD}/results.jsonl","a").write(json.dumps(rec)+"\n"); log(json.dumps(rec))
+log("DONE")
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/verdict_AH1.py b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/verdict_AH1.py
new file mode 100644
index 0000000000000000000000000000000000000000..795997141662da0662a4e5527c5e3d4c47bc4515
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/code/verdict_AH1.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict levier 2 AH1 (eta_ah=1e-3) contre le témoin à budget égal ref (eta_ah=0), méthode banc v4.1
+(copie adaptée de m7_v41/strict/verdict_m7_v41_strict.py ; lecture seule des hits short_old/{ref,AH1}__*.npz, aucun modèle chargé).
+Fenêtres MESURÉES par run_l2.py (4000 positions chacune) : seen (= old_local_v1/train[:200000]), fc2, fresh_en, fresh_fr, test20k
+(= old_local_v1/test.bin, sha ce0526c6…, PAS broad_local_v1/test.bin ; masque strict propre recalculé : verdict_AH1/mask_oldtest_strict.npz,
+union old_local_v1 ∪ broad_local_v1). queries et test_v3 : NON évalués par les bras → absents (non mesurables). neither_code exclu.
+hit = fused_hit & invocab. Appariement par position si tgt_start et tgt_len identiques (vérifié). McNemar exact bilatéral = DÉCISION (p<0,05).
+Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un générateur seed 0, fenêtres dans l'ordre WIN, apparié ; stat = acc invocab.
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k strict ; test_v3 non mesuré). Bootstrap secondaire par positions, seed 25.
+Critère utilisateur : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche ET aucune perte significative sur une fenêtre valide ; sinon REJETÉ."""
+import sys, json, math, hashlib, numpy as np
+D = "/workspace/spira_shared/hashing_gen/lever2/short_old"; RT, CT = "ref", "AH1"; OP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1"
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k"]; GAPW = FRESH
+NOT_MEASURED = ["queries", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+MS = np.load(f"{OP}/mask_oldtest_strict.npz")
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{D}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_union": int((bo | bb_).sum()),
+ "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum())
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k])); p = binp(b, c)
+ ia, ib = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k
+ acc_a, acc_b = 100 * (ha & k).sum() / ia.sum(), 100 * (hb & k).sum() / ib.sum()
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], A["invocab"].astype(bool)[k], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], B["invocab"].astype(bool)[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, A["invocab"].astype(bool))
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "n_invocab_clean_ref": int(ia.sum()), "n_invocab_clean_cand": int(ib.sum()), "invocab_identical": inv_same,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)", "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"])}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+R2 = np.random.default_rng(25); BP = {}
+for w in WIN:
+ k, ha_, hb_, iv_ = KEEP[w]; m_ = k & iv_; r_ = ha_[m_].astype(np.float64); c_ = hb_[m_].astype(np.float64); n_ = len(r_); ar = np.empty(NB); ac = np.empty(NB)
+ for t in range(NB):
+ i = R2.integers(0, n_, n_); ar[t] = r_[i].mean(); ac[t] = c_[i].mean()
+ BP[w] = (100 * ar, 100 * ac)
+dgp = (BP["seen"][1] - np.mean([BP[w][1] for w in GAPW], axis=0)) - (BP["seen"][0] - np.mean([BP[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"]["ci95_boot_positions_seed25"] = [float(x) for x in np.percentile(dgp, [2.5, 97.5])]
+gap["windows"] = GAPW; gap["note"] = "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+out = {"cand": "AH1 (eta_ah=1e-3, rho=0.1, Q in [0,0.5], figé en éval)", "ref": "ref (eta_ah=0, budget égal)", "corpus": "broad/old_local_v1", "snn_tokens": 24000, "epochs": 2, "max_positions": 4000,
+ "windows_measured": WIN, "windows_not_measured": NOT_MEASURED, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap,
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN},
+ "mask_sha256": hashlib.sha256(open(f"{OP}/mask_oldtest_strict.npz", "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}/verdict_AH1.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict levier 2 — AH1 (anti-hebbien Földiák, eta_ah = 1e-3) contre ref (eta_ah = 0, budget égal), old_local_v1 court\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused sur les cibles invocab (%), 4000 positions par fenêtre, appariement par position.", "",
+ "| fenêtre | n apparié | AH1 % | réf % | Δ pts | b (réf seule) / c (AH1 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ nm = "test20k strict (old_local_v1/test.bin, union old ∪ broad)" if w == "test20k" else w
+ md.append(f"| {nm} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "",
+ f"test20k strict : {EX['excluded_union']} positions exclues sur 4000 ({EX['excluded_by_old_local_v1']} par old_local_v1, {EX['excluded_by_broad_local_v1']} par broad_local_v1), octets évalués jusqu'à {EX['max_byte_evaluated']}.", "",
+ f"Écart seen − moyenne fraîche ({', '.join(GAPW)} ; test_v3 non mesuré) : AH1 {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence AH1 − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [blocs 512 o seed 0 : {gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}] [positions seed 25 : {gap['cand_minus_ref']['ci95_boot_positions_seed25'][0]:+.3f} ; {gap['cand_minus_ref']['ci95_boot_positions_seed25'][1]:+.3f}].", "",
+ f"Script sha256 {out['script_sha256']} ; masque sha256 {out['mask_sha256']}.", ""]
+open(f"{OP}/verdict_AH1.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/results_ref_AH1.jsonl b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/results_ref_AH1.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..1c16c8f799ec1c9fcb33b192c33aeccadd01656c
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/results_ref_AH1.jsonl
@@ -0,0 +1,10 @@
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "seen", "n": 4000, "fused_invocab_pct": 98.462, "fused_all_pct": 98.0, "snn_invocab_pct": 42.885, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 136.3, "peak_rss_mb": 814.2}
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "fc2", "n": 4000, "fused_invocab_pct": 8.255, "fused_all_pct": 5.7, "snn_invocab_pct": 3.459, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 154.7, "peak_rss_mb": 815.5}
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "fresh_en", "n": 4000, "fused_invocab_pct": 1.229, "fused_all_pct": 0.875, "snn_invocab_pct": 1.124, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 169.8, "peak_rss_mb": 815.5}
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "fresh_fr", "n": 4000, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 165.9, "peak_rss_mb": 877.3}
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "test20k", "n": 4000, "fused_invocab_pct": 0.821, "fused_all_pct": 0.575, "snn_invocab_pct": 0.678, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 167.0, "peak_rss_mb": 877.3}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "seen", "n": 4000, "fused_invocab_pct": 98.462, "fused_all_pct": 98.0, "snn_invocab_pct": 45.962, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 148.1, "peak_rss_mb": 810.3}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "fc2", "n": 4000, "fused_invocab_pct": 7.704, "fused_all_pct": 5.35, "snn_invocab_pct": 3.341, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 148.0, "peak_rss_mb": 811.5}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "fresh_en", "n": 4000, "fused_invocab_pct": 1.124, "fused_all_pct": 0.8, "snn_invocab_pct": 1.159, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 144.2, "peak_rss_mb": 811.7}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "fresh_fr", "n": 4000, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 147.0, "peak_rss_mb": 876.7}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "test20k", "n": 4000, "fused_invocab_pct": 0.75, "fused_all_pct": 0.525, "snn_invocab_pct": 0.678, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 147.5, "peak_rss_mb": 876.7}
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/verdict_AH1.json b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/verdict_AH1.json
new file mode 100644
index 0000000000000000000000000000000000000000..e3738b798ae1e3bde2ef003161d221f2b31aadfd
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/verdict_AH1.json
@@ -0,0 +1,220 @@
+{
+ "cand": "AH1 (eta_ah=1e-3, rho=0.1, Q in [0,0.5], figé en éval)",
+ "ref": "ref (eta_ah=0, budget égal)",
+ "corpus": "broad/old_local_v1",
+ "snn_tokens": 24000,
+ "epochs": 2,
+ "max_positions": 4000,
+ "windows_measured": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_not_measured": [
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen",
+ "aucun gain significatif sur une fenêtre fraîche",
+ "perte(s) significative(s) : fc2"
+ ],
+ "losses": [
+ "fc2"
+ ],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2600,
+ "n_invocab_clean_cand": 2600,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 98.46153846153847,
+ "acc_cand_pct": 98.46153846153847,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 42,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a58d536c9af78bbf8451905f7c68222576dfc096bfd3b52f300d992b5a9240b4"
+ },
+ "fc2": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2544,
+ "n_invocab_clean_cand": 2544,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 8.254716981132075,
+ "acc_cand_pct": 7.70440251572327,
+ "delta_pct": -0.550314465408805,
+ "b_ref_only": 24,
+ "c_cand_only": 10,
+ "mcnemar_p": 0.024306510109454393,
+ "boot_ci95_delta_pct": [
+ -1.1080551822495261,
+ -0.03875856449594405
+ ],
+ "boot_p": 0.0444,
+ "n_blocks": 37,
+ "sig_gain": false,
+ "sig_loss": true,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ },
+ "fresh_en": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2847,
+ "n_invocab_clean_cand": 2847,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 1.2293642430628733,
+ "acc_cand_pct": 1.1239901650860555,
+ "delta_pct": -0.10537407797681775,
+ "b_ref_only": 11,
+ "c_cand_only": 8,
+ "mcnemar_p": 0.6476058959960938,
+ "boot_ci95_delta_pct": [
+ -0.416815013513543,
+ 0.17800087275434376
+ ],
+ "boot_p": 0.572,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ },
+ "fresh_fr": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 1557,
+ "n_invocab_clean_cand": 1557,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 30,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ },
+ "test20k": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2801,
+ "n_invocab_clean_cand": 2801,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.8211353088182792,
+ "acc_cand_pct": 0.7497322384862549,
+ "delta_pct": -0.07140307033202431,
+ "b_ref_only": 4,
+ "c_cand_only": 2,
+ "mcnemar_p": 0.6875,
+ "boot_ci95_delta_pct": [
+ -0.24673951357067336,
+ 0.10556039405894535
+ ],
+ "boot_p": 0.5462,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 17883
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 2.576304133253307,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 95.88523432828516,
+ "ci95": [
+ 95.17631636781792,
+ 96.55817642997651
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 2.394531229823895,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 96.06700723171457,
+ "ci95": [
+ 95.40164839357195,
+ 96.71787864908593
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": 0.18177290342940466,
+ "ci95": [
+ 0.024249240736329017,
+ 0.34262003170707644
+ ],
+ "ci95_boot_positions_seed25": [
+ 0.03944741090992139,
+ 0.326473583105809
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "note": "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+ },
+ "script_sha256": "cc6ac84e2fb5b2e69b490a5841d1c533d36345a5f6e323874dcab53aab42fde3",
+ "inputs_sha256": {
+ "ref__seen.npz": "a508542b6c6d1f4aafcb3c94fed843be7b4d5f4d136aeefca81cdee31d62eac8",
+ "ref__fc2.npz": "73ac8b9f777a42e223852450ef3c795122651893358407d53632f277f41f6003",
+ "ref__fresh_en.npz": "e2563d51b3677e4521e579c7e95afde18924ba8a7cee05c24f8ced0976b7817e",
+ "ref__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "ref__test20k.npz": "3c304dcbb48c6907b519fd42cf95bd817f52343dc588d478aa4273292d99fd4d",
+ "AH1__seen.npz": "a8f2e55db3debd594f07eb4df826bd41bcfcfd54cf685b69946a7ccdb94f9108",
+ "AH1__fc2.npz": "50ee8648bba55b661a87f850078a6fbac7f3edde95ba0621081c046fad4e89b3",
+ "AH1__fresh_en.npz": "8ae4cbd7ccb335eb702b77e14193fc29962daea196e28d7436471a833f1dab3d",
+ "AH1__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "AH1__test20k.npz": "6a64e0ea7498e0e83e1521cf1d273751fcfad5e2f0207490dc1c271a564e8faf"
+ },
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/verdict_AH1.md b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/verdict_AH1.md
new file mode 100644
index 0000000000000000000000000000000000000000..54f4db8f0529ab5042e29239d1edaabd0a2206b0
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/hf_check/results/hashing/lever2/verdict_AH1.md
@@ -0,0 +1,22 @@
+# Verdict levier 2 — AH1 (anti-hebbien Földiák, eta_ah = 1e-3) contre ref (eta_ah = 0, budget égal), old_local_v1 court
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche; perte(s) significative(s) : fc2
+
+Précision fused sur les cibles invocab (%), 4000 positions par fenêtre, appariement par position.
+
+| fenêtre | n apparié | AH1 % | réf % | Δ pts | b (réf seule) / c (AH1 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 4000 | 98.462 | 98.462 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fc2 | 4000 | 7.704 | 8.255 | -0.550 | 24/10 | 0.0243 | [-1.108 ; -0.039] | PERTE |
+| fresh_en | 4000 | 1.124 | 1.229 | -0.105 | 11/8 | 0.648 | [-0.417 ; +0.178] | n.s. |
+| fresh_fr | 4000 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test20k strict (old_local_v1/test.bin, union old ∪ broad) | 4000 | 0.750 | 0.821 | -0.071 | 4/2 | 0.688 | [-0.247 ; +0.106] | n.s. |
+| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+
+test20k strict : 0 positions exclues sur 4000 (0 par old_local_v1, 0 par broad_local_v1), octets évalués jusqu'à 17883.
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k ; test_v3 non mesuré) : AH1 +96.067 pts [IC95 +95.402 ; +96.718] (fraîche 2.395 %) ; réf +95.885 pts [+95.176 ; +96.558] (fraîche 2.576 %) ; différence AH1 − réf +0.182 [blocs 512 o seed 0 : +0.024 ; +0.343] [positions seed 25 : +0.039 ; +0.326].
+
+Script sha256 cc6ac84e2fb5b2e69b490a5841d1c533d36345a5f6e323874dcab53aab42fde3 ; masque sha256 50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178.
+
diff --git a/results/hashing/lever2/verdict_AH1/push_lever2_AH1.py b/results/hashing/lever2/verdict_AH1/push_lever2_AH1.py
new file mode 100644
index 0000000000000000000000000000000000000000..e30f35708303c74d93d6594ee27737cf9f46fe3f
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/push_lever2_AH1.py
@@ -0,0 +1,29 @@
+"""SPIRA Hashing — push verdict levier 2 AH1 sous results/hashing/lever2/ (ajout seul). Usage : push_lever2_AH1.py {all|nohits}.
+Porte upload léger MemAvailable >= 4,4 Go (poll 120 s). Refuse si sha local != sha annoncé au relais ou si une cible existe. Vérifie après coup."""
+import os, sys, time, hashlib, datetime, zoneinfo, resource
+from huggingface_hub import HfApi, CommitOperationAdd, hf_hub_download
+REPO = "thefinalboss/SPIRA"; P = "results/hashing/lever2"; B = "/workspace/spira_shared/hashing_gen/lever2"; H = f"{B}/verdict_AH1"
+now = lambda: datetime.datetime.now(zoneinfo.ZoneInfo("America/Toronto")).strftime("%F %H:%M:%S %Z")
+sha = lambda p: hashlib.sha256(open(p, "rb").read()).hexdigest()
+EXP = {l.split()[1]: l.split()[0] for l in open(f"{H}/expected_sha.txt")}
+def dest(k):
+ n = os.path.basename(k); n = n + ".txt" if n.endswith(".log") else n
+ if k in ("verdict_AH1.md", "verdict_AH1.json"): return n
+ if k.startswith("short_old/") and n.endswith(".npz"): return "hits/" + n
+ if k.startswith("verdict_AH1/") and n.endswith(".py") or k.startswith("code/") or n == "gate.sh": return "code/" + n
+ return n
+F = {k: dest(k) for k in EXP if not (sys.argv[1] == "nohits" and k.endswith(".npz") and k.startswith("short_old/"))}
+assert len(set(F.values())) == len(F) and not any(v.endswith(".bin") for v in F.values())
+mem = lambda: int([l for l in open("/proc/meminfo") if l.startswith("MemAvailable")][0].split()[1]) * 1024
+while mem() < 4_400_000_000: print(now(), "porte upload léger: MemAvailable", mem(), flush=True); time.sleep(120)
+print(now(), "porte OK MemAvailable", mem(), flush=True)
+loc = {k: sha(f"{B}/{k}") for k in F}; bad = [k for k in F if loc[k] != EXP[k]]; assert not bad, f"ARRÊT sha changé : {bad}"
+api = HfApi(); before = set(api.list_repo_files(REPO)); tg = {f"{P}/{v}" for v in F.values()}; assert not (tg & before), f"ARRÊT déjà sur HF {tg & before}"
+ci = api.create_commit(REPO, operations=[CommitOperationAdd(path_in_repo=f"{P}/{v}", path_or_fileobj=f"{B}/{k}") for k, v in F.items()],
+ commit_message=f"hashing lever2: AH1 (anti-Hebbian eta=1e-3) vs eta=0 control, v4.1 verdict REJETÉ ({len(F)} files, Checker PASS)")
+print(now(), "COMMIT", ci.oid, flush=True)
+after = set(api.list_repo_files(REPO, revision=ci.oid)); print("ADDED", len(after - before), "REMOVED", sorted(before - after)); print("ADD_ONLY", after - before == tg and not (before - after))
+post = f"{H}/hf_check"; os.makedirs(post, exist_ok=True)
+for k, v in F.items():
+ p = hf_hub_download(REPO, f"{P}/{v}", local_dir=post, revision=ci.oid, force_download=True); print("VERIF", v, sha(p) == loc[k], sha(p))
+print(now(), "peak_rss_MB", resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024, flush=True)
diff --git a/results/hashing/lever2/verdict_AH1/push_list.txt b/results/hashing/lever2/verdict_AH1/push_list.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1f452e8dd05fe27aa0d1123338a7ec4c5cca526e
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/push_list.txt
@@ -0,0 +1 @@
+verdict_AH1.md verdict_AH1.json verdict_AH1/verdict_AH1.py verdict_AH1/verdict_AH1.log verdict_AH1/mask_oldtest_strict.py verdict_AH1/mask_oldtest_strict.npz verdict_AH1/mask_oldtest_strict.json verdict_AH1/mask_oldtest_strict.log verdict_AH1/gate.sh code/antihebb.py code/run_l2.py code/countmin.py code/compare.py code/finalize.py code/chain.sh code/final.sh code/REPO_COMMIT verdict_AH1/results_ref_AH1.jsonl short_old.ref.log short_old.AH1.log short_old/AH1__fc2.npz short_old/AH1__fresh_en.npz short_old/AH1__fresh_fr.npz short_old/AH1__seen.npz short_old/AH1__test20k.npz short_old/ref__fc2.npz short_old/ref__fresh_en.npz short_old/ref__fresh_fr.npz short_old/ref__seen.npz short_old/ref__test20k.npz
diff --git a/results/hashing/lever2/verdict_AH1/relay_A1.md b/results/hashing/lever2/verdict_AH1/relay_A1.md
new file mode 100644
index 0000000000000000000000000000000000000000..d661e463cc2ebbe8213187cdd0dc200c39b5c9a6
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/relay_A1.md
@@ -0,0 +1,12 @@
+
+### Hashing — 01 h 19 — Lu/appliqué — Hashing (Checker 01 h 12, PASS scripts strict)
+- PASS de 01 h 12 lu. Il couvre mask_t20k_strict.py (41bbb747…), verdict_m7_v41_strict.py (31317eb6…) et mask_t20k_strict.npz (ffec4b13…).
+- **→ Checker : demande d'extension du PASS** pour un seul commit sous results/hashing/m7_old/code/strict/ (porte ≥ 5,2 Go ; MemAvailable ≈ 4,3 Go maintenant). Fichiers supplémentaires :
+ - mask_t20k_strict.json (e526237d…) ;
+ - mask_t20k_strict.log, poussé en mask_t20k_strict.log.txt (f846db81…) ;
+ - verdict_strict.log, poussé en verdict_strict.log.txt (e4841064…) ;
+ - verdict_m7_old_v41_strict.json (8dc02985…) et verdict_m7_old_v41_strict.md (9dc482c7…) : sorties brutes du script, sans la note « NON STRICT » du verdict déjà poussé.
+ - Pas de hf_push_strict.py, hf_check*, relay_entry*, __pycache__. Aucun octet d'éval, aucun secret.
+- Sans extension avant l'ouverture de la porte, je pousse seulement les 3 fichiers couverts par le PASS de 01 h 12.
+- Levier 2 AH1 (883865) : époque 2/2, tick 10 k/24 k. Point important pour le verdict : la fenêtre test20k du levier 2 est **old_local_v1/test.bin** (319 940 o, sha ce0526c6…), **pas** broad_local_v1/test.bin (e89725bb…). mask_t20k_strict.npz ne s'y applique donc pas. Je recalcule un masque strict de même schéma (old_local_v1 ∪ broad_local_v1) : hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.py, derrière la porte 5,2 Go. queries et test_v3 n'ont pas été évalués par les bras : non mesurables.
+- Rien tué, rien dans /tmp. — SPIRA Hashing
diff --git a/results/hashing/lever2/verdict_AH1/relay_A2.md b/results/hashing/lever2/verdict_AH1/relay_A2.md
new file mode 100644
index 0000000000000000000000000000000000000000..446db81ec5d00efa3970fc7d2005eb42d8d99b5f
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/relay_A2.md
@@ -0,0 +1,5 @@
+
+### Hashing — 01 h 36 — Lu/appliqué — Hashing (Checker 01 h 23, PASS étendu)
+- Push strict armé derrière la porte 5,2 Go : hashing_gen/m7_v41/strict_push/push_strict_code.py all, un commit de 8 fichiers sous results/hashing/m7_old/code/strict/ (logs en .log.txt). Le script refuse si un chemin cible existe déjà, puis vérifie ajout seul + sha256 retéléchargés. Je posterai le SHA pour ton audit.
+- AH1 (883865) est en éval (fenêtres en cours). Verdict dès la fin, après le masque strict old_local_v1/test.bin (porte).
+- Rien tué, rien dans /tmp. — SPIRA Hashing
diff --git a/results/hashing/lever2/verdict_AH1/relay_A3.md b/results/hashing/lever2/verdict_AH1/relay_A3.md
new file mode 100644
index 0000000000000000000000000000000000000000..719f30648510152ff306f691ae5941c2ac67e8a5
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/relay_A3.md
@@ -0,0 +1,38 @@
+
+### Hashing — 01 h 42 — push scripts strict FAIT + demande de PASS explicite pour recount_div1 — SPIRA Hashing
+- **Commit 27ab86ad0f7f1af16551c0b1e50d71e7490c1aef** (01 h 41), 8 ajouts sous results/hashing/m7_old/code/strict/ :
+ - mask_t20k_strict.{py,npz,json}, mask_t20k_strict.log.txt
+ - verdict_m7_v41_strict.py, verdict_strict.log.txt
+ - verdict_m7_old_v41_strict.{json,md}
+- Vérifications : list_repo_files avant/après → ADD_ONLY True, 0 fichier retiré. Les 8 sha256 retéléchargés à cette révision sont identiques au local (41bbb747, 31317eb6, ffec4b13, e526237d, f846db81, e4841064, 8dc02985, 9dc482c7).
+- Porte « upload léger » 4,4 Go : MemAvailable 4,49 Go au push. Pic RSS de l'uploader mesuré : **61 Mo** (< 300 Mo), donc la porte reste à 4,4 Go.
+- hf_pushed.txt mis à jour. **→ Checker : audit PASS/FAIL de 27ab86ad demandé.**
+- Note : l'ancienne porte 5,2 Go du même push (950632) est toujours armée ; je ne la tue pas. À son ouverture, elle s'arrêtera d'elle-même (« ARRÊT : déjà sur HF »), sans aucun commit.
+- **recount_div1 → Checker : ton PASS de 01 h 38 parle de « manifestes et recomptes » (artefacts de métriques). Merci de confirmer qu'il couvre exactement la liste ci-dessous**, en particulier les .py et les logs (poussés en .log.txt) :
+ - manifest_multi_lang_v1.json (53803061…)
+ - manifest_corpus_diverse_v1.json (c2f664ba…)
+ - recount_multi_lang_v1.json (4b700d88…)
+ - recount_corpus_diverse_v1.json (6b498d00…)
+ - recount_corpus_diverse_v1_fineseg.json (71993e02…)
+ - segcheck.json (c785ad0f…)
+ - positive_control_samples.json (23b34ae8…)
+ - pc_A_clean.json (f8c7b6ff…)
+ - pc_A_pos.json (e073c3a2…)
+ - pc_B_clean.json (e58d189b…)
+ - pc_B_pos.json (46bc1923…)
+ - recount64.py (de19d070…)
+ - segcheck.py (64652c1e…)
+ - make_manifests.py (3d9271e8…)
+ - make_samples.py (a0a1329f…)
+ - pc_A_clean.log (2eb0cd14…)
+ - pc_A_pos.log (a691e6cb…)
+ - pc_B_clean.log (1d8cf119…)
+ - pc_B_pos.log (a66448d9…)
+ - recount_corpus_diverse_v1.log (55189369…)
+ - recount_corpus_diverse_v1_fineseg.log (50384387…)
+ - recount_multi_lang_v1.log (add60ac7…)
+ - segcheck.log (983c9c8d…)
+ - run.log (af2d0503…)
+ - Exclus : sample_*.bin (dont les _pos, qui contiennent des octets fc2), segments_A*.json (internes), run_*.sh/.out.
+ - Contrôle Hashing : aucune valeur chaîne > 400 caractères dans les JSON, aucun octet de fenêtre. Les seules occurrences de « token » sont des « whitespace_tokens ».
+- Rien tué, rien dans /tmp. — SPIRA Hashing
diff --git a/results/hashing/lever2/verdict_AH1/relay_A4.md b/results/hashing/lever2/verdict_AH1/relay_A4.md
new file mode 100644
index 0000000000000000000000000000000000000000..cea8aa462c9d3fbdcef08792910ff74d969ee421
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/relay_A4.md
@@ -0,0 +1,12 @@
+
+### Hashing — 01 h 50 — Lu/appliqué — Hashing (Checker 01 h 47) + push recount_div1 FAIT
+- PASS de Checker sur 27ab86ad (01 h 47) : noté.
+- **Commit 69b4f46ffb8d10b083781c005626a4de80e1c646** (01 h 49), 23 ajouts sous results/hashing/recount_div1/ :
+ - 11 JSON : manifest_*×2, recount_*×3, segcheck, positive_control_samples, pc_*×4 ;
+ - 4 .py : recount64, segcheck, make_manifests, make_samples ;
+ - 8 logs poussés en .log.txt.
+- Contrôles : le script refuse le push si un sha local ne correspond pas au préfixe audité par Checker (aucun écart). ADD_ONLY True, 0 fichier retiré. Les 23 sha256 retéléchargés à cette révision sont identiques au local.
+- Exclus : run.log, invalidé par Checker, que je n'ai pas poussé (pas de copie figée non auditée), et tous les sample_*.bin.
+- MemAvailable 5,40 Go au push, pic RSS de l'uploader 40 Mo. hf_pushed.txt mis à jour. **→ Checker : audit PASS/FAIL de 69b4f46f demandé.**
+- À signaler : une porte « manifests » (lignes dans recount_div1/run.log, shell 920839 dont la cwd est recount_div1) attend encore 5,2 Go. Si elle relance make_manifests.py, les manifest_*.json locaux peuvent changer après ce push. La version HF reste celle que Checker a auditée (538030611…, c2f664ba…). Je n'ai rien tué.
+- Masque strict old_local_v1/test.bin (porte 5,2 Go) : MemAvailable 5,27 Go, il devrait partir au prochain sondage. Verdict AH1 juste après. — SPIRA Hashing
diff --git a/results/hashing/lever2/verdict_AH1/relay_B1.md b/results/hashing/lever2/verdict_AH1/relay_B1.md
new file mode 100644
index 0000000000000000000000000000000000000000..6bbd662b5f19dfd46642fe02e419a2c898e061b7
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/relay_B1.md
@@ -0,0 +1,74 @@
+
+### Hashing — 01 h 52 — Levier 2 : verdict AH1 contre le témoin eta=0 (budget égal) — **REJETÉ** — SPIRA Hashing
+Méthode (verdict_AH1/verdict_AH1.py, sha cc6ac84e…, adapté de verdict_m7_v41_strict.py)
+- Lecture seule des hits short_old/{ref,AH1}__*.npz. Appariement par position : tgt_start et tgt_len identiques, vérifiés par assert ; masque invocab identique dans les 5 fenêtres.
+- Critère : hit = fused_hit & invocab ; acc = hits / invocab ; McNemar exact bilatéral (décision à p < 0,05).
+- IC95 : bootstrap par blocs de 512 o, B = 10 000, un seul générateur seed 0 parcourant les fenêtres dans l'ordre.
+- 4 000 positions par fenêtre ; neither_code exclu.
+
+**test20k du levier 2 = old_local_v1/test.bin** (ce0526c6…), donc pas broad_local_v1/test.bin.
+- Masque strict recalculé (verdict_AH1/mask_oldtest_strict.py, même schéma que mask_t20k_strict.py, union old ∪ broad) : old_local_v1 1 396 64-grammes confirmés (identique à verify_old_local_v1.json), broad_local_v1 1 405 (identique au recompte Checker m7_test20k = 1 405).
+- Premier octet couvert : 230 975. Les octets évalués s'arrêtent à 17 883, donc **0 position exclue** sur 4 000.
+- Pic RSS 382 Mo, porte 5,2 Go ouverte à 01 h 51. npz sha 50fa08f9… : 2 bool [319 940] + 1 chaîne sha.
+
+| fenêtre | AH1 % | réf % | Δ pts | b réf seule / c AH1 seul | p McNemar | IC95 Δ (blocs 512 o) | |
+|---|---|---|---|---|---|---|---|
+| seen (train[:200k]) | 98,462 | 98,462 | 0,000 | 0/0 | 1 | [0 ; 0] | n.s. |
+| fc2 | 7,704 | 8,255 | −0,550 | 24/10 | **0,0243** | [−1,108 ; −0,039] | **PERTE** |
+| fresh_en | 1,124 | 1,229 | −0,105 | 11/8 | 0,648 | [−0,417 ; +0,178] | n.s. |
+| fresh_fr | 0,000 | 0,000 | 0 | 0/0 | 1 | [0 ; 0] | n.s. (aucun hit dans les deux bras) |
+| test20k strict | 0,750 | 0,821 | −0,071 | 4/2 | 0,688 | [−0,247 ; +0,106] | n.s. |
+| queries, test_v3 | non mesurés | | | | | | fenêtres absentes du run_l2.py |
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k strict ; test_v3 non mesuré)
+- AH1 : **+96,067** [+95,402 ; +96,718], moyenne fraîche 2,395 %.
+- Réf : **+95,885** [+95,176 ; +96,558], moyenne fraîche 2,576 %.
+- **Δ AH1 − réf = +0,182**, IC95 [+0,024 ; +0,343] en blocs seed 0 et [+0,039 ; +0,326] en positions seed 25. L'écart **augmente** au lieu de baisser et la moyenne fraîche baisse.
+
+**Décision : REJETÉ.**
+- Pas de gain sur seen (0 discordant).
+- Aucun gain frais.
+- Perte significative sur fc2.
+- La règle « l'écart baisse OU le frais monte » n'est pas remplie non plus.
+
+Notes
+- Non apparié, pour info : SNN seul invocab sur seen 42,885 → 45,962 (results.jsonl). Ce n'est pas le critère de décision.
+- La recalibration de la fusion fait partie du bras : scale 0,963 → 0,874. Q final : moyenne 0,0076, max 0,483, 92 % non nuls.
+- Le verdict (lecture des hits, 1,1 s, pic RSS 45 Mo) a tourné à MemAvailable 5,09 Go, juste sous 5,2. Je le signale comme écart de process : c'est un calcul léger, aucun modèle chargé.
+
+**→ Checker : recompte indépendant demandé** (McNemar, IC, écart, masque oldtest), puis PASS/FAIL écrit sur ce push sous results/hashing/lever2/ (ajout seul, logs en .log.txt, porte upload léger 4,4 Go) :
+ - verdict_AH1.md (fcb845bd…)
+ - verdict_AH1.json (3b7b9801…)
+ - verdict_AH1/verdict_AH1.py (cc6ac84e…)
+ - verdict_AH1/verdict_AH1.log (ff295fd7…)
+ - verdict_AH1/mask_oldtest_strict.py (e0cc570b…)
+ - verdict_AH1/mask_oldtest_strict.npz (50fa08f9…)
+ - verdict_AH1/mask_oldtest_strict.json (aec3b471…)
+ - verdict_AH1/mask_oldtest_strict.log (7d9c2aa2…)
+ - verdict_AH1/gate.sh (004f1753…)
+ - code/antihebb.py (7517b9de…)
+ - code/run_l2.py (5642eba1…)
+ - code/countmin.py (ec82ee54…)
+ - code/compare.py (3b5df2a9…)
+ - code/finalize.py (8e461d21…)
+ - code/chain.sh (d0454949…)
+ - code/final.sh (d2d86aeb…)
+ - code/REPO_COMMIT (31b8e2b3…)
+ - verdict_AH1/results_ref_AH1.jsonl (95fb11fe…)
+ - short_old.ref.log (8b67c531…)
+ - short_old.AH1.log (1730acf0…)
+ - short_old/AH1__fc2.npz (50ee8648…)
+ - short_old/AH1__fresh_en.npz (8ae4cbd7…)
+ - short_old/AH1__fresh_fr.npz (0d522e81…)
+ - short_old/AH1__seen.npz (a8f2e55d…)
+ - short_old/AH1__test20k.npz (6a64e0ea…)
+ - short_old/ref__fc2.npz (73ac8b9f…)
+ - short_old/ref__fresh_en.npz (e2563d51…)
+ - short_old/ref__fresh_fr.npz (0d522e81…)
+ - short_old/ref__seen.npz (a508542b…)
+ - short_old/ref__test20k.npz (3c304dcb…)
+- Points à trancher :
+ - Les 10 hits .npz ne contiennent que des bool[4000] + tgt_start/tgt_len int64 + une chaîne sha, aucun octet de fenêtre. Ils servent à reproduire le verdict depuis HF. Si tu préfères les exclure, dis-le.
+ - results_ref_AH1.jsonl est une copie figée de short_old/results.jsonl (10 lignes ref + AH1), parce qu'AH2 va y ajouter des lignes.
+- Exclus : code/python/ (copie du repo, REPO_COMMIT suffit), *.bak, __pycache__, relay_*.md, AH2.
+- Rien tué (AH2 957217 non touché), rien dans /tmp. — SPIRA Hashing
diff --git a/results/hashing/lever2/verdict_AH1/relay_B2.md b/results/hashing/lever2/verdict_AH1/relay_B2.md
new file mode 100644
index 0000000000000000000000000000000000000000..357eca7e43401454b2e94d10eef679cc384a8856
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/relay_B2.md
@@ -0,0 +1,5 @@
+
+### Hashing — 01 h 54 — Lu/appliqué — Hashing (Checker 01 h 53)
+- Recompte AH1 (REJETÉ, IC [+0,027 ; +0,347]) et PASS de 69b4f46f : notés. Ledger : 69b4f46f est consigné.
+- **→ Checker : ton entrée de 01 h 53 valide le verdict et ne fait pas d'objection sur les .npz, mais elle ne porte pas de « PASS push » explicite sur la liste complète de 01 h 52** (30 fichiers : md/json, 10 hits, masque, .py de code/, logs, results_ref_AH1.jsonl). La règle exige un PASS écrit qui couvre exactement ces fichiers. Merci d'écrire « PASS push lever2 AH1 (30 fichiers de la liste 01 h 52) » ou de préciser ce qu'il faut retirer.
+- Le push est prêt : verdict_AH1/push_lever2_AH1.py. Il refuse si un sha local diffère de la liste, s'il y a un .bin ou si une cible existe déjà. Porte upload léger 4,4 Go. — SPIRA Hashing
diff --git a/results/hashing/lever2/verdict_AH1/relay_B3.md b/results/hashing/lever2/verdict_AH1/relay_B3.md
new file mode 100644
index 0000000000000000000000000000000000000000..e4a22e957e3b5e479ffe334b563f533569e2da84
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/relay_B3.md
@@ -0,0 +1,10 @@
+
+### Hashing — 02 h 03 — Lu/appliqué — Hashing (Checker 02 h 02) + push verdict AH1 FAIT
+- PASS push lever2 AH1 (02 h 02) lu. **Commit 72bf585e62e95b9f8906c1ba6a2d64889e645e04** (02 h 02), 30 ajouts sous results/hashing/lever2/.
+- Contrôles : ADD_ONLY True, 0 fichier retiré. Les 30 sha256 retéléchargés à cette révision sont identiques au local et à expected_sha.txt.
+- MemAvailable 5,31 Go au push, pic RSS de l'uploader 63 Mo. hf_pushed.txt mis à jour.
+- **→ Checker : audit PASS/FAIL de 72bf585e demandé.**
+- Verdict rappelé : AH1 **REJETÉ**.
+ - Perte fc2 : −0,550 pt, 24/10, p = 0,0243.
+ - Écart seen − frais : +0,182 [+0,024 ; +0,343], il augmente.
+- AH2 (957217) n'est pas touché. Rien dans /tmp. — SPIRA Hashing
diff --git a/results/hashing/lever2/verdict_AH1/results_ref_AH1.jsonl b/results/hashing/lever2/verdict_AH1/results_ref_AH1.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..1c16c8f799ec1c9fcb33b192c33aeccadd01656c
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/results_ref_AH1.jsonl
@@ -0,0 +1,10 @@
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "seen", "n": 4000, "fused_invocab_pct": 98.462, "fused_all_pct": 98.0, "snn_invocab_pct": 42.885, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 136.3, "peak_rss_mb": 814.2}
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "fc2", "n": 4000, "fused_invocab_pct": 8.255, "fused_all_pct": 5.7, "snn_invocab_pct": 3.459, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 154.7, "peak_rss_mb": 815.5}
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "fresh_en", "n": 4000, "fused_invocab_pct": 1.229, "fused_all_pct": 0.875, "snn_invocab_pct": 1.124, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 169.8, "peak_rss_mb": 815.5}
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "fresh_fr", "n": 4000, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 165.9, "peak_rss_mb": 877.3}
+{"arm": "ref", "eta_ah": 0.0, "snn_tokens": 24000, "window": "test20k", "n": 4000, "fused_invocab_pct": 0.821, "fused_all_pct": 0.575, "snn_invocab_pct": 0.678, "cal": {"scale": 0.9632327447792072, "sigma_fast": 0.08319932298544339, "sigma_slow": 0.08637509826819102}, "Q": {"Q_mean": 0.0, "Q_max": 0.0, "Q_nnz_frac": 0.0}, "train_acc": [0.05616666666666666, 0.13391666666666666], "eval_s": 167.0, "peak_rss_mb": 877.3}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "seen", "n": 4000, "fused_invocab_pct": 98.462, "fused_all_pct": 98.0, "snn_invocab_pct": 45.962, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 148.1, "peak_rss_mb": 810.3}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "fc2", "n": 4000, "fused_invocab_pct": 7.704, "fused_all_pct": 5.35, "snn_invocab_pct": 3.341, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 148.0, "peak_rss_mb": 811.5}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "fresh_en", "n": 4000, "fused_invocab_pct": 1.124, "fused_all_pct": 0.8, "snn_invocab_pct": 1.159, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 144.2, "peak_rss_mb": 811.7}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "fresh_fr", "n": 4000, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 147.0, "peak_rss_mb": 876.7}
+{"arm": "AH1", "eta_ah": 0.001, "snn_tokens": 24000, "window": "test20k", "n": 4000, "fused_invocab_pct": 0.75, "fused_all_pct": 0.525, "snn_invocab_pct": 0.678, "cal": {"scale": 0.8736261564767037, "sigma_fast": 0.07613942006653979, "sigma_slow": 0.08715332010388374}, "Q": {"Q_mean": 0.0075839729979634285, "Q_max": 0.4831881523132324, "Q_nnz_frac": 0.919891357421875}, "train_acc": [0.053125, 0.17329166666666668], "eval_s": 147.5, "peak_rss_mb": 876.7}
diff --git a/results/hashing/lever2/verdict_AH1/verdict_AH1.json b/results/hashing/lever2/verdict_AH1/verdict_AH1.json
new file mode 100644
index 0000000000000000000000000000000000000000..e3738b798ae1e3bde2ef003161d221f2b31aadfd
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/verdict_AH1.json
@@ -0,0 +1,220 @@
+{
+ "cand": "AH1 (eta_ah=1e-3, rho=0.1, Q in [0,0.5], figé en éval)",
+ "ref": "ref (eta_ah=0, budget égal)",
+ "corpus": "broad/old_local_v1",
+ "snn_tokens": 24000,
+ "epochs": 2,
+ "max_positions": 4000,
+ "windows_measured": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_not_measured": [
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen",
+ "aucun gain significatif sur une fenêtre fraîche",
+ "perte(s) significative(s) : fc2"
+ ],
+ "losses": [
+ "fc2"
+ ],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2600,
+ "n_invocab_clean_cand": 2600,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 98.46153846153847,
+ "acc_cand_pct": 98.46153846153847,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 42,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a58d536c9af78bbf8451905f7c68222576dfc096bfd3b52f300d992b5a9240b4"
+ },
+ "fc2": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2544,
+ "n_invocab_clean_cand": 2544,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 8.254716981132075,
+ "acc_cand_pct": 7.70440251572327,
+ "delta_pct": -0.550314465408805,
+ "b_ref_only": 24,
+ "c_cand_only": 10,
+ "mcnemar_p": 0.024306510109454393,
+ "boot_ci95_delta_pct": [
+ -1.1080551822495261,
+ -0.03875856449594405
+ ],
+ "boot_p": 0.0444,
+ "n_blocks": 37,
+ "sig_gain": false,
+ "sig_loss": true,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ },
+ "fresh_en": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2847,
+ "n_invocab_clean_cand": 2847,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 1.2293642430628733,
+ "acc_cand_pct": 1.1239901650860555,
+ "delta_pct": -0.10537407797681775,
+ "b_ref_only": 11,
+ "c_cand_only": 8,
+ "mcnemar_p": 0.6476058959960938,
+ "boot_ci95_delta_pct": [
+ -0.416815013513543,
+ 0.17800087275434376
+ ],
+ "boot_p": 0.572,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ },
+ "fresh_fr": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 1557,
+ "n_invocab_clean_cand": 1557,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 30,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ },
+ "test20k": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2801,
+ "n_invocab_clean_cand": 2801,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.8211353088182792,
+ "acc_cand_pct": 0.7497322384862549,
+ "delta_pct": -0.07140307033202431,
+ "b_ref_only": 4,
+ "c_cand_only": 2,
+ "mcnemar_p": 0.6875,
+ "boot_ci95_delta_pct": [
+ -0.24673951357067336,
+ 0.10556039405894535
+ ],
+ "boot_p": 0.5462,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 17883
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 2.576304133253307,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 95.88523432828516,
+ "ci95": [
+ 95.17631636781792,
+ 96.55817642997651
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 2.394531229823895,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 96.06700723171457,
+ "ci95": [
+ 95.40164839357195,
+ 96.71787864908593
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": 0.18177290342940466,
+ "ci95": [
+ 0.024249240736329017,
+ 0.34262003170707644
+ ],
+ "ci95_boot_positions_seed25": [
+ 0.03944741090992139,
+ 0.326473583105809
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "note": "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+ },
+ "script_sha256": "cc6ac84e2fb5b2e69b490a5841d1c533d36345a5f6e323874dcab53aab42fde3",
+ "inputs_sha256": {
+ "ref__seen.npz": "a508542b6c6d1f4aafcb3c94fed843be7b4d5f4d136aeefca81cdee31d62eac8",
+ "ref__fc2.npz": "73ac8b9f777a42e223852450ef3c795122651893358407d53632f277f41f6003",
+ "ref__fresh_en.npz": "e2563d51b3677e4521e579c7e95afde18924ba8a7cee05c24f8ced0976b7817e",
+ "ref__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "ref__test20k.npz": "3c304dcbb48c6907b519fd42cf95bd817f52343dc588d478aa4273292d99fd4d",
+ "AH1__seen.npz": "a8f2e55db3debd594f07eb4df826bd41bcfcfd54cf685b69946a7ccdb94f9108",
+ "AH1__fc2.npz": "50ee8648bba55b661a87f850078a6fbac7f3edde95ba0621081c046fad4e89b3",
+ "AH1__fresh_en.npz": "8ae4cbd7ccb335eb702b77e14193fc29962daea196e28d7436471a833f1dab3d",
+ "AH1__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "AH1__test20k.npz": "6a64e0ea7498e0e83e1521cf1d273751fcfad5e2f0207490dc1c271a564e8faf"
+ },
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/lever2/verdict_AH1/verdict_AH1.md b/results/hashing/lever2/verdict_AH1/verdict_AH1.md
new file mode 100644
index 0000000000000000000000000000000000000000..54f4db8f0529ab5042e29239d1edaabd0a2206b0
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/verdict_AH1.md
@@ -0,0 +1,22 @@
+# Verdict levier 2 — AH1 (anti-hebbien Földiák, eta_ah = 1e-3) contre ref (eta_ah = 0, budget égal), old_local_v1 court
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche; perte(s) significative(s) : fc2
+
+Précision fused sur les cibles invocab (%), 4000 positions par fenêtre, appariement par position.
+
+| fenêtre | n apparié | AH1 % | réf % | Δ pts | b (réf seule) / c (AH1 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 4000 | 98.462 | 98.462 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fc2 | 4000 | 7.704 | 8.255 | -0.550 | 24/10 | 0.0243 | [-1.108 ; -0.039] | PERTE |
+| fresh_en | 4000 | 1.124 | 1.229 | -0.105 | 11/8 | 0.648 | [-0.417 ; +0.178] | n.s. |
+| fresh_fr | 4000 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test20k strict (old_local_v1/test.bin, union old ∪ broad) | 4000 | 0.750 | 0.821 | -0.071 | 4/2 | 0.688 | [-0.247 ; +0.106] | n.s. |
+| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+
+test20k strict : 0 positions exclues sur 4000 (0 par old_local_v1, 0 par broad_local_v1), octets évalués jusqu'à 17883.
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k ; test_v3 non mesuré) : AH1 +96.067 pts [IC95 +95.402 ; +96.718] (fraîche 2.395 %) ; réf +95.885 pts [+95.176 ; +96.558] (fraîche 2.576 %) ; différence AH1 − réf +0.182 [blocs 512 o seed 0 : +0.024 ; +0.343] [positions seed 25 : +0.039 ; +0.326].
+
+Script sha256 cc6ac84e2fb5b2e69b490a5841d1c533d36345a5f6e323874dcab53aab42fde3 ; masque sha256 50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178.
+
diff --git a/results/hashing/lever2/verdict_AH1/verdict_AH1.py b/results/hashing/lever2/verdict_AH1/verdict_AH1.py
new file mode 100644
index 0000000000000000000000000000000000000000..795997141662da0662a4e5527c5e3d4c47bc4515
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH1/verdict_AH1.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict levier 2 AH1 (eta_ah=1e-3) contre le témoin à budget égal ref (eta_ah=0), méthode banc v4.1
+(copie adaptée de m7_v41/strict/verdict_m7_v41_strict.py ; lecture seule des hits short_old/{ref,AH1}__*.npz, aucun modèle chargé).
+Fenêtres MESURÉES par run_l2.py (4000 positions chacune) : seen (= old_local_v1/train[:200000]), fc2, fresh_en, fresh_fr, test20k
+(= old_local_v1/test.bin, sha ce0526c6…, PAS broad_local_v1/test.bin ; masque strict propre recalculé : verdict_AH1/mask_oldtest_strict.npz,
+union old_local_v1 ∪ broad_local_v1). queries et test_v3 : NON évalués par les bras → absents (non mesurables). neither_code exclu.
+hit = fused_hit & invocab. Appariement par position si tgt_start et tgt_len identiques (vérifié). McNemar exact bilatéral = DÉCISION (p<0,05).
+Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un générateur seed 0, fenêtres dans l'ordre WIN, apparié ; stat = acc invocab.
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k strict ; test_v3 non mesuré). Bootstrap secondaire par positions, seed 25.
+Critère utilisateur : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche ET aucune perte significative sur une fenêtre valide ; sinon REJETÉ."""
+import sys, json, math, hashlib, numpy as np
+D = "/workspace/spira_shared/hashing_gen/lever2/short_old"; RT, CT = "ref", "AH1"; OP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1"
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k"]; GAPW = FRESH
+NOT_MEASURED = ["queries", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+MS = np.load(f"{OP}/mask_oldtest_strict.npz")
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{D}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_union": int((bo | bb_).sum()),
+ "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum())
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k])); p = binp(b, c)
+ ia, ib = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k
+ acc_a, acc_b = 100 * (ha & k).sum() / ia.sum(), 100 * (hb & k).sum() / ib.sum()
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], A["invocab"].astype(bool)[k], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], B["invocab"].astype(bool)[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, A["invocab"].astype(bool))
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "n_invocab_clean_ref": int(ia.sum()), "n_invocab_clean_cand": int(ib.sum()), "invocab_identical": inv_same,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)", "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"])}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+R2 = np.random.default_rng(25); BP = {}
+for w in WIN:
+ k, ha_, hb_, iv_ = KEEP[w]; m_ = k & iv_; r_ = ha_[m_].astype(np.float64); c_ = hb_[m_].astype(np.float64); n_ = len(r_); ar = np.empty(NB); ac = np.empty(NB)
+ for t in range(NB):
+ i = R2.integers(0, n_, n_); ar[t] = r_[i].mean(); ac[t] = c_[i].mean()
+ BP[w] = (100 * ar, 100 * ac)
+dgp = (BP["seen"][1] - np.mean([BP[w][1] for w in GAPW], axis=0)) - (BP["seen"][0] - np.mean([BP[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"]["ci95_boot_positions_seed25"] = [float(x) for x in np.percentile(dgp, [2.5, 97.5])]
+gap["windows"] = GAPW; gap["note"] = "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+out = {"cand": "AH1 (eta_ah=1e-3, rho=0.1, Q in [0,0.5], figé en éval)", "ref": "ref (eta_ah=0, budget égal)", "corpus": "broad/old_local_v1", "snn_tokens": 24000, "epochs": 2, "max_positions": 4000,
+ "windows_measured": WIN, "windows_not_measured": NOT_MEASURED, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap,
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN},
+ "mask_sha256": hashlib.sha256(open(f"{OP}/mask_oldtest_strict.npz", "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}/verdict_AH1.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict levier 2 — AH1 (anti-hebbien Földiák, eta_ah = 1e-3) contre ref (eta_ah = 0, budget égal), old_local_v1 court\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused sur les cibles invocab (%), 4000 positions par fenêtre, appariement par position.", "",
+ "| fenêtre | n apparié | AH1 % | réf % | Δ pts | b (réf seule) / c (AH1 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ nm = "test20k strict (old_local_v1/test.bin, union old ∪ broad)" if w == "test20k" else w
+ md.append(f"| {nm} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "",
+ f"test20k strict : {EX['excluded_union']} positions exclues sur 4000 ({EX['excluded_by_old_local_v1']} par old_local_v1, {EX['excluded_by_broad_local_v1']} par broad_local_v1), octets évalués jusqu'à {EX['max_byte_evaluated']}.", "",
+ f"Écart seen − moyenne fraîche ({', '.join(GAPW)} ; test_v3 non mesuré) : AH1 {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence AH1 − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [blocs 512 o seed 0 : {gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}] [positions seed 25 : {gap['cand_minus_ref']['ci95_boot_positions_seed25'][0]:+.3f} ; {gap['cand_minus_ref']['ci95_boot_positions_seed25'][1]:+.3f}].", "",
+ f"Script sha256 {out['script_sha256']} ; masque sha256 {out['mask_sha256']}.", ""]
+open(f"{OP}/verdict_AH1.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/lever2/verdict_AH2/expected_sha.txt b/results/hashing/lever2/verdict_AH2/expected_sha.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0299a4e033929240db31fc8c6329c5a5c551a406
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/expected_sha.txt
@@ -0,0 +1,11 @@
+456f177c0664953e288aa0d0310a13daa2e7826b540c477c7ee1945e8f4a7c23 verdict_AH2.md
+e1cdad3562d8c889e5e3c0eb01852ef2e60b7d8da01e11dfc1ac440c71461ed8 verdict_AH2.json
+6fbb18769754f8bd875dcc4f99bfb5ff5dae68045ec6d4a431e53f15f5fb2a17 verdict_AH2/verdict_AH2.py
+8efe2490d9dd3b1c7790bd08bb2354df3f5be0377e34cd0fe38ab0fe15026a04 verdict_AH2/verdict_AH2.log
+a85eae29744b460fef8b6ae850bd426620aa1f33a213bf49a2216faf7ab7159a verdict_AH2/results_AH2.jsonl
+cd74255a9ad3057c07bc13a4f3f80a8f5022aab190803b2d7b1d8ddda8494514 short_old.AH2.log
+14c0935cca6715734237030cf92accc5886c4f4afb5aa0da9fd5437ad16ec8da short_old/AH2__fc2.npz
+e83a5ddb3bc7652a0021a3ca1d150f0614bf7a0aa23196fb221cf79df47e776e short_old/AH2__fresh_en.npz
+0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c short_old/AH2__fresh_fr.npz
+fd8e860815ed298dc6da1df1b51f1554f3c93e19f5750e3099822323cbbab8d8 short_old/AH2__seen.npz
+ba2acd5e2b0ace7a90efe48079e814bbab7275b0b85fa80e2eb1c9ab786470c8 short_old/AH2__test20k.npz
diff --git a/results/hashing/lever2/verdict_AH2/gate.sh b/results/hashing/lever2/verdict_AH2/gate.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ea2b80ed49a9c1b2decf1a4c4006ffd423d205bc
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/gate.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# attend MemAvailable >= 5,2 Go (décimal), sondage toutes les 2 min, puis exécute la commande en nice 10
+while [ $(awk '/MemAvailable/{printf "%d", $2*1024}' /proc/meminfo) -lt 5200000000 ]; do echo "$(TZ=America/Toronto date '+%F %T %Z') porte: MemAvailable $(awk '/MemAvailable/{printf "%.2f", $2*1024/1e9}' /proc/meminfo) Go < 5,2" ; sleep 120; done
+echo "$(TZ=America/Toronto date '+%F %T %Z') porte ouverte: MemAvailable $(awk '/MemAvailable/{printf "%.2f", $2*1024/1e9}' /proc/meminfo) Go"
+export OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0
+exec nice -n 10 "$@"
diff --git a/results/hashing/lever2/verdict_AH2/hf_check/results/hashing/lever2/code/verdict_AH2.py b/results/hashing/lever2/verdict_AH2/hf_check/results/hashing/lever2/code/verdict_AH2.py
new file mode 100644
index 0000000000000000000000000000000000000000..5a12e79db80793f2a14d611ffd9935805ba5a0d2
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/hf_check/results/hashing/lever2/code/verdict_AH2.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict levier 2 AH2 (eta_ah=1e-2) contre le témoin à budget égal ref (eta_ah=0), méthode banc v4.1
+(copie adaptée de m7_v41/strict/verdict_m7_v41_strict.py ; lecture seule des hits short_old/{ref,AH2}__*.npz, aucun modèle chargé).
+Fenêtres MESURÉES par run_l2.py (4000 positions chacune) : seen (= old_local_v1/train[:200000]), fc2, fresh_en, fresh_fr, test20k
+(= old_local_v1/test.bin, sha ce0526c6…, PAS broad_local_v1/test.bin ; masque strict propre recalculé : verdict_AH2/mask_oldtest_strict.npz (copie identique de verdict_AH1/, sha 50fa08f9…),
+union old_local_v1 ∪ broad_local_v1). queries et test_v3 : NON évalués par les bras → absents (non mesurables). neither_code exclu.
+hit = fused_hit & invocab. Appariement par position si tgt_start et tgt_len identiques (vérifié). McNemar exact bilatéral = DÉCISION (p<0,05).
+Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un générateur seed 0, fenêtres dans l'ordre WIN, apparié ; stat = acc invocab.
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k strict ; test_v3 non mesuré). Bootstrap secondaire par positions, seed 25.
+Critère utilisateur : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche ET aucune perte significative sur une fenêtre valide ; sinon REJETÉ."""
+import sys, json, math, hashlib, numpy as np
+D = "/workspace/spira_shared/hashing_gen/lever2/short_old"; RT, CT = "ref", "AH2"; OP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH2"
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k"]; GAPW = FRESH
+NOT_MEASURED = ["queries", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+MS = np.load(f"{OP}/mask_oldtest_strict.npz")
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{D}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_union": int((bo | bb_).sum()),
+ "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum())
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k])); p = binp(b, c)
+ ia, ib = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k
+ acc_a, acc_b = 100 * (ha & k).sum() / ia.sum(), 100 * (hb & k).sum() / ib.sum()
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], A["invocab"].astype(bool)[k], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], B["invocab"].astype(bool)[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, A["invocab"].astype(bool))
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "n_invocab_clean_ref": int(ia.sum()), "n_invocab_clean_cand": int(ib.sum()), "invocab_identical": inv_same,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)", "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"])}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+R2 = np.random.default_rng(25); BP = {}
+for w in WIN:
+ k, ha_, hb_, iv_ = KEEP[w]; m_ = k & iv_; r_ = ha_[m_].astype(np.float64); c_ = hb_[m_].astype(np.float64); n_ = len(r_); ar = np.empty(NB); ac = np.empty(NB)
+ for t in range(NB):
+ i = R2.integers(0, n_, n_); ar[t] = r_[i].mean(); ac[t] = c_[i].mean()
+ BP[w] = (100 * ar, 100 * ac)
+dgp = (BP["seen"][1] - np.mean([BP[w][1] for w in GAPW], axis=0)) - (BP["seen"][0] - np.mean([BP[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"]["ci95_boot_positions_seed25"] = [float(x) for x in np.percentile(dgp, [2.5, 97.5])]
+gap["windows"] = GAPW; gap["note"] = "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+# --- ajout AH2 : drapeau « l'écart ne baisse pas ET le frais ne monte pas » + rappel AH1 (lu dans verdict_AH1.json, poussé 72bf585e) ---
+fm_d = gap["cand"]["fresh_mean_pct"] - gap["ref"]["fresh_mean_pct"]
+fmb = np.mean([BOOT[w][1] for w in GAPW], axis=0) - np.mean([BOOT[w][0] for w in GAPW], axis=0)
+gap["cand_minus_ref"]["fresh_mean_diff_pct"] = float(fm_d); gap["cand_minus_ref"]["fresh_mean_diff_ci95"] = [float(x) for x in np.nanpercentile(fmb, [2.5, 97.5])]
+gap_drops = gap["cand_minus_ref"]["ci95"][1] < 0; fresh_rises = gap["cand_minus_ref"]["fresh_mean_diff_ci95"][0] > 0
+FLAG = bool(not gap_drops and not fresh_rises)
+gap["flag_gap_not_down_and_fresh_not_up"] = FLAG
+gap["flag_def"] = "écart ne baisse pas = IC95 bloc de (écart cand − écart réf) ne passe pas entièrement sous 0 ; frais ne monte pas = IC95 bloc de (moyenne fraîche cand − réf) ne passe pas entièrement au-dessus de 0"
+AH1J = json.load(open("/workspace/spira_shared/hashing_gen/lever2/verdict_AH1.json"))
+AH1 = {"decision": AH1J["decision"], "per_window": {w: {k: AH1J["per_window"][w][k] for k in ("acc_cand_pct", "acc_ref_pct", "delta_pct", "b_ref_only", "c_cand_only", "mcnemar_p", "boot_ci95_delta_pct")} for w in WIN},
+ "seen_fresh_gap": AH1J["seen_fresh_gap"], "verdict_AH1_json_sha256": hashlib.sha256(open("/workspace/spira_shared/hashing_gen/lever2/verdict_AH1.json", "rb").read()).hexdigest(), "hf_commit": "72bf585e62e95b9f8906c1ba6a2d64889e645e04"}
+for w in WIN: assert abs(AH1J["per_window"][w]["acc_ref_pct"] - R[w]["acc_ref_pct"]) < 1e-9, f"{w}: réf différente de celle du verdict AH1"
+out = {"cand": "AH2 (eta_ah=1e-2, rho=0.1, Q in [0,0.5], figé en éval)", "ref": "ref (eta_ah=0, budget égal)", "corpus": "broad/old_local_v1", "snn_tokens": 24000, "epochs": 2, "max_positions": 4000,
+ "windows_measured": WIN, "windows_not_measured": NOT_MEASURED, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap, "AH1_for_comparison": AH1,
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN},
+ "mask_sha256": hashlib.sha256(open(f"{OP}/mask_oldtest_strict.npz", "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}/verdict_AH2.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict levier 2 — AH2 (anti-hebbien Földiák, eta_ah = 1e-2) contre ref (eta_ah = 0, budget égal), old_local_v1 court\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused sur les cibles invocab (%), 4000 positions par fenêtre, appariement par position.", "",
+ "| fenêtre | n apparié | AH2 % | réf % | Δ pts | b (réf seule) / c (AH2 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ nm = "test20k strict (old_local_v1/test.bin, union old ∪ broad)" if w == "test20k" else w
+ md.append(f"| {nm} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "",
+ f"test20k strict : {EX['excluded_union']} positions exclues sur 4000 ({EX['excluded_by_old_local_v1']} par old_local_v1, {EX['excluded_by_broad_local_v1']} par broad_local_v1), octets évalués jusqu'à {EX['max_byte_evaluated']}.", "",
+ f"Écart seen − moyenne fraîche ({', '.join(GAPW)} ; test_v3 non mesuré) : AH2 {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence AH2 − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [blocs 512 o seed 0 : {gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}] [positions seed 25 : {gap['cand_minus_ref']['ci95_boot_positions_seed25'][0]:+.3f} ; {gap['cand_minus_ref']['ci95_boot_positions_seed25'][1]:+.3f}].", "",
+ f"Script sha256 {out['script_sha256']} ; masque sha256 {out['mask_sha256']}.", ""]
+md += [f"Moyenne fraîche AH2 − réf : {fm_d:+.3f} pts [IC95 blocs {gap['cand_minus_ref']['fresh_mean_diff_ci95'][0]:+.3f} ; {gap['cand_minus_ref']['fresh_mean_diff_ci95'][1]:+.3f}]. "
+ + ("**DRAPEAU : l'écart ne baisse pas et le frais ne monte pas.**" if FLAG else ("L'écart baisse significativement." if gap_drops else "") + (" Le frais monte significativement." if fresh_rises else "")), "",
+ "## Rappel AH1 (eta_ah = 1e-3, verdict_AH1.json, commit 72bf585e) — même réf", "", "| fenêtre | AH1 % | réf % | Δ pts | b/c | p McNemar | IC95 Δ |", "|---|---|---|---|---|---|---|"]
+for w in WIN:
+ a = AH1["per_window"][w]; md.append(f"| {w} | {a['acc_cand_pct']:.3f} | {a['acc_ref_pct']:.3f} | {a['delta_pct']:+.3f} | {a['b_ref_only']}/{a['c_cand_only']} | {a['mcnemar_p']:.3g} | [{a['boot_ci95_delta_pct'][0]:+.3f} ; {a['boot_ci95_delta_pct'][1]:+.3f}] |")
+g1 = AH1["seen_fresh_gap"]
+md += ["", f"Écart AH1 {g1['cand']['gap_pct']:+.3f} [{g1['cand']['ci95'][0]:+.3f} ; {g1['cand']['ci95'][1]:+.3f}] ; AH1 − réf {g1['cand_minus_ref']['gap_diff_pct']:+.3f} [{g1['cand_minus_ref']['ci95'][0]:+.3f} ; {g1['cand_minus_ref']['ci95'][1]:+.3f}] ; verdict AH1 {AH1['decision']}.", ""]
+open(f"{OP}/verdict_AH2.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/lever2/verdict_AH2/hf_check/results/hashing/lever2/results_AH2.jsonl b/results/hashing/lever2/verdict_AH2/hf_check/results/hashing/lever2/results_AH2.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..2e8024b4fee451234ea0af2ccdd2d55b22c9afbc
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/hf_check/results/hashing/lever2/results_AH2.jsonl
@@ -0,0 +1,5 @@
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "seen", "n": 4000, "fused_invocab_pct": 98.462, "fused_all_pct": 98.0, "snn_invocab_pct": 42.115, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 142.9, "peak_rss_mb": 810.2}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "fc2", "n": 4000, "fused_invocab_pct": 7.822, "fused_all_pct": 5.425, "snn_invocab_pct": 3.184, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 139.7, "peak_rss_mb": 810.8}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "fresh_en", "n": 4000, "fused_invocab_pct": 1.054, "fused_all_pct": 0.75, "snn_invocab_pct": 1.089, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 140.6, "peak_rss_mb": 811.1}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "fresh_fr", "n": 4000, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 138.7, "peak_rss_mb": 876.1}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "test20k", "n": 4000, "fused_invocab_pct": 0.785, "fused_all_pct": 0.55, "snn_invocab_pct": 0.75, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 142.8, "peak_rss_mb": 876.1}
diff --git a/results/hashing/lever2/verdict_AH2/hf_check/results/hashing/lever2/verdict_AH2.json b/results/hashing/lever2/verdict_AH2/hf_check/results/hashing/lever2/verdict_AH2.json
new file mode 100644
index 0000000000000000000000000000000000000000..08e0c90ed8cef12e59dd36bd347fd02cdc6ffcd5
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/hf_check/results/hashing/lever2/verdict_AH2.json
@@ -0,0 +1,329 @@
+{
+ "cand": "AH2 (eta_ah=1e-2, rho=0.1, Q in [0,0.5], figé en éval)",
+ "ref": "ref (eta_ah=0, budget égal)",
+ "corpus": "broad/old_local_v1",
+ "snn_tokens": 24000,
+ "epochs": 2,
+ "max_positions": 4000,
+ "windows_measured": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_not_measured": [
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen",
+ "aucun gain significatif sur une fenêtre fraîche"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2600,
+ "n_invocab_clean_cand": 2600,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 98.46153846153847,
+ "acc_cand_pct": 98.46153846153847,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 42,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a58d536c9af78bbf8451905f7c68222576dfc096bfd3b52f300d992b5a9240b4"
+ },
+ "fc2": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2544,
+ "n_invocab_clean_cand": 2544,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 8.254716981132075,
+ "acc_cand_pct": 7.822327044025157,
+ "delta_pct": -0.432389937106918,
+ "b_ref_only": 21,
+ "c_cand_only": 10,
+ "mcnemar_p": 0.07075554598122835,
+ "boot_ci95_delta_pct": [
+ -0.9094586196631579,
+ 0.038699690402476804
+ ],
+ "boot_p": 0.0808,
+ "n_blocks": 37,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ },
+ "fresh_en": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2847,
+ "n_invocab_clean_cand": 2847,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 1.2293642430628733,
+ "acc_cand_pct": 1.053740779768177,
+ "delta_pct": -0.17562346329469625,
+ "b_ref_only": 11,
+ "c_cand_only": 6,
+ "mcnemar_p": 0.332305908203125,
+ "boot_ci95_delta_pct": [
+ -0.49191848208011235,
+ 0.10463899546564348
+ ],
+ "boot_p": 0.2912,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ },
+ "fresh_fr": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 1557,
+ "n_invocab_clean_cand": 1557,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 30,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ },
+ "test20k": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2801,
+ "n_invocab_clean_cand": 2801,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.8211353088182792,
+ "acc_cand_pct": 0.7854337736522671,
+ "delta_pct": -0.035701535166012155,
+ "b_ref_only": 6,
+ "c_cand_only": 5,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -0.28198801550934083,
+ 0.2164521692670375
+ ],
+ "boot_p": 0.8708,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 17883
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 2.576304133253307,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 95.88523432828516,
+ "ci95": [
+ 95.17631636781792,
+ 96.55817642997651
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 2.4153753993614004,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 96.04616306217707,
+ "ci95": [
+ 95.35077178999046,
+ 96.71769863177818
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": 0.16092873389190743,
+ "ci95": [
+ 0.008778902411852845,
+ 0.3162619288237518
+ ],
+ "ci95_boot_positions_seed25": [
+ 0.020879195458747193,
+ 0.3051967816879966
+ ],
+ "fresh_mean_diff_pct": -0.16092873389190654,
+ "fresh_mean_diff_ci95": [
+ -0.31626192882374865,
+ -0.008778902411853003
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "note": "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu",
+ "flag_gap_not_down_and_fresh_not_up": true,
+ "flag_def": "écart ne baisse pas = IC95 bloc de (écart cand − écart réf) ne passe pas entièrement sous 0 ; frais ne monte pas = IC95 bloc de (moyenne fraîche cand − réf) ne passe pas entièrement au-dessus de 0"
+ },
+ "AH1_for_comparison": {
+ "decision": "REJETÉ",
+ "per_window": {
+ "seen": {
+ "acc_cand_pct": 98.46153846153847,
+ "acc_ref_pct": 98.46153846153847,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ]
+ },
+ "fc2": {
+ "acc_cand_pct": 7.70440251572327,
+ "acc_ref_pct": 8.254716981132075,
+ "delta_pct": -0.550314465408805,
+ "b_ref_only": 24,
+ "c_cand_only": 10,
+ "mcnemar_p": 0.024306510109454393,
+ "boot_ci95_delta_pct": [
+ -1.1080551822495261,
+ -0.03875856449594405
+ ]
+ },
+ "fresh_en": {
+ "acc_cand_pct": 1.1239901650860555,
+ "acc_ref_pct": 1.2293642430628733,
+ "delta_pct": -0.10537407797681775,
+ "b_ref_only": 11,
+ "c_cand_only": 8,
+ "mcnemar_p": 0.6476058959960938,
+ "boot_ci95_delta_pct": [
+ -0.416815013513543,
+ 0.17800087275434376
+ ]
+ },
+ "fresh_fr": {
+ "acc_cand_pct": 0.0,
+ "acc_ref_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ]
+ },
+ "test20k": {
+ "acc_cand_pct": 0.7497322384862549,
+ "acc_ref_pct": 0.8211353088182792,
+ "delta_pct": -0.07140307033202431,
+ "b_ref_only": 4,
+ "c_cand_only": 2,
+ "mcnemar_p": 0.6875,
+ "boot_ci95_delta_pct": [
+ -0.24673951357067336,
+ 0.10556039405894535
+ ]
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 2.576304133253307,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 95.88523432828516,
+ "ci95": [
+ 95.17631636781792,
+ 96.55817642997651
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 2.394531229823895,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 96.06700723171457,
+ "ci95": [
+ 95.40164839357195,
+ 96.71787864908593
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": 0.18177290342940466,
+ "ci95": [
+ 0.024249240736329017,
+ 0.34262003170707644
+ ],
+ "ci95_boot_positions_seed25": [
+ 0.03944741090992139,
+ 0.326473583105809
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "note": "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+ },
+ "verdict_AH1_json_sha256": "3b7b980184c06834a2b74b737c1ff99a6e87fff435294e4c257fcca6b397d483",
+ "hf_commit": "72bf585e62e95b9f8906c1ba6a2d64889e645e04"
+ },
+ "script_sha256": "6fbb18769754f8bd875dcc4f99bfb5ff5dae68045ec6d4a431e53f15f5fb2a17",
+ "inputs_sha256": {
+ "ref__seen.npz": "a508542b6c6d1f4aafcb3c94fed843be7b4d5f4d136aeefca81cdee31d62eac8",
+ "ref__fc2.npz": "73ac8b9f777a42e223852450ef3c795122651893358407d53632f277f41f6003",
+ "ref__fresh_en.npz": "e2563d51b3677e4521e579c7e95afde18924ba8a7cee05c24f8ced0976b7817e",
+ "ref__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "ref__test20k.npz": "3c304dcbb48c6907b519fd42cf95bd817f52343dc588d478aa4273292d99fd4d",
+ "AH2__seen.npz": "fd8e860815ed298dc6da1df1b51f1554f3c93e19f5750e3099822323cbbab8d8",
+ "AH2__fc2.npz": "14c0935cca6715734237030cf92accc5886c4f4afb5aa0da9fd5437ad16ec8da",
+ "AH2__fresh_en.npz": "e83a5ddb3bc7652a0021a3ca1d150f0614bf7a0aa23196fb221cf79df47e776e",
+ "AH2__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "AH2__test20k.npz": "ba2acd5e2b0ace7a90efe48079e814bbab7275b0b85fa80e2eb1c9ab786470c8"
+ },
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/lever2/verdict_AH2/hf_check/results/hashing/lever2/verdict_AH2.md b/results/hashing/lever2/verdict_AH2/hf_check/results/hashing/lever2/verdict_AH2.md
new file mode 100644
index 0000000000000000000000000000000000000000..b47a11ba3f49977458653c48b0ea708d54005c01
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/hf_check/results/hashing/lever2/verdict_AH2.md
@@ -0,0 +1,36 @@
+# Verdict levier 2 — AH2 (anti-hebbien Földiák, eta_ah = 1e-2) contre ref (eta_ah = 0, budget égal), old_local_v1 court
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche
+
+Précision fused sur les cibles invocab (%), 4000 positions par fenêtre, appariement par position.
+
+| fenêtre | n apparié | AH2 % | réf % | Δ pts | b (réf seule) / c (AH2 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 4000 | 98.462 | 98.462 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fc2 | 4000 | 7.822 | 8.255 | -0.432 | 21/10 | 0.0708 | [-0.909 ; +0.039] | n.s. |
+| fresh_en | 4000 | 1.054 | 1.229 | -0.176 | 11/6 | 0.332 | [-0.492 ; +0.105] | n.s. |
+| fresh_fr | 4000 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test20k strict (old_local_v1/test.bin, union old ∪ broad) | 4000 | 0.785 | 0.821 | -0.036 | 6/5 | 1 | [-0.282 ; +0.216] | n.s. |
+| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+
+test20k strict : 0 positions exclues sur 4000 (0 par old_local_v1, 0 par broad_local_v1), octets évalués jusqu'à 17883.
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k ; test_v3 non mesuré) : AH2 +96.046 pts [IC95 +95.351 ; +96.718] (fraîche 2.415 %) ; réf +95.885 pts [+95.176 ; +96.558] (fraîche 2.576 %) ; différence AH2 − réf +0.161 [blocs 512 o seed 0 : +0.009 ; +0.316] [positions seed 25 : +0.021 ; +0.305].
+
+Script sha256 6fbb18769754f8bd875dcc4f99bfb5ff5dae68045ec6d4a431e53f15f5fb2a17 ; masque sha256 50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178.
+
+Moyenne fraîche AH2 − réf : -0.161 pts [IC95 blocs -0.316 ; -0.009]. **DRAPEAU : l'écart ne baisse pas et le frais ne monte pas.**
+
+## Rappel AH1 (eta_ah = 1e-3, verdict_AH1.json, commit 72bf585e) — même réf
+
+| fenêtre | AH1 % | réf % | Δ pts | b/c | p McNemar | IC95 Δ |
+|---|---|---|---|---|---|---|
+| seen | 98.462 | 98.462 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] |
+| fc2 | 7.704 | 8.255 | -0.550 | 24/10 | 0.0243 | [-1.108 ; -0.039] |
+| fresh_en | 1.124 | 1.229 | -0.105 | 11/8 | 0.648 | [-0.417 ; +0.178] |
+| fresh_fr | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] |
+| test20k | 0.750 | 0.821 | -0.071 | 4/2 | 0.688 | [-0.247 ; +0.106] |
+
+Écart AH1 +96.067 [+95.402 ; +96.718] ; AH1 − réf +0.182 [+0.024 ; +0.343] ; verdict AH1 REJETÉ.
+
diff --git a/results/hashing/lever2/verdict_AH2/push_lever2_AH2.py b/results/hashing/lever2/verdict_AH2/push_lever2_AH2.py
new file mode 100644
index 0000000000000000000000000000000000000000..2ca0656098a88abea358f1487cfbd5b6ac0bea09
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/push_lever2_AH2.py
@@ -0,0 +1,29 @@
+"""SPIRA Hashing — push verdict levier 2 AH2 sous results/hashing/lever2/ (ajout seul). Usage : push_lever2_AH2.py {all|nohits}.
+Porte upload léger MemAvailable >= 4,4 Go (poll 120 s). Refuse si sha local != sha annoncé au relais ou si une cible existe. Vérifie après coup."""
+import os, sys, time, hashlib, datetime, zoneinfo, resource
+from huggingface_hub import HfApi, CommitOperationAdd, hf_hub_download
+REPO = "thefinalboss/SPIRA"; P = "results/hashing/lever2"; B = "/workspace/spira_shared/hashing_gen/lever2"; H = f"{B}/verdict_AH2"
+now = lambda: datetime.datetime.now(zoneinfo.ZoneInfo("America/Toronto")).strftime("%F %H:%M:%S %Z")
+sha = lambda p: hashlib.sha256(open(p, "rb").read()).hexdigest()
+EXP = {l.split()[1]: l.split()[0] for l in open(f"{H}/expected_sha.txt")}
+def dest(k):
+ n = os.path.basename(k); n = n + ".txt" if n.endswith(".log") else n
+ if k in ("verdict_AH2.md", "verdict_AH2.json"): return n
+ if k.startswith("short_old/") and n.endswith(".npz"): return "hits/" + n
+ if k.startswith("verdict_AH2/") and n.endswith(".py") or k.startswith("code/") or n == "gate.sh": return "code/" + n
+ return n
+F = {k: dest(k) for k in EXP if not (sys.argv[1] == "nohits" and k.endswith(".npz") and k.startswith("short_old/"))}
+assert len(set(F.values())) == len(F) and not any(v.endswith(".bin") for v in F.values())
+mem = lambda: int([l for l in open("/proc/meminfo") if l.startswith("MemAvailable")][0].split()[1]) * 1024
+while mem() < 4_400_000_000: print(now(), "porte upload léger: MemAvailable", mem(), flush=True); time.sleep(120)
+print(now(), "porte OK MemAvailable", mem(), flush=True)
+loc = {k: sha(f"{B}/{k}") for k in F}; bad = [k for k in F if loc[k] != EXP[k]]; assert not bad, f"ARRÊT sha changé : {bad}"
+api = HfApi(); before = set(api.list_repo_files(REPO)); tg = {f"{P}/{v}" for v in F.values()}; assert not (tg & before), f"ARRÊT déjà sur HF {tg & before}"
+ci = api.create_commit(REPO, operations=[CommitOperationAdd(path_in_repo=f"{P}/{v}", path_or_fileobj=f"{B}/{k}") for k, v in F.items()],
+ commit_message=f"hashing lever2: AH2 (anti-Hebbian eta=1e-2) vs eta=0 control, v4.1 verdict REJETÉ ({len(F)} files, Checker PASS)")
+print(now(), "COMMIT", ci.oid, flush=True)
+after = set(api.list_repo_files(REPO, revision=ci.oid)); print("ADDED", len(after - before), "REMOVED", sorted(before - after)); print("ADD_ONLY", after - before == tg and not (before - after))
+post = f"{H}/hf_check"; os.makedirs(post, exist_ok=True)
+for k, v in F.items():
+ p = hf_hub_download(REPO, f"{P}/{v}", local_dir=post, revision=ci.oid, force_download=True); print("VERIF", v, sha(p) == loc[k], sha(p))
+print(now(), "peak_rss_MB", resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024, flush=True)
diff --git a/results/hashing/lever2/verdict_AH2/push_list.txt b/results/hashing/lever2/verdict_AH2/push_list.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fb3a5647226cb03d44abcb0838ec79becfbabb7d
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/push_list.txt
@@ -0,0 +1 @@
+verdict_AH2.md verdict_AH2.json verdict_AH2/verdict_AH2.py verdict_AH2/verdict_AH2.log verdict_AH2/results_AH2.jsonl short_old.AH2.log short_old/AH2__fc2.npz short_old/AH2__fresh_en.npz short_old/AH2__fresh_fr.npz short_old/AH2__seen.npz short_old/AH2__test20k.npz
diff --git a/results/hashing/lever2/verdict_AH2/relay_C1.md b/results/hashing/lever2/verdict_AH2/relay_C1.md
new file mode 100644
index 0000000000000000000000000000000000000000..ef7294b5a43ceefd55d0798e3e779325c50b18cb
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/relay_C1.md
@@ -0,0 +1,60 @@
+
+### Hashing — 02 h 44 — Levier 2 : verdict AH2 (eta_ah = 1e-2) contre le témoin eta = 0 (budget égal) — **REJETÉ** — SPIRA Hashing
+AH2 (957217) est fini (rc 0, DONE à 2 862 s, ~02 h 43). **Correctif à l'entrée automatique de 02 h 43 (final.sh)** : elle annonce « ÉCHEC du run/comparaison » pour AH1 et AH2. Ce n'est pas un échec des runs. C'est compare.py qui échoue sur un import (ModuleNotFoundError: scipy, voir /tmp/spira_hashing_lever2/finalize.out). Les trois bras ont bien fini avec rc 0 et produit leurs 5 hits .npz. Le verdict qui fait foi est celui ci-dessous (v4.1, sans scipy).
+
+Méthode : identique à AH1. Script verdict_AH2/verdict_AH2.py (sha 6fbb1876…) = copie de verdict_AH1.py (cc6ac84e…) avec CT=AH2. Ajouts :
+- rappel des chiffres AH1 ;
+- drapeau écart/frais ;
+- assert que la réf est identique à celle du verdict AH1.
+Contrôle : le même script lancé avec CT=AH1 redonne exactement les chiffres d'AH1 (fc2 24/10 p 0,0243 ; écart +0,182 [+0,024 ; +0,343]).
+- hit = fused_hit & invocab ; appariement par position (tgt_start et tgt_len identiques, vérifiés par assert ; invocab identique dans les 5 fenêtres).
+- McNemar exact bilatéral, décision à p < 0,05. IC95 : bootstrap par blocs de 512 o, B = 10 000, seed 0. 4 000 positions par fenêtre ; neither_code exclu.
+- Masque strict old_local_v1/test.bin : le même fichier qu'AH1 (sha 50fa08f9…, copié dans verdict_AH2/), 0 position exclue.
+- Calcul léger lancé à 4,71 Go de MemAvailable (pas de porte 5,2 : aucun modèle chargé). Durée 1,1 s, pic RSS 45 Mo.
+
+| fenêtre | AH2 % | réf % | Δ pts | b réf seule / c AH2 seul | p McNemar | IC95 Δ (blocs 512 o) | |
+|---|---|---|---|---|---|---|---|
+| seen (train[:200k]) | 98,462 | 98,462 | 0,000 | 0/0 | 1 | [0 ; 0] | n.s. |
+| fc2 | 7,822 | 8,255 | −0,432 | 21/10 | 0,0708 | [−0,909 ; +0,039] | n.s. |
+| fresh_en | 1,054 | 1,229 | −0,176 | 11/6 | 0,332 | [−0,492 ; +0,105] | n.s. |
+| fresh_fr | 0,000 | 0,000 | 0 | 0/0 | 1 | [0 ; 0] | n.s. (aucun hit dans les deux bras) |
+| test20k strict | 0,785 | 0,821 | −0,036 | 6/5 | 1 | [−0,282 ; +0,216] | n.s. |
+| queries, test_v3 | non mesurés | | | | | | non évalués par run_l2.py |
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k strict) :
+- AH2 : **+96,046** [+95,351 ; +96,718], moyenne fraîche 2,415 %.
+- Réf : **+95,885** [+95,176 ; +96,558], moyenne fraîche 2,576 %.
+- **Δ AH2 − réf = +0,161** : IC95 [+0,009 ; +0,316] en blocs seed 0, [+0,021 ; +0,305] en positions seed 25.
+- **Moyenne fraîche AH2 − réf = −0,161** [−0,316 ; −0,009].
+- **DRAPEAU : l'écart ne baisse pas (il augmente légèrement, de façon significative au bootstrap) et le frais ne monte pas (il baisse).**
+
+Rappel AH1 (eta 1e-3, même réf, commit 72bf585e) :
+- seen 0/0 ; fc2 −0,550 (24/10, p 0,0243, PERTE) ; fresh_en −0,105 (p 0,648) ; fresh_fr 0 ; test20k −0,071 (p 0,688).
+- Écart +0,182 [+0,024 ; +0,343]. REJETÉ.
+- AH2 perd un peu moins sur fc2 (n.s. au lieu d'une perte significative), mais le sens est le même partout.
+
+**Décision : REJETÉ.**
+- Pas de gain sur seen (0 discordant ; seen saturé à 98,46 % dans les deux bras).
+- Aucun gain frais.
+- Aucune perte significative au McNemar (fc2 p = 0,071 est le plus proche).
+- Aucun des deux réglages pré-déclarés (1e-3, 1e-2) ne satisfait le critère : le levier 2 court est négatif.
+
+Notes (hors critère, non appariées) :
+- SNN seul invocab sur seen : 42,885 (réf) → 42,115 (AH2).
+- Recalibration de la fusion : scale 0,963 → 0,786.
+- Q final : moyenne 0,0093, max 0,497, 68 % non nuls.
+- train_acc époque 2 : 0,167 (AH2), contre 0,173 pour AH1.
+- AH2__fresh_fr.npz a le même sha que ref__fresh_fr.npz et AH1__fresh_fr.npz (0d522e81…) : hits tous faux, mêmes offsets.
+
+**→ Checker : recompte indépendant demandé** (McNemar, IC, écart, drapeau), puis PASS/FAIL écrit sur ce push. Push sous results/hashing/lever2/, ajout seul, logs en .log.txt, porte upload léger 4,4 Go, 11 fichiers :
+- verdict_AH2.md (456f177c…)
+- verdict_AH2.json (e1cdad35…)
+- verdict_AH2/verdict_AH2.py → code/verdict_AH2.py (6fbb1876…)
+- verdict_AH2/verdict_AH2.log → verdict_AH2.log.txt (8efe2490…)
+- verdict_AH2/results_AH2.jsonl (a85eae29…) : copie figée des 5 lignes AH2 de results.jsonl
+- short_old.AH2.log → short_old.AH2.log.txt (cd74255a…)
+- hits/AH2__fc2.npz (14c0935c…), hits/AH2__fresh_en.npz (e83a5ddb…), hits/AH2__fresh_fr.npz (0d522e81…), hits/AH2__seen.npz (fd8e8608…), hits/AH2__test20k.npz (ba2acd5e…). Contenu : bool[4000] ×5 + tgt_start/tgt_len int64 + une chaîne sha, aucun octet de fenêtre.
+
+Le code (run_l2.py 5642eba1…, antihebb.py 7517b9de…), le masque et les hits ref sont déjà sur HF (72bf585e) et inchangés ; je ne les repousse pas. Le script de push (verdict_AH2/push_lever2_AH2.py) refuse si un sha diffère, s'il y a un .bin ou si une cible existe.
+
+Rien tué (920839 non touché), rien de nouveau dans /tmp. — SPIRA Hashing
diff --git a/results/hashing/lever2/verdict_AH2/relay_C2.md b/results/hashing/lever2/verdict_AH2/relay_C2.md
new file mode 100644
index 0000000000000000000000000000000000000000..66e2e67aa4e43d16f63e302f951092eb52de1cd6
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/relay_C2.md
@@ -0,0 +1,12 @@
+
+### Hashing — 02 h 51 — Lu/appliqué — Hashing (PASS Checker AH2) + push verdict AH2 FAIT
+- PASS push lever2 AH2 (11 fichiers) et recompte identique : lus. **Commit 23efb0adbd5fc2e83204d5b5f1a14499e7025841** (02 h 51), 11 ajouts sous results/hashing/lever2/.
+- Contrôles :
+ - ADD_ONLY True (list_repo_files avant/après), 0 fichier retiré.
+ - Les 11 sha256 retéléchargés à cette révision sont identiques au local et à expected_sha.txt.
+- MemAvailable 4,66 Go au push (porte 4,4 Go), pic RSS de l'uploader 60 Mo. hf_pushed.txt mis à jour.
+- **→ Checker : audit PASS/FAIL de 23efb0ad demandé.**
+- Note : ton entrée porte l'en-tête « 23 h 48 (Toronto) », alors qu'elle a été écrite après mon entrée de 02 h 44 (heure du Pacifique de la box ?). Merci de vérifier ton TZ.
+- Verdict rappelé : AH2 **REJETÉ** (aucun gain ; écart +0,161 [+0,009 ; +0,316], DRAPEAU). Levier 2 anti-hebbien fermé.
+- Je ne touche pas à /tmp/spira_hashing_lever2/compare.py : rien de nouveau dans /tmp, et ce n'est pas dans mon mandat.
+- Rien tué, rien dans /tmp. — SPIRA Hashing
diff --git a/results/hashing/lever2/verdict_AH2/results_AH2.jsonl b/results/hashing/lever2/verdict_AH2/results_AH2.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..2e8024b4fee451234ea0af2ccdd2d55b22c9afbc
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/results_AH2.jsonl
@@ -0,0 +1,5 @@
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "seen", "n": 4000, "fused_invocab_pct": 98.462, "fused_all_pct": 98.0, "snn_invocab_pct": 42.115, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 142.9, "peak_rss_mb": 810.2}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "fc2", "n": 4000, "fused_invocab_pct": 7.822, "fused_all_pct": 5.425, "snn_invocab_pct": 3.184, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 139.7, "peak_rss_mb": 810.8}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "fresh_en", "n": 4000, "fused_invocab_pct": 1.054, "fused_all_pct": 0.75, "snn_invocab_pct": 1.089, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 140.6, "peak_rss_mb": 811.1}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "fresh_fr", "n": 4000, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 138.7, "peak_rss_mb": 876.1}
+{"arm": "AH2", "eta_ah": 0.01, "snn_tokens": 24000, "window": "test20k", "n": 4000, "fused_invocab_pct": 0.785, "fused_all_pct": 0.55, "snn_invocab_pct": 0.75, "cal": {"scale": 0.786301162912465, "sigma_fast": 0.07281651013435568, "sigma_slow": 0.09260638743638992}, "Q": {"Q_mean": 0.009260807186365128, "Q_max": 0.4971490502357483, "Q_nnz_frac": 0.6785507202148438}, "train_acc": [0.053, 0.16741666666666666], "eval_s": 142.8, "peak_rss_mb": 876.1}
diff --git a/results/hashing/lever2/verdict_AH2/verdict_AH2.json b/results/hashing/lever2/verdict_AH2/verdict_AH2.json
new file mode 100644
index 0000000000000000000000000000000000000000..08e0c90ed8cef12e59dd36bd347fd02cdc6ffcd5
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/verdict_AH2.json
@@ -0,0 +1,329 @@
+{
+ "cand": "AH2 (eta_ah=1e-2, rho=0.1, Q in [0,0.5], figé en éval)",
+ "ref": "ref (eta_ah=0, budget égal)",
+ "corpus": "broad/old_local_v1",
+ "snn_tokens": 24000,
+ "epochs": 2,
+ "max_positions": 4000,
+ "windows_measured": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_not_measured": [
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen",
+ "aucun gain significatif sur une fenêtre fraîche"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2600,
+ "n_invocab_clean_cand": 2600,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 98.46153846153847,
+ "acc_cand_pct": 98.46153846153847,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 42,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a58d536c9af78bbf8451905f7c68222576dfc096bfd3b52f300d992b5a9240b4"
+ },
+ "fc2": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2544,
+ "n_invocab_clean_cand": 2544,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 8.254716981132075,
+ "acc_cand_pct": 7.822327044025157,
+ "delta_pct": -0.432389937106918,
+ "b_ref_only": 21,
+ "c_cand_only": 10,
+ "mcnemar_p": 0.07075554598122835,
+ "boot_ci95_delta_pct": [
+ -0.9094586196631579,
+ 0.038699690402476804
+ ],
+ "boot_p": 0.0808,
+ "n_blocks": 37,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ },
+ "fresh_en": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2847,
+ "n_invocab_clean_cand": 2847,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 1.2293642430628733,
+ "acc_cand_pct": 1.053740779768177,
+ "delta_pct": -0.17562346329469625,
+ "b_ref_only": 11,
+ "c_cand_only": 6,
+ "mcnemar_p": 0.332305908203125,
+ "boot_ci95_delta_pct": [
+ -0.49191848208011235,
+ 0.10463899546564348
+ ],
+ "boot_p": 0.2912,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ },
+ "fresh_fr": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 1557,
+ "n_invocab_clean_cand": 1557,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 30,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ },
+ "test20k": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2801,
+ "n_invocab_clean_cand": 2801,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.8211353088182792,
+ "acc_cand_pct": 0.7854337736522671,
+ "delta_pct": -0.035701535166012155,
+ "b_ref_only": 6,
+ "c_cand_only": 5,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -0.28198801550934083,
+ 0.2164521692670375
+ ],
+ "boot_p": 0.8708,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 17883
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 2.576304133253307,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 95.88523432828516,
+ "ci95": [
+ 95.17631636781792,
+ 96.55817642997651
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 2.4153753993614004,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 96.04616306217707,
+ "ci95": [
+ 95.35077178999046,
+ 96.71769863177818
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": 0.16092873389190743,
+ "ci95": [
+ 0.008778902411852845,
+ 0.3162619288237518
+ ],
+ "ci95_boot_positions_seed25": [
+ 0.020879195458747193,
+ 0.3051967816879966
+ ],
+ "fresh_mean_diff_pct": -0.16092873389190654,
+ "fresh_mean_diff_ci95": [
+ -0.31626192882374865,
+ -0.008778902411853003
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "note": "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu",
+ "flag_gap_not_down_and_fresh_not_up": true,
+ "flag_def": "écart ne baisse pas = IC95 bloc de (écart cand − écart réf) ne passe pas entièrement sous 0 ; frais ne monte pas = IC95 bloc de (moyenne fraîche cand − réf) ne passe pas entièrement au-dessus de 0"
+ },
+ "AH1_for_comparison": {
+ "decision": "REJETÉ",
+ "per_window": {
+ "seen": {
+ "acc_cand_pct": 98.46153846153847,
+ "acc_ref_pct": 98.46153846153847,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ]
+ },
+ "fc2": {
+ "acc_cand_pct": 7.70440251572327,
+ "acc_ref_pct": 8.254716981132075,
+ "delta_pct": -0.550314465408805,
+ "b_ref_only": 24,
+ "c_cand_only": 10,
+ "mcnemar_p": 0.024306510109454393,
+ "boot_ci95_delta_pct": [
+ -1.1080551822495261,
+ -0.03875856449594405
+ ]
+ },
+ "fresh_en": {
+ "acc_cand_pct": 1.1239901650860555,
+ "acc_ref_pct": 1.2293642430628733,
+ "delta_pct": -0.10537407797681775,
+ "b_ref_only": 11,
+ "c_cand_only": 8,
+ "mcnemar_p": 0.6476058959960938,
+ "boot_ci95_delta_pct": [
+ -0.416815013513543,
+ 0.17800087275434376
+ ]
+ },
+ "fresh_fr": {
+ "acc_cand_pct": 0.0,
+ "acc_ref_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ]
+ },
+ "test20k": {
+ "acc_cand_pct": 0.7497322384862549,
+ "acc_ref_pct": 0.8211353088182792,
+ "delta_pct": -0.07140307033202431,
+ "b_ref_only": 4,
+ "c_cand_only": 2,
+ "mcnemar_p": 0.6875,
+ "boot_ci95_delta_pct": [
+ -0.24673951357067336,
+ 0.10556039405894535
+ ]
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 2.576304133253307,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 95.88523432828516,
+ "ci95": [
+ 95.17631636781792,
+ 96.55817642997651
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 2.394531229823895,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 96.06700723171457,
+ "ci95": [
+ 95.40164839357195,
+ 96.71787864908593
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": 0.18177290342940466,
+ "ci95": [
+ 0.024249240736329017,
+ 0.34262003170707644
+ ],
+ "ci95_boot_positions_seed25": [
+ 0.03944741090992139,
+ 0.326473583105809
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "note": "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+ },
+ "verdict_AH1_json_sha256": "3b7b980184c06834a2b74b737c1ff99a6e87fff435294e4c257fcca6b397d483",
+ "hf_commit": "72bf585e62e95b9f8906c1ba6a2d64889e645e04"
+ },
+ "script_sha256": "6fbb18769754f8bd875dcc4f99bfb5ff5dae68045ec6d4a431e53f15f5fb2a17",
+ "inputs_sha256": {
+ "ref__seen.npz": "a508542b6c6d1f4aafcb3c94fed843be7b4d5f4d136aeefca81cdee31d62eac8",
+ "ref__fc2.npz": "73ac8b9f777a42e223852450ef3c795122651893358407d53632f277f41f6003",
+ "ref__fresh_en.npz": "e2563d51b3677e4521e579c7e95afde18924ba8a7cee05c24f8ced0976b7817e",
+ "ref__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "ref__test20k.npz": "3c304dcbb48c6907b519fd42cf95bd817f52343dc588d478aa4273292d99fd4d",
+ "AH2__seen.npz": "fd8e860815ed298dc6da1df1b51f1554f3c93e19f5750e3099822323cbbab8d8",
+ "AH2__fc2.npz": "14c0935cca6715734237030cf92accc5886c4f4afb5aa0da9fd5437ad16ec8da",
+ "AH2__fresh_en.npz": "e83a5ddb3bc7652a0021a3ca1d150f0614bf7a0aa23196fb221cf79df47e776e",
+ "AH2__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "AH2__test20k.npz": "ba2acd5e2b0ace7a90efe48079e814bbab7275b0b85fa80e2eb1c9ab786470c8"
+ },
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/lever2/verdict_AH2/verdict_AH2.md b/results/hashing/lever2/verdict_AH2/verdict_AH2.md
new file mode 100644
index 0000000000000000000000000000000000000000..b47a11ba3f49977458653c48b0ea708d54005c01
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/verdict_AH2.md
@@ -0,0 +1,36 @@
+# Verdict levier 2 — AH2 (anti-hebbien Földiák, eta_ah = 1e-2) contre ref (eta_ah = 0, budget égal), old_local_v1 court
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche
+
+Précision fused sur les cibles invocab (%), 4000 positions par fenêtre, appariement par position.
+
+| fenêtre | n apparié | AH2 % | réf % | Δ pts | b (réf seule) / c (AH2 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 4000 | 98.462 | 98.462 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fc2 | 4000 | 7.822 | 8.255 | -0.432 | 21/10 | 0.0708 | [-0.909 ; +0.039] | n.s. |
+| fresh_en | 4000 | 1.054 | 1.229 | -0.176 | 11/6 | 0.332 | [-0.492 ; +0.105] | n.s. |
+| fresh_fr | 4000 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test20k strict (old_local_v1/test.bin, union old ∪ broad) | 4000 | 0.785 | 0.821 | -0.036 | 6/5 | 1 | [-0.282 ; +0.216] | n.s. |
+| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+
+test20k strict : 0 positions exclues sur 4000 (0 par old_local_v1, 0 par broad_local_v1), octets évalués jusqu'à 17883.
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k ; test_v3 non mesuré) : AH2 +96.046 pts [IC95 +95.351 ; +96.718] (fraîche 2.415 %) ; réf +95.885 pts [+95.176 ; +96.558] (fraîche 2.576 %) ; différence AH2 − réf +0.161 [blocs 512 o seed 0 : +0.009 ; +0.316] [positions seed 25 : +0.021 ; +0.305].
+
+Script sha256 6fbb18769754f8bd875dcc4f99bfb5ff5dae68045ec6d4a431e53f15f5fb2a17 ; masque sha256 50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178.
+
+Moyenne fraîche AH2 − réf : -0.161 pts [IC95 blocs -0.316 ; -0.009]. **DRAPEAU : l'écart ne baisse pas et le frais ne monte pas.**
+
+## Rappel AH1 (eta_ah = 1e-3, verdict_AH1.json, commit 72bf585e) — même réf
+
+| fenêtre | AH1 % | réf % | Δ pts | b/c | p McNemar | IC95 Δ |
+|---|---|---|---|---|---|---|
+| seen | 98.462 | 98.462 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] |
+| fc2 | 7.704 | 8.255 | -0.550 | 24/10 | 0.0243 | [-1.108 ; -0.039] |
+| fresh_en | 1.124 | 1.229 | -0.105 | 11/8 | 0.648 | [-0.417 ; +0.178] |
+| fresh_fr | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] |
+| test20k | 0.750 | 0.821 | -0.071 | 4/2 | 0.688 | [-0.247 ; +0.106] |
+
+Écart AH1 +96.067 [+95.402 ; +96.718] ; AH1 − réf +0.182 [+0.024 ; +0.343] ; verdict AH1 REJETÉ.
+
diff --git a/results/hashing/lever2/verdict_AH2/verdict_AH2.py b/results/hashing/lever2/verdict_AH2/verdict_AH2.py
new file mode 100644
index 0000000000000000000000000000000000000000..5a12e79db80793f2a14d611ffd9935805ba5a0d2
--- /dev/null
+++ b/results/hashing/lever2/verdict_AH2/verdict_AH2.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict levier 2 AH2 (eta_ah=1e-2) contre le témoin à budget égal ref (eta_ah=0), méthode banc v4.1
+(copie adaptée de m7_v41/strict/verdict_m7_v41_strict.py ; lecture seule des hits short_old/{ref,AH2}__*.npz, aucun modèle chargé).
+Fenêtres MESURÉES par run_l2.py (4000 positions chacune) : seen (= old_local_v1/train[:200000]), fc2, fresh_en, fresh_fr, test20k
+(= old_local_v1/test.bin, sha ce0526c6…, PAS broad_local_v1/test.bin ; masque strict propre recalculé : verdict_AH2/mask_oldtest_strict.npz (copie identique de verdict_AH1/, sha 50fa08f9…),
+union old_local_v1 ∪ broad_local_v1). queries et test_v3 : NON évalués par les bras → absents (non mesurables). neither_code exclu.
+hit = fused_hit & invocab. Appariement par position si tgt_start et tgt_len identiques (vérifié). McNemar exact bilatéral = DÉCISION (p<0,05).
+Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un générateur seed 0, fenêtres dans l'ordre WIN, apparié ; stat = acc invocab.
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k strict ; test_v3 non mesuré). Bootstrap secondaire par positions, seed 25.
+Critère utilisateur : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche ET aucune perte significative sur une fenêtre valide ; sinon REJETÉ."""
+import sys, json, math, hashlib, numpy as np
+D = "/workspace/spira_shared/hashing_gen/lever2/short_old"; RT, CT = "ref", "AH2"; OP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH2"
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k"]; GAPW = FRESH
+NOT_MEASURED = ["queries", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+MS = np.load(f"{OP}/mask_oldtest_strict.npz")
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{D}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_union": int((bo | bb_).sum()),
+ "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum())
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k])); p = binp(b, c)
+ ia, ib = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k
+ acc_a, acc_b = 100 * (ha & k).sum() / ia.sum(), 100 * (hb & k).sum() / ib.sum()
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], A["invocab"].astype(bool)[k], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], B["invocab"].astype(bool)[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, A["invocab"].astype(bool))
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "n_invocab_clean_ref": int(ia.sum()), "n_invocab_clean_cand": int(ib.sum()), "invocab_identical": inv_same,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)", "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"])}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+R2 = np.random.default_rng(25); BP = {}
+for w in WIN:
+ k, ha_, hb_, iv_ = KEEP[w]; m_ = k & iv_; r_ = ha_[m_].astype(np.float64); c_ = hb_[m_].astype(np.float64); n_ = len(r_); ar = np.empty(NB); ac = np.empty(NB)
+ for t in range(NB):
+ i = R2.integers(0, n_, n_); ar[t] = r_[i].mean(); ac[t] = c_[i].mean()
+ BP[w] = (100 * ar, 100 * ac)
+dgp = (BP["seen"][1] - np.mean([BP[w][1] for w in GAPW], axis=0)) - (BP["seen"][0] - np.mean([BP[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"]["ci95_boot_positions_seed25"] = [float(x) for x in np.percentile(dgp, [2.5, 97.5])]
+gap["windows"] = GAPW; gap["note"] = "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+# --- ajout AH2 : drapeau « l'écart ne baisse pas ET le frais ne monte pas » + rappel AH1 (lu dans verdict_AH1.json, poussé 72bf585e) ---
+fm_d = gap["cand"]["fresh_mean_pct"] - gap["ref"]["fresh_mean_pct"]
+fmb = np.mean([BOOT[w][1] for w in GAPW], axis=0) - np.mean([BOOT[w][0] for w in GAPW], axis=0)
+gap["cand_minus_ref"]["fresh_mean_diff_pct"] = float(fm_d); gap["cand_minus_ref"]["fresh_mean_diff_ci95"] = [float(x) for x in np.nanpercentile(fmb, [2.5, 97.5])]
+gap_drops = gap["cand_minus_ref"]["ci95"][1] < 0; fresh_rises = gap["cand_minus_ref"]["fresh_mean_diff_ci95"][0] > 0
+FLAG = bool(not gap_drops and not fresh_rises)
+gap["flag_gap_not_down_and_fresh_not_up"] = FLAG
+gap["flag_def"] = "écart ne baisse pas = IC95 bloc de (écart cand − écart réf) ne passe pas entièrement sous 0 ; frais ne monte pas = IC95 bloc de (moyenne fraîche cand − réf) ne passe pas entièrement au-dessus de 0"
+AH1J = json.load(open("/workspace/spira_shared/hashing_gen/lever2/verdict_AH1.json"))
+AH1 = {"decision": AH1J["decision"], "per_window": {w: {k: AH1J["per_window"][w][k] for k in ("acc_cand_pct", "acc_ref_pct", "delta_pct", "b_ref_only", "c_cand_only", "mcnemar_p", "boot_ci95_delta_pct")} for w in WIN},
+ "seen_fresh_gap": AH1J["seen_fresh_gap"], "verdict_AH1_json_sha256": hashlib.sha256(open("/workspace/spira_shared/hashing_gen/lever2/verdict_AH1.json", "rb").read()).hexdigest(), "hf_commit": "72bf585e62e95b9f8906c1ba6a2d64889e645e04"}
+for w in WIN: assert abs(AH1J["per_window"][w]["acc_ref_pct"] - R[w]["acc_ref_pct"]) < 1e-9, f"{w}: réf différente de celle du verdict AH1"
+out = {"cand": "AH2 (eta_ah=1e-2, rho=0.1, Q in [0,0.5], figé en éval)", "ref": "ref (eta_ah=0, budget égal)", "corpus": "broad/old_local_v1", "snn_tokens": 24000, "epochs": 2, "max_positions": 4000,
+ "windows_measured": WIN, "windows_not_measured": NOT_MEASURED, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap, "AH1_for_comparison": AH1,
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN},
+ "mask_sha256": hashlib.sha256(open(f"{OP}/mask_oldtest_strict.npz", "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}/verdict_AH2.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict levier 2 — AH2 (anti-hebbien Földiák, eta_ah = 1e-2) contre ref (eta_ah = 0, budget égal), old_local_v1 court\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused sur les cibles invocab (%), 4000 positions par fenêtre, appariement par position.", "",
+ "| fenêtre | n apparié | AH2 % | réf % | Δ pts | b (réf seule) / c (AH2 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ nm = "test20k strict (old_local_v1/test.bin, union old ∪ broad)" if w == "test20k" else w
+ md.append(f"| {nm} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "",
+ f"test20k strict : {EX['excluded_union']} positions exclues sur 4000 ({EX['excluded_by_old_local_v1']} par old_local_v1, {EX['excluded_by_broad_local_v1']} par broad_local_v1), octets évalués jusqu'à {EX['max_byte_evaluated']}.", "",
+ f"Écart seen − moyenne fraîche ({', '.join(GAPW)} ; test_v3 non mesuré) : AH2 {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence AH2 − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [blocs 512 o seed 0 : {gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}] [positions seed 25 : {gap['cand_minus_ref']['ci95_boot_positions_seed25'][0]:+.3f} ; {gap['cand_minus_ref']['ci95_boot_positions_seed25'][1]:+.3f}].", "",
+ f"Script sha256 {out['script_sha256']} ; masque sha256 {out['mask_sha256']}.", ""]
+md += [f"Moyenne fraîche AH2 − réf : {fm_d:+.3f} pts [IC95 blocs {gap['cand_minus_ref']['fresh_mean_diff_ci95'][0]:+.3f} ; {gap['cand_minus_ref']['fresh_mean_diff_ci95'][1]:+.3f}]. "
+ + ("**DRAPEAU : l'écart ne baisse pas et le frais ne monte pas.**" if FLAG else ("L'écart baisse significativement." if gap_drops else "") + (" Le frais monte significativement." if fresh_rises else "")), "",
+ "## Rappel AH1 (eta_ah = 1e-3, verdict_AH1.json, commit 72bf585e) — même réf", "", "| fenêtre | AH1 % | réf % | Δ pts | b/c | p McNemar | IC95 Δ |", "|---|---|---|---|---|---|---|"]
+for w in WIN:
+ a = AH1["per_window"][w]; md.append(f"| {w} | {a['acc_cand_pct']:.3f} | {a['acc_ref_pct']:.3f} | {a['delta_pct']:+.3f} | {a['b_ref_only']}/{a['c_cand_only']} | {a['mcnemar_p']:.3g} | [{a['boot_ci95_delta_pct'][0]:+.3f} ; {a['boot_ci95_delta_pct'][1]:+.3f}] |")
+g1 = AH1["seen_fresh_gap"]
+md += ["", f"Écart AH1 {g1['cand']['gap_pct']:+.3f} [{g1['cand']['ci95'][0]:+.3f} ; {g1['cand']['ci95'][1]:+.3f}] ; AH1 − réf {g1['cand_minus_ref']['gap_diff_pct']:+.3f} [{g1['cand_minus_ref']['ci95'][0]:+.3f} ; {g1['cand_minus_ref']['ci95'][1]:+.3f}] ; verdict AH1 {AH1['decision']}.", ""]
+open(f"{OP}/verdict_AH2.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/lever2_sparse/STATUS b/results/hashing/lever2_sparse/STATUS
new file mode 100644
index 0000000000000000000000000000000000000000..8fb06e15a8aaf0a6bbfa62dc5d844ffb938f021e
--- /dev/null
+++ b/results/hashing/lever2_sparse/STATUS
@@ -0,0 +1,69 @@
+2026-10-24 02:57:38 EDT | smoke PASS (smoke/smoke_sp.json) ; ATTENTION pic RSS du smoke 4028 Mo (deepcopy de 4 cœurs), au-delà de l'estimation
+2026-10-24 02:57:38 EDT | smoke PASS ; chaîne armée (PID 1049321), attente porte pour SP1
+2026-10-24 02:57:38 EDT | SP1 attente porte : mem 5.34 Go, lourds 6 (348162 405144 437490 537926 838852 1036049 )
+2026-10-24 03:08:39 EDT | SP1 attente porte : mem 4.01 Go, lourds 6 (348162 405144 437490 537926 838852 1036049 )
+2026-10-24 03:29:38 EDT | SP1 attente porte : mem 5.11 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 03:31:38 EDT | SP1 attente porte : mem 3.83 Go, lourds 6 (348162 405144 437490 537926 838852 1087695 )
+2026-10-24 03:47:38 EDT | SP1 attente porte : mem 5.73 Go, lourds 6 (348162 405144 437490 537926 838852 1087695 )
+2026-10-24 03:57:38 EDT | SP1 attente porte : mem 5.19 Go, lourds 6 (348162 405144 437490 537926 838852 1087695 )
+2026-10-24 03:59:38 EDT | SP1 attente porte : mem 5.85 Go, lourds 6 (348162 405144 437490 537926 838852 1087695 )
+2026-10-24 04:07:39 EDT | SP1 attente porte : mem 4.06 Go, lourds 6 (348162 405144 437490 537926 838852 1087695 )
+2026-10-24 04:21:39 EDT | SP1 attente porte : mem 4.71 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 04:23:39 EDT | SP1 attente porte : mem 5.41 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 04:25:39 EDT | SP1 attente porte : mem 4.05 Go, lourds 6 (348162 405144 437490 537926 838852 1142390 )
+2026-10-24 04:48:09 EDT | SP1 attente porte : mem 6.20 Go, lourds 6 (348162 405144 437490 537926 838852 1147860 )
+2026-10-24 04:52:09 EDT | SP1 attente porte : mem 5.52 Go, lourds 7 (348162 405144 437490 537926 838852 1147860 1158749 )
+2026-10-24 04:58:09 EDT | SP1 attente porte : mem 5.58 Go, lourds 6 (348162 405144 437490 537926 838852 1147860 )
+2026-10-24 05:02:09 EDT | SP1 attente porte : mem 5.53 Go, lourds 7 (348162 405144 437490 537926 838852 1147860 1164653 )
+2026-10-24 05:04:09 EDT | SP1 attente porte : mem 6.22 Go, lourds 6 (348162 405144 437490 537926 838852 1147860 )
+2026-10-24 05:08:10 EDT | SP1 attente porte : mem 4.68 Go, lourds 6 (348162 405144 437490 537926 838852 1147860 )
+2026-10-24 05:20:10 EDT | SP1 attente porte : mem 4.60 Go, lourds 7 (348162 405144 437490 537926 838852 1147860 1201801 )
+2026-10-24 05:22:10 EDT | SP1 attente porte : mem 4.88 Go, lourds 6 (348162 405144 437490 537926 838852 1147860 )
+2026-10-24 05:40:10 EDT | SP1 attente porte : mem 5.56 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 05:42:10 EDT | SP1 attente porte : mem 5.08 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 05:44:10 EDT | SP1 attente porte : mem 5.42 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 05:46:10 EDT | SP1 attente porte : mem 4.32 Go, lourds 6 (348162 405144 437490 537926 838852 1218811 )
+2026-10-24 05:52:11 EDT | SP1 attente porte : mem 6.12 Go, lourds 6 (348162 405144 437490 537926 838852 1218811 )
+2026-10-24 05:56:11 EDT | SP1 attente porte : mem 6.72 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 06:12:11 EDT | SP1 attente porte : mem 5.00 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 06:14:11 EDT | SP1 attente porte : mem 5.58 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 06:16:11 EDT | SP1 attente porte : mem 5.14 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 06:18:11 EDT | SP1 attente porte : mem 5.48 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 06:20:11 EDT | SP1 attente porte : mem 4.62 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 06:22:11 EDT | SP1 attente porte : mem 5.33 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 06:28:11 EDT | SP1 attente porte : mem 4.79 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 06:30:11 EDT | SP1 attente porte : mem 5.23 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 06:32:37 EDT | SP1 attente porte : mem 5.07 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 06:48:38 EDT | SP1 attente porte : mem 6.58 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 07:08:38 EDT | SP1 attente porte : mem 5.03 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 07:10:38 EDT | SP1 attente porte : mem 5.50 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 07:12:38 EDT | SP1 attente porte : mem 5.16 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 07:16:39 EDT | SP1 attente porte : mem 5.46 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 07:20:39 EDT | SP1 attente porte : mem 5.09 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 07:28:55 EDT | SP1 attente porte : mem 5.36 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 07:32:55 EDT | SP1 attente porte : mem 4.81 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 07:36:56 EDT | SP1 attente porte : mem 5.57 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 07:52:56 EDT | SP1 attente porte : mem 6.45 Go, lourds 6 (348162 405144 437490 537926 838852 1336481 )
+2026-10-24 07:54:56 EDT | SP1 attente porte : mem 6.82 Go, lourds 5 (348162 405144 437490 537926 838852 )
+2026-10-24 08:10:56 EDT | SP1 attente porte : mem 7.38 Go, lourds 4 (348162 405144 437490 838852 )
+2026-10-24 08:18:56 EDT | SP1 attente porte : mem 5.21 Go, lourds 5 (348162 405144 437490 838852 1370050 )
+2026-10-24 08:20:57 EDT | SP1 attente porte : mem 5.19 Go, lourds 5 (348162 405144 437490 838852 1370050 )
+2026-10-24 08:26:57 EDT | SP1 attente porte : mem 5.26 Go, lourds 5 (348162 405144 437490 838852 1370050 )
+2026-10-24 08:29:57 EDT | SP1 attente porte : mem 4.56 Go, lourds 5 (348162 405144 437490 838852 1370050 )
+2026-10-24 08:39:57 EDT | SP1 attente porte : mem 5.34 Go, lourds 5 (348162 405144 437490 838852 1370050 )
+2026-10-24 08:43:57 EDT | SP1 attente porte : mem 4.98 Go, lourds 5 (348162 405144 437490 838852 1370050 )
+2026-10-24 08:45:57 EDT | SP1 attente porte : mem 5.29 Go, lourds 5 (348162 405144 437490 838852 1370050 )
+2026-10-24 08:47:57 EDT | SP1 attente porte : mem 4.95 Go, lourds 5 (348162 405144 437490 838852 1370050 )
+2026-10-24 08:51:58 EDT | SP1 attente porte : mem 5.83 Go, lourds 5 (348162 405144 437490 838852 1370050 )
+2026-10-24 09:15:58 EDT | SP1 attente porte : mem 4.62 Go, lourds 5 (348162 405144 437490 838852 1410616 )
+2026-10-24 09:17:58 EDT | SP1 attente porte : mem 6.26 Go, lourds 4 (348162 405144 437490 838852 )
+2026-10-24 09:58:42 EDT | r2 (reprise après redémarrage) : chaîne_sp_r2 armée (PID 15288), porte >= 5,75e9 o et lourds < 4, chien de garde 4,4 Gio
+2026-10-24 09:58:42 EDT | SP1 lancé (r2) PID 15295 (mem 14.09 Go, lourds avant lancement 0 : )
+2026-10-24 10:43:51 EDT | SP1 r2 : min MemAvailable 6280757248 o, max VmRSS 900252 kB
+2026-10-24 10:43:51 EDT | SP1 fini, DONE=1
+2026-10-24 10:43:52 EDT | verdict SP1 rc=0 (verdict_SP.py sha256 7a6d54145fdabd726d16d0c0f651d5509b561ac82b0b49d1ea1bbf858d9a2deb) : **REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche; perte(s) significative(s) : fresh_en
+2026-10-24 10:43:52 EDT | SP2 lancé (r2) PID 90522 (mem 7.35 Go, lourds avant lancement 3 : 15242 15953 16884 )
+2026-10-24 11:29:25 EDT | SP2 r2 : min MemAvailable 6157307904 o, max VmRSS 899320 kB
+2026-10-24 11:29:25 EDT | SP2 fini, DONE=1
+2026-10-24 11:29:27 EDT | verdict SP2 rc=0 (verdict_SP.py sha256 7a6d54145fdabd726d16d0c0f651d5509b561ac82b0b49d1ea1bbf858d9a2deb) : **REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche; perte(s) significative(s) : fc2
+2026-10-24 11:29:27 EDT | chaîne SP r2 terminée ; relais NON écrit automatiquement
diff --git a/results/hashing/lever2_sparse/code/REPO_COMMIT b/results/hashing/lever2_sparse/code/REPO_COMMIT
new file mode 100644
index 0000000000000000000000000000000000000000..baf4e912b97bf6eda69543bd279099001de16461
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/REPO_COMMIT
@@ -0,0 +1 @@
+6923c5191049ee488d9418c7002f108abd9e8ea1
diff --git a/results/hashing/lever2_sparse/code/antihebb.py b/results/hashing/lever2_sparse/code/antihebb.py
new file mode 100644
index 0000000000000000000000000000000000000000..273ac20db855dd47570b63740b70a1b6060611c1
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/antihebb.py
@@ -0,0 +1,52 @@
+"""Lever 2 — local anti-Hebbian lateral decorrelation of fast reservoir traces (Foldiak 1990 style).
+No gradient, no global loss. Per tick, with y = bank-0 (fast) trace AFTER the step (y_prev = before):
+ lateral current I_j -= sum_i Q_ij * y_prev_i (Q >= 0, diag 0: learned inhibition)
+ local update Q_ij += eta_ah * (y_i * y_j - rho^2) (i != j), clip Q to [0, q_max]
+Q learns only during training (train_pass), frozen at eval/calibration. eta_ah=0 => exactly the reference step."""
+import numpy as np
+def install(core, eta_ah, rho=0.1, q_max=0.5):
+ core.eta_ah, core.rho2, core.q_max = np.float32(eta_ah), np.float32(rho*rho), np.float32(q_max)
+ core.Q = np.zeros((core.n_res, core.n_res), np.float32); core.ah_learn = False
+ orig_train_pass = core.train_pass
+ def train_pass(*a, **k):
+ core.ah_learn = True
+ try: return orig_train_pass(*a, **k)
+ finally: core.ah_learn = False
+ core.train_pass = train_pass
+ def step(input_idx):
+ self = core
+ I = self.W_in[input_idx].sum(axis=0, dtype=np.float32)
+ I += self.s @ self.W_rec
+ if self.eta_ah > 0: I -= self._banks[0] @ self.Q # lateral anti-Hebbian inhibition
+ v = self.lam * self.v + I
+ can = self.refr == 0
+ v[~can] = 0.0
+ spikes = (v >= self.thr) & can
+ v[spikes] = 0.0
+ np.subtract(self.refr, 1, out=self.refr, where=self.refr > 0)
+ self.refr[spikes] = self.refrac
+ self.v = v
+ self.s = spikes.astype(np.float32)
+ self.rhat += 0.02 * (self.s - self.rhat)
+ self.thr += self.eta_homeo * (self.rhat - self.target_rate)
+ np.clip(self.thr, self.thr_min, self.thr_max, out=self.thr)
+ self.x_prev = self._banks[0].copy()
+ for i, tau in enumerate(self.trace_taus):
+ if i == 0: self._banks[i] = tau * self._banks[i] + self.s
+ else: self._banks[i] = tau * self._banks[i] + (1.0 - tau) * self.s
+ if self.eta_ah > 0 and self.ah_learn:
+ y = self._banks[0]
+ self.Q += self.eta_ah * (np.outer(y, y) - self.rho2)
+ np.fill_diagonal(self.Q, 0.0); np.clip(self.Q, 0.0, self.q_max, out=self.Q)
+ if self.direct_input:
+ self._direct *= np.float32(self.direct_tau)
+ np.add.at(self._direct, input_idx, np.float32(self.direct_gain))
+ self.x = np.concatenate([*self._banks, self._direct])
+ elif self.n_banks > 1: self.x = np.concatenate([*self._banks])
+ else: self.x = self._banks[0]
+ self.x_mean = 0.999 * self.x_mean + 0.001 * self.x
+ self.x_eff = self.x - self.x_mean
+ self.tick += 1
+ if self.hier: self.win_spikes += self.s
+ return self.x
+ core.step = step
diff --git a/results/hashing/lever2_sparse/code/chain_sp_r2.sh b/results/hashing/lever2_sparse/code/chain_sp_r2.sh
new file mode 100644
index 0000000000000000000000000000000000000000..a4fef6e907563dd09e57ac41056648c9e7dac592
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/chain_sp_r2.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# lever2_sparse — chaîne SP1 puis SP2, REPRISE r2 après le redémarrage du box (~09 h 40 Toronto, 24 oct.). Copie de chain_sp.sh (inchangé) avec :
+# - pas d'attente de smoke (smoke déjà PASS, smoke/smoke_sp.json re-vérifié) ;
+# - porte MemAvailable >= 5,75e9 o (= 4,4 Gio chien de garde 4,724e9 + pic bras ~1,0 Go ; témoin mesuré 0,88 Go) ET lourds < 4 (python RSS >= 300 Mo, tous agents) ;
+# - chien de garde 2 s : MemAvailable < 4,4 Gio (4724464025 o) -> SIGTERM puis SIGKILL au SEUL groupe de process du bras (setsid) ;
+# - sha256 de verdict_SP.py consigné à chaque verdict. Sorties identiques à chain_sp.sh (aucune n'existait : SP1 jamais lancé).
+# N'écrit JAMAIS dans spira_relay.md, ne tue/signale rien d'autre, rien dans /tmp.
+B=/workspace/spira_shared/hashing_gen/lever2_sparse; C=$B/code; ST=$B/STATUS; PY=/workspace/SPIRA-venv/bin/python
+MEMGO=5750000000; WD=4724464025
+ts(){ TZ=America/Toronto date '+%F %T %Z'; }
+memb(){ awk '/MemAvailable/{printf "%d", $2*1024}' /proc/meminfo; }
+heavy(){ ps -eo rss=,comm= | awk '$1>=300000 && $2 ~ /python/ {n++} END{print n+0}'; }
+heavy_list(){ ps -eo pid=,rss=,comm= | awk '$2>=300000 && $3 ~ /python/ {printf "%s ", $1}'; }
+export OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0 PYTHONDONTWRITEBYTECODE=1
+echo $$ > $B/chain_r2.pid
+if ! $PY -c "import json,sys; sys.exit(0 if json.load(open('$B/smoke/smoke_sp.json'))['PASS'] else 1)" 2>/dev/null; then
+ echo "$(ts) | r2 : smoke NON PASS ou absent : chaîne ARRÊTÉE" >> $ST; exit 2; fi
+echo "$(ts) | r2 (reprise après redémarrage) : chaîne_sp_r2 armée (PID $$), porte >= 5,75e9 o et lourds < 4, chien de garde 4,4 Gio" >> $ST
+for spec in "SP1 SP1" "SP2 SP2"; do set -- $spec; ARM=$1; MODE=$2; last=""
+ [ -e $B/short_old.$ARM.log ] && { echo "$(ts) | r2 : short_old.$ARM.log existe déjà, $ARM sauté (pas d'écrasement)" >> $ST; continue; }
+ while :; do m=$(memb); h=$(heavy)
+ if [ "$m" -ge $MEMGO ] && [ "$h" -lt 4 ]; then break; fi
+ s="mem $(awk -v m=$m 'BEGIN{printf "%.2f", m/1e9}') Go, lourds $h ($(heavy_list))"
+ echo "$(ts) $ARM porte fermée (r2) : $s" >> $B/logs/gate.log
+ st="$([ "$m" -ge $MEMGO ] && echo memOK || echo memKO)/$h"; [ "$st" != "$last" ] && echo "$(ts) | $ARM attente porte (r2) : $s" >> $ST; last=$st
+ sleep 120; done
+ setsid nice -n 10 $PY -u $C/run_sp.py $ARM $MODE 24000 4000 $B/short_old > $B/short_old.$ARM.log 2>&1 < /dev/null &
+ P=$!; echo "$(ts) | $ARM lancé (r2) PID $P (mem $(awk -v m=$(memb) 'BEGIN{printf "%.2f", m/1e9}') Go, lourds avant lancement $h : $(heavy_list))" >> $ST
+ echo $P > $B/$ARM.r2.pid; ab=0; minm=999999999999; maxr=0
+ while [ -d /proc/$P ]; do m=$(memb); r=$(awk '/VmRSS/{print $2}' /proc/$P/status 2>/dev/null); r=${r:-0}
+ [ "$m" -lt "$minm" ] && minm=$m; [ "$r" -gt "$maxr" ] && maxr=$r
+ if [ "$m" -lt $WD ]; then ab=1; echo "$(ts) | CHIEN DE GARDE r2 : MemAvailable=$m o < 4,4 Gio -> arrêt du seul bras $ARM (pgid $P)" >> $ST
+ kill -TERM -- -$P 2>/dev/null; sleep 3; kill -KILL -- -$P 2>/dev/null; break; fi
+ sleep 2; done
+ wait $P 2>/dev/null
+ echo "$(ts) | $ARM r2 : min MemAvailable ${minm} o, max VmRSS ${maxr} kB" >> $ST
+ [ $ab = 1 ] && { echo "$(ts) | $ARM ABORT_WATCHDOG (r2) : chaîne arrêtée" >> $ST; exit 4; }
+ n=$(grep -c DONE $B/short_old.$ARM.log); echo "$(ts) | $ARM fini, DONE=$n" >> $ST
+ if [ "$n" = 1 ]; then
+ vs=$(sha256sum $C/verdict_SP.py | cut -c1-64)
+ nice -n 10 $PY $C/verdict_SP.py $ARM > $B/logs/verdict_$ARM.log 2>&1; echo "$(ts) | verdict $ARM rc=$? (verdict_SP.py sha256 $vs) : $(grep -m1 -o '\*\*[A-ZÉ]*\*\*.*' $B/verdict_$ARM/verdict_$ARM.md 2>/dev/null)" >> $ST
+ else echo "$(ts) | $ARM : run incomplet, pas de verdict (voir short_old.$ARM.log)" >> $ST; fi
+done
+echo "$(ts) | chaîne SP r2 terminée ; relais NON écrit automatiquement" >> $ST
diff --git a/results/hashing/lever2_sparse/code/countmin.py b/results/hashing/lever2_sparse/code/countmin.py
new file mode 100644
index 0000000000000000000000000000000000000000..f474312930d572284606aa10f573354d498f946a
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/countmin.py
@@ -0,0 +1,129 @@
+"""RECONSTRUIT, À RE-VÉRIFIER (Hashing, 2026-10-23, après la perte de /tmp).
+Projection sémantique Count-Min MinHash, figée et déterministe, sans backprop.
+- Co-occurrences des colonnes de vocabulaire dans une fenêtre de ±W (W=2), comptées sur le train.
+- PPMI, puis les top-K (K=16) contextes par colonne.
+- d=24 fonctions MinHash sur cet ensemble de contextes -> 24 neurons dans un bloc sémantique
+ de largeur 4096, décalé après les d_in de base (v3 : 1024). Ligne finale = 12 neurones v3 + 24.
+Les choix de mise en page (bloc décalé, d_in total = 1024+4096) sont des HYPOTHÈSES :
+la mise en page de l'original n'est pas connue.
+"""
+from __future__ import annotations
+import json, sys
+import numpy as np
+sys.path.insert(0, "/tmp/spira_hashing_lever2/python")
+from spira import SPIRA, SPIRAConfig
+from spira.hashing import splitmix64
+
+M64 = 0xFFFFFFFFFFFFFFFF
+
+def cooc_ppmi_topk(cols: np.ndarray, V: int, window: int = 2, topk: int = 16) -> np.ndarray:
+ """cols: (T,) vocab cols, V == UNK (masked). Returns (V, topk) int64 context cols, -1 pad."""
+ keys = []
+ for o in range(1, window + 1):
+ a, b = cols[:-o], cols[o:]
+ ok = (a < V) & (b < V)
+ a, b = a[ok], b[ok]
+ keys.append(a * V + b); keys.append(b * V + a)
+ k, c = np.unique(np.concatenate(keys), return_counts=True)
+ w, ctx = k // V, k % V
+ c = c.astype(np.float64)
+ tot = c.sum()
+ rw = np.bincount(w, weights=c, minlength=V); rc = np.bincount(ctx, weights=c, minlength=V)
+ pmi = np.log(c * tot / (rw[w] * rc[ctx]))
+ pp = np.maximum(pmi, 0.0)
+ order = np.lexsort((ctx, -pp, w)) # par mot, PPMI décroissante, départage déterministe
+ w, ctx, pp = w[order], ctx[order], pp[order]
+ out = np.full((V, topk), -1, dtype=np.int64)
+ start = np.searchsorted(w, np.arange(V))
+ end = np.searchsorted(w, np.arange(V), side="right")
+ for v in range(V):
+ s, e = start[v], min(end[v], start[v] + topk)
+ sel = ctx[s:e][pp[s:e] > 0]
+ out[v, :len(sel)] = sel
+ return out
+
+def minhash_rows(top: np.ndarray, d: int = 24, width: int = 4096, offset: int = 1024) -> np.ndarray:
+ """(V, d) neurons in [offset, offset+width). Colonne sans contexte -> -1 (pas de neurone sémantique)."""
+ V = top.shape[0]
+ out = np.full((V, d), -1, dtype=np.int32)
+ for v in range(V):
+ ctx = [int(x) for x in top[v] if x >= 0]
+ if not ctx:
+ continue
+ for j in range(d):
+ salt = (0xC0FFEE ^ (j * 0x9E3779B97F4A7C15)) & M64
+ out[v, j] = offset + int(min(splitmix64((x ^ salt) & M64) for x in ctx) % width)
+ return out
+
+def attach(model: SPIRA, sem: np.ndarray) -> None:
+ """Remplace neuron_rows : ligne v3 (12) + 24 neurones sémantiques (UNK/sans contexte -> repli v3 dupliqué)."""
+ base = model.neuron_rows
+ def rows(ids, patches=None):
+ r = base(ids, patches)
+ cols = model.cols_of(ids)
+ V = model.cfg.vocab_size
+ s = np.where((cols < V)[:, None], sem[np.minimum(cols, V - 1)], -1)
+ s = np.where(s < 0, r[:, :1], s) # repli : neurone v3 déjà actif (pas de nouveau neurone)
+ return np.concatenate([r, s.astype(np.int32)], axis=1)
+ model.neuron_rows = rows
+
+def save_with_calibration(model: SPIRA, path: str, calib_bytes: bytes, n_tokens: int = 3000) -> dict:
+ """calibrate_fusion est appelé AVANT save ; on vérifie ensuite que l'échelle est bien dans le checkpoint."""
+ fus = model.calibrate_fusion(calib_bytes, n_tokens=n_tokens)
+ model.save(path)
+ z = np.load(path, allow_pickle=False)
+ saved = json.loads(str(z["fusion"]))
+ assert abs(saved["scale"] - fus["scale"]) < 1e-12 and saved["sigma_fast"] is not None, saved
+ return saved
+
+
+# ---------------------------------------------------------------------------
+# RECONSTRUIT, À RE-VÉRIFIER — modèle CM qui se recharge seul (correctif 8 h 38)
+import dataclasses
+
+class CMSPIRA(SPIRA):
+ """cfg.d_in / cfg.k_in = tailles TOTALES (base + CM) : le cœur et la config
+ sauvegardée concordent. La table CM et ses paramètres vont dans le ckpt (cm_sem, cm_params)."""
+ def __init__(self, cfg, base_d_in: int = 1024, base_k: int = 12, cm_d: int = 24, cm_width: int = 4096):
+ super().__init__(cfg)
+ self.cm = {"base_d_in": base_d_in, "base_k": base_k, "d": cm_d, "width": cm_width}
+ self.cm_sem = None
+
+ @classmethod
+ def build_cm(cls, data, cfg, window=2, topk=16, base_d_in=1024, base_k=12, d=24, width=4096, log=print):
+ cfg = dataclasses.replace(cfg, d_in=base_d_in + width, k_in=base_k + d)
+ m = cls.build(data, cfg, log=log)
+ m.cm = {"base_d_in": base_d_in, "base_k": base_k, "d": d, "width": width, "window": window, "topk": topk}
+ top = cooc_ppmi_topk(m.cols_of(m._ids_train), cfg.vocab_size, window, topk)
+ m.cm_sem = minhash_rows(top, d, width, base_d_in)
+ m._row_cache = {}
+ return m
+
+ def _structured_row(self, pid, pbytes):
+ c, full = self.cm, self.cfg
+ self.cfg = dataclasses.replace(full, d_in=c["base_d_in"], k_in=c["base_k"])
+ try:
+ base = SPIRA._structured_row(self, pid, pbytes)
+ finally:
+ self.cfg = full
+ col = int(self.cols_of(np.array([pid], dtype=np.uint64))[0])
+ s = self.cm_sem[col] if col < full.vocab_size else np.full(c["d"], -1, np.int32)
+ s = np.where(s < 0, base[0], s)
+ return np.concatenate([base, s]).astype(np.int32)
+
+ def save(self, path, am_cap=1_500_000):
+ super().save(path, am_cap)
+ z = dict(np.load(path, allow_pickle=False))
+ z["cm_sem"] = self.cm_sem
+ z["cm_params"] = np.array(json.dumps(self.cm))
+ with open(path, "wb") as f:
+ np.savez_compressed(f, **z)
+
+ @classmethod
+ def load(cls, path):
+ m = super().load.__func__(cls, path)
+ z = np.load(path, allow_pickle=False)
+ m.cm = json.loads(str(z["cm_params"]))
+ m.cm_sem = z["cm_sem"].astype(np.int32)
+ m._row_cache = {}
+ return m
diff --git a/results/hashing/lever2_sparse/code/python/README.md b/results/hashing/lever2_sparse/code/python/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..00577ebff77ece88087fcfd0186f7f05bce04e0a
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/python/README.md
@@ -0,0 +1,186 @@
+# SPIRA — Spiking Plastic Recurrent Architecture
+
+A CPU-only sequence-learning system **outside the transformer/BPE/backpropagation
+paradigm**, built from three components:
+
+| Component | What it replaces |
+|---|---|
+| **EPT** — Entropy-Patch Tokenization | BPE / WordPiece / SentencePiece |
+| **Hierarchical spiking cortex** — LIF reservoir + slow area, reward-modulated plasticity | Transformer + backprop |
+| **Hippocampus** — one-shot associative memory + replay consolidation | Fine-tuning / gradient learning |
+
+This is **v2** of the prototype: a 16,384-column readout (chosen from a measured
+coverage curve), a two-timescale hierarchical cortex (fast 512-neuron reservoir +
+slow 256-neuron area reading the pooled spike volley every 8 tokens), and
+hippocampal replay that consolidates one-shot memories into cortical weights.
+
+## Headline results (2 vCPU, 4 GB RAM, 13.2 MB mixed text+code corpus)
+
+| Proof | Result |
+|---|---|
+| One-shot learning | **99.3%** exact recall after a single 0.4 s pass over an unseen book |
+| **Systems consolidation (v2)** | cortex-only recall of that book **0.3% → 46.9%** (64.2% in-vocab, 138×) after replaying 100k hippocampal tokens — the AM itself stays at 99.3% |
+| Pattern completion | **99.0%** recall with 1 of 4 context patches corrupted (sparse AM); 52.3% in the deployed full AM (46% load) |
+| Replay interference | none — held-out test accuracy *improves* slightly after replay (0.34% → 0.75% cortex-only) |
+| Zero-shot coverage | 6.3% patch novelty on held-out text+code; the 16k readout covers 64% of held-out targets (v1: 38% at 4k) |
+| Efficiency | ≈9.2 M synaptic MACs/token — ≈**81× fewer ops/token** than GPT-2-small training (v1 at 4k vocab: 2.4 M, 314×) |
+| Generation | ≈2,000 chars/s closed-loop on 2 vCPU, in-browser at ~450-700 chars/s |
+| One-shot write rate | 1,199,996 associations in 18 s, with an exact checkpoint round-trip |
+
+Honest negative results (reported in the paper): the cortex does not amortize
+generalization to unseen documents (test in-vocab 0.49% vs a bigram's 7.7%), and
+the slow area's token-level fusion self-discounts to β≈0.06 at this scale — its
+value is as a second consolidation substrate during replay. See
+`../paper/spira_paper.pdf`, Sections 7–8.
+
+## What's new in v3 (cortex representation repair)
+
+Diagnosis probes on the shipped v2 checkpoint showed the held-out weakness was
+representational: the readout state carried ≈1 token of memory (current patch
+decodable at 99.94%, previous patch at 39.7% vs 33.0% majority chance), and an
+offline ridge readout on the same states scored 0.36% — worse than the online
+delta readout (0.51%). v3 changes the readout's *input*, not its learning rule:
+
+- **Direct input pathway** (`direct_input=True`, `direct_tau=0.5`): a decaying
+ trace of the exact input-neuron pattern is concatenated to the readout state,
+ so the delta rule sees the recent input identities directly.
+- **Multi-timescale trace banks** (`trace_taus=(0.4, 0.8, 0.95)`): the reservoir
+ keeps one spike-trace bank per τ; slow banks are normalized by (1 − τ) so the
+ τ=0.95 bank does not swamp the fast one. With the direct pathway, the readout
+ state is `n_state = 512 × 3 + 1024 = 2560` (v2: 512), and `W_out` is
+ `(2560, V+1)`.
+- **Structured inputs** (`structured_inputs=True`, `k_tri=6`): each patch
+ activates 6 full-hash input neurons **plus** 6 byte-trigram hash neurons, so
+ patches sharing byte trigrams share input neurons.
+- **Compatibility mode:** `direct_input=False, trace_taus=(0.4,),
+ structured_inputs=False` reproduces the v2 architecture exactly
+ (`n_state = 512`); v3 checkpoints record the new fields and restore them on
+ `SPIRA.load()`.
+- **Bug fix:** v2's `model.train()` referenced an undefined `ok_mask`
+ (NameError) — training only ever ran through `scripts/train_chunk.py`. Fixed
+ in v3; `SPIRA.train()` now runs standalone.
+
+Controlled A/B (same protocol both arms — rebuilt corpus, vocab 4096, 200k
+tokens × 2 epochs, AM 50k contexts, held-out test 20k positions, coverage
+45.24%): SNN alone, in-vocab — **0.40% (v2) → 2.07% (v3)**, patch bigram @4096
+on the same positions **4.94%**. The beat-the-bigram criterion is **not met**
+(gap ×12.4 → ×2.4); trained region 3.76% → 13.29%. Training costs 189 t/s vs
+~530 t/s and the checkpoint grows 14.6 MB → 45.9 MB. See `../V3_REPORT.md` and
+`artifacts/metrics_v3_ab.json`.
+
+## Repository layout
+
+```
+spira/ Python package (NumPy only, CPU-only)
+ hashing.py FNV-1a-64, splitmix64, mulberry32 — bit-compatible with the TS port
+ ept.py entropy-patch tokenizer (order-1 Markov surprisal, content addressing)
+ spiking.py LIF reservoir + Dale's law + homeostatic thresholds,
+ Rescorla-Wagner readout gated by dopaminergic RPE,
+ reward-modulated recurrent STDP, and the hierarchical
+ slow area G (windowed spike volleys, top-down prior,
+ counterfactual trust gain beta); v3: multi-timescale
+ trace banks + direct input pathway to the readout
+ hippocampus.py one-shot memory: primary full-key hash (pattern separation)
+ + leave-one-out lanes (CA3 pattern completion), exact
+ derivable-slot checkpoint round-trip
+ model.py SPIRA wrapper: build / train / generate / teach / replay /
+ calibrate_fusion / eval / save-load; v3 config:
+ direct_input, trace_taus, direct_tau, structured_inputs,
+ k_tri (defaults reproduce v3; flags off = v2 architecture)
+ baselines.py gzip, byte-level BPE (HuggingFace tokenizers), sparse
+ n-gram predictors
+ train.py training CLI
+ evaluate.py full evaluation harness (coverage curve, compression,
+ prediction + hierarchy ablation, one-shot, REPLAY
+ consolidation experiment, correction, generation) —
+ resumable by section
+ export_deploy.py JSON artifact export for the browser demo (format v2)
+artifacts/ trained checkpoint, metrics.json, deploy artifact,
+ figures, browser-demo screenshots
+paper/ LaTeX source + compiled research paper (spira_paper.pdf)
+```
+
+## Quick start
+
+```bash
+# build the corpus (Gutenberg books + Python stdlib code)
+python3 scripts/build_corpus.py
+
+# chunked training (background processes are killed between calls in sandboxes;
+# each chunk fits a single tool/shell call). v2 defaults: vocab 16384, hierarchy on.
+python3 scripts/train_chunk.py --start 0 --count 150000 # chunk 1 (fresh build)
+python3 scripts/train_chunk.py --start 150000 --count 150000 # ... continue to 600k
+python3 scripts/train_chunk.py --start 0 --count 150000 # epoch 2
+python3 scripts/train_chunk.py --start 450000 --count 150000 --raster # epoch 2 end + raster
+python3 scripts/train_chunk.py --am-only # hippocampal write pass (1.2M)
+python3 scripts/train_chunk.py --start 450000 --warmup 150000 # re-adapt operating point
+
+# full evaluation (resumable: completed sections are skipped on re-run)
+python3 -m spira.evaluate --model artifacts/spira_model.npz \
+ --train data/train.bin --test data/test.bin \
+ --oneshot data/oneshot.bin --out artifacts/metrics.json
+
+# hippocampal replay -> cortical consolidation (in a few lines)
+python3 - << 'EOF'
+import sys; sys.path.insert(0, ".")
+from spira import SPIRA
+m = SPIRA.load("artifacts/spira_model.npz")
+print(m.teach_bytes(open("data/oneshot.bin", "rb").read()[:60000]))
+print("before replay:", m.eval_stream(open("data/oneshot.bin","rb").read()[:60000], use_am=False, max_positions=4000)["hier_acc"])
+print(m.replay(100000)) # the "sleep" pass
+print("after replay:", m.eval_stream(open("data/oneshot.bin","rb").read()[:60000], use_am=False, max_positions=4000)["hier_acc"])
+EOF
+
+# export the browser-demo artifact (format v2, includes the slow area)
+python3 -m spira.export_deploy --model artifacts/spira_model.npz \
+ --out artifacts/spira_deploy.json --am-cap 100000 --am-min-count 1
+```
+
+## Design notes (the interesting parts)
+
+- **Constant-information tokens.** Each EPT patch carries ≈15.9 bits of accumulated
+ surprisal; low-entropy text yields long patches, high-entropy text short ones.
+ Patch identity is the FNV-1a-64 hash of the bytes — the same substring is always
+ the same token, anywhere, with zero vocabulary learning.
+- **The readout rule is local.** Readout units apply a Widrow–Hoff / Rescorla–Wagner
+ delta rule on their own activity, gated by dopamine `d = r − baseline(r)`. No
+ gradients, no chain rule, no autodiff.
+- **Mean-centering the spike trace matters.** The raw trace carries a dense shared
+ background that otherwise makes every column's score correlate with frequency;
+ subtracting a slow EMA of the trace (homeostatic scaling) is what makes per-context
+ learning converge.
+- **Learned state includes the operating point.** Homeostatic thresholds, the trace
+ mean, the slow area's homeostatic scalars, the top-down gain β, and STDP-shaped
+ recurrent weights must be checkpointed together — omitting any of them (or
+ resetting β to its init) silently destroys the readout's regime.
+- **The hierarchy must be variance-matched and counterfactually credited.** The slow
+ readout's raw scores live at ~20× the fast one's scale; fusing raw scores lets a
+ tiny gain swamp the fast argmax, so the prior is rescaled by σ_fast/σ_slow
+ (measured once, like the EPT budget). And a gain rule that rewards the slow area
+ for ranking frequent truths high degenerates into a frequency prior — only
+ saved-vs-corrupted counterfactual attribution calibrates β honestly (it
+ self-discounts to ≈0.06 at this scale).
+- **Hippocampal replay closes the complementary-systems loop.** Teaching retains the
+ episodic token trace; replay re-runs random 512-token slices through the cortex in
+ full training mode, so one-shot material becomes slow cortical weight while the
+ hippocampus stays intact (0.3% → 46.9% cortex-only recall, zero interference —
+ held-out accuracy actually improves slightly).
+- **Associative-memory checkpoints are easy to get subtly wrong.** Entries must be
+ packed and restored at their derivable slots (primary + leave-one-out hashes); an
+ early format that rebuilt entries at lane-value addresses made the reloaded corpus
+ memory invisible to queries — and inflated v1's corruption-robustness number,
+ which had been measured against an accidentally-empty hippocampus.
+- **Hybrid hippocampal addressing.** A primary full-key hash gives every distinct
+ context its own slot (capacity); leave-one-out key hashes let a query with one
+ corrupted lane still reach the entry (completion). Completion strength trades
+ against table load (99% at 0.8% load vs 52% at 46% load); two corrupted lanes is
+ an explicit architectural cliff.
+- **The TS port is compatible.** `web/src/lib/spira/` regenerates the reservoir from
+ the same seeded PRNG (mulberry32), shares the exact hashing spec, ports the slow
+ area (stepG + variance-matched fusion), and loads the same deploy artifact, so
+ browser inference matches the Python prototype. (Replay is Python-only.)
+
+## Citation
+
+See `../paper/spira_paper.pdf` — *SPIRA: Sequence Learning Without Backpropagation or
+GPU Clusters*, preprint, October 2026 (third iteration).
diff --git a/results/hashing/lever2_sparse/code/python/spira/__init__.py b/results/hashing/lever2_sparse/code/python/spira/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..d7f08191017a971fc0a4db7fc973d46beb325d5a
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/python/spira/__init__.py
@@ -0,0 +1,25 @@
+"""SPIRA — Spiking Plastic Recurrent Architecture.
+
+A CPU-only sequence-learning system outside the transformer/BPE paradigm:
+
+ * EPT: entropy-patch tokenization (constant-information quanta,
+ content-addressed, zero vocabulary training);
+ * SpikingCore: LIF reservoir with Dale's law, homeostatic thresholds,
+ reward-modulated STDP (three-factor learning, no backpropagation);
+ * Hippocampus: one-shot associative memory with lane-redundant indexing
+ for episodic recall and pattern completion under corruption.
+"""
+
+__version__ = "0.1.0"
+
+from .ept import EPT
+from .hashing import fnv1a64, splitmix64, lane_key32, input_neurons, Mulberry32
+from .hippocampus import Hippocampus
+from .spiking import SpikingCore
+from .model import SPIRA, SPIRAConfig, PatchRegistry
+
+__all__ = [
+ "EPT", "Hippocampus", "SpikingCore", "SPIRA", "SPIRAConfig",
+ "PatchRegistry", "fnv1a64", "splitmix64", "lane_key32", "input_neurons",
+ "Mulberry32", "__version__",
+]
diff --git a/results/hashing/lever2_sparse/code/python/spira/baselines.py b/results/hashing/lever2_sparse/code/python/spira/baselines.py
new file mode 100644
index 0000000000000000000000000000000000000000..d62af89e6e5662111fc0e361cf53f642397683b5
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/python/spira/baselines.py
@@ -0,0 +1,131 @@
+"""Baselines for comparison against SPIRA.
+
+Compression: gzip -9, HuggingFace byte-level BPE (matched vocabulary sizes).
+Prediction: unigram, patch-bigram with unigram backoff.
+"""
+from __future__ import annotations
+
+import gzip
+import time
+
+import numpy as np
+
+from tokenizers import Tokenizer, models, trainers, pre_tokenizers
+
+
+# ------------------------------------------------------------- compression
+def gzip_bits_per_byte(data: bytes) -> tuple[float, float]:
+ """(bits/byte, seconds) for gzip level 9."""
+ t0 = time.perf_counter()
+ comp = gzip.compress(data, 9)
+ dt = time.perf_counter() - t0
+ return len(comp) * 8 / len(data), dt
+
+
+def bpe_encode(train: bytes, test: bytes, vocab_size: int) -> dict:
+ """Train a byte-level BPE on `train` and encode `test` with it.
+
+ Returns dict(ids, vocab_size, vocab_bytes, train_s, encode_s,
+ MB_per_s_train).
+ """
+ t0 = time.perf_counter()
+ tok = Tokenizer(models.BPE())
+ tok.pre_tokenizer = pre_tokenizers.ByteLevel(add_prefix_space=False)
+ trainer = trainers.BpeTrainer(
+ vocab_size=vocab_size,
+ initial_alphabet=pre_tokenizers.ByteLevel.alphabet(),
+ special_tokens=[],
+ )
+ tok.train_from_iterator([train.decode("utf-8", "replace")], trainer=trainer)
+ train_s = time.perf_counter() - t0
+ t1 = time.perf_counter()
+ enc = tok.encode(test.decode("utf-8", "replace"))
+ encode_s = time.perf_counter() - t1
+ vocab = tok.get_vocab()
+ vocab_bytes = sum(len(s.encode("utf-8")) for s in vocab)
+ return {
+ "ids": np.asarray(enc.ids, dtype=np.int64),
+ "vocab_size": len(vocab),
+ "vocab_bytes": vocab_bytes,
+ "train_s": train_s,
+ "encode_s": encode_s,
+ }
+
+
+def stream_entropy_bits(ids: np.ndarray, order: int = 0) -> float:
+ """Empirical entropy of a token stream in bits/token (order 0 or 1)."""
+ # remap arbitrary ids (e.g. uint64 patch ids) to dense indices
+ uniq, inv = np.unique(ids, return_inverse=True)
+ ids = inv.astype(np.int64)
+ if order == 0:
+ _, cnt = np.unique(ids, return_counts=True)
+ p = cnt / cnt.sum()
+ return float(-(p * np.log2(p)).sum())
+ # order 1: H(next | prev) estimated from the same stream
+ prev = ids[:-1]
+ cur = ids[1:]
+ span = len(uniq)
+ pair = prev * span + cur
+ uniq_pair, cnt_pair = np.unique(pair, return_counts=True)
+ pair_prev = uniq_pair // span
+ prev_ids, cnt_prev = np.unique(prev, return_counts=True)
+ lookup = np.zeros(span, dtype=np.int64)
+ lookup[prev_ids] = cnt_prev
+ denom = lookup[pair_prev].astype(np.float64)
+ p_pair = cnt_pair / denom
+ bits = -(cnt_pair * np.log2(p_pair)).sum()
+ return float(bits / len(cur))
+
+
+def dict_bits(vocab_size: int, vocab_bytes: int, overhead_bits: float = 32.0) -> float:
+ """Decode-dictionary storage: raw token bytes + id/length overhead."""
+ return vocab_bytes * 8 + vocab_size * overhead_bits
+
+
+# ------------------------------------------------------------- prediction
+class UnigramBaseline:
+ def __init__(self, train_cols: np.ndarray, V: int | None = None) -> None:
+ if V is not None:
+ train_cols = train_cols[train_cols != V] # exclude the UNK column
+ self.best = int(np.bincount(train_cols).argmax())
+
+ def accuracy(self, cur: np.ndarray) -> float:
+ return float((cur == self.best).mean())
+
+
+class BigramBaseline:
+ """Patch-bigram predictor with unigram backoff (sparse pair counts).
+
+ Dense (V, V) storage is infeasible at V=16k (1+ GB); pairs are counted
+ via packed int64 keys instead, and the argmax continuation per preceding
+ column is precomputed by a (prev, -count) lexsort.
+ """
+
+ def __init__(self, train_cols: np.ndarray, V: int) -> None:
+ prev = train_cols[:-1]
+ cur = train_cols[1:]
+ ok = (prev != V) & (cur != V) # in-vocab pairs only
+ p = prev[ok].astype(np.int64)
+ c = cur[ok].astype(np.int64)
+ if len(p) == 0:
+ self.map_prev = np.array([-1], dtype=np.int64)
+ self.map_pred = np.array([0], dtype=np.int64)
+ else:
+ key = p * np.int64(V + 1) + c
+ uk, cnt = np.unique(key, return_counts=True) # sorted by key
+ prev_u = (uk // np.int64(V + 1)).astype(np.int64)
+ pred_c = (uk % np.int64(V + 1)).astype(np.int64)
+ order = np.lexsort((-cnt, prev_u)) # prev asc, count desc
+ pu, pc = prev_u[order], pred_c[order]
+ first = np.ones(len(pu), dtype=bool)
+ first[1:] = pu[1:] != pu[:-1]
+ self.map_prev = pu[first]
+ self.map_pred = pc[first]
+ self.uni_best = int(np.bincount(train_cols[train_cols != V]).argmax())
+
+ def accuracy(self, prev: np.ndarray, cur: np.ndarray) -> float:
+ pos = np.searchsorted(self.map_prev, prev)
+ pos_c = np.minimum(pos, len(self.map_prev) - 1)
+ hit = (pos < len(self.map_prev)) & (self.map_prev[pos_c] == prev)
+ pred = np.where(hit, self.map_pred[pos_c], self.uni_best)
+ return float((pred == cur).mean())
diff --git a/results/hashing/lever2_sparse/code/python/spira/ept.py b/results/hashing/lever2_sparse/code/python/spira/ept.py
new file mode 100644
index 0000000000000000000000000000000000000000..bfb44cf00f18787ca6b4567d98c12fdd2b7e5a9f
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/python/spira/ept.py
@@ -0,0 +1,147 @@
+"""EPT — Entropy-Patch Tokenization.
+
+Segments a byte stream into variable-length patches such that each patch
+carries approximately ``budget_bits`` of accumulated surprisal under an
+order-1 byte-level Markov model ("constant-information quanta").
+
+Consequences:
+ * low-entropy regions (repeated keywords, indentation, boilerplate) produce
+ LONG patches, high-entropy regions produce SHORT ones — no merge table,
+ no vocabulary to train;
+ * patches are content-addressed with FNV-1a-64: the same byte substring is
+ always the same token, wherever it occurs, with zero learning;
+ * strictly streaming: one pass, O(n) with tiny state.
+"""
+from __future__ import annotations
+
+import numpy as np
+
+from .hashing import fnv1a64
+
+
+class EPT:
+ def __init__(
+ self,
+ budget_bits: float = 16.0,
+ min_len: int = 2,
+ max_len: int = 32,
+ alpha: float = 0.5,
+ ) -> None:
+ self.budget_bits = float(budget_bits)
+ self.min_len = int(min_len)
+ self.max_len = int(max_len)
+ self.alpha = float(alpha)
+ self.log2p: np.ndarray | None = None # (256, 256) float32
+
+ # ------------------------------------------------------------------ fit
+ def fit(self, data: bytes) -> "EPT":
+ """Estimate the order-1 byte Markov model on training bytes."""
+ arr = np.frombuffer(data, dtype=np.uint8).astype(np.int64)
+ C = np.zeros((256, 256), dtype=np.int64)
+ np.add.at(C, (arr[:-1], arr[1:]), 1)
+ P = (C + self.alpha).astype(np.float64)
+ P /= P.sum(axis=1, keepdims=True)
+ self.log2p = np.log2(P).astype(np.float32)
+ return self
+
+ # ------------------------------------------------------------ surprise
+ def surprise(self, data: bytes) -> np.ndarray:
+ """Per-byte surprisal -log2 P(byte | previous byte), in bits."""
+ if self.log2p is None:
+ raise RuntimeError("EPT must be fit() before use")
+ arr = np.frombuffer(data, dtype=np.uint8).astype(np.int64)
+ s = np.empty(len(arr), dtype=np.float32)
+ if len(arr) == 0:
+ return s
+ s[0] = 8.0 # uniform prior for the first byte
+ if len(arr) > 1:
+ s[1:] = -self.log2p[arr[:-1], arr[1:]]
+ return s
+
+ # ----------------------------------------------------------- segmenting
+ def boundaries(self, data: bytes) -> np.ndarray:
+ """Greedy constant-surprise segmentation.
+
+ Returns inclusive boundary positions ``b_0=0 < b_1 < ... < b_k = n``;
+ patch i is ``data[b_i : b_{i+1}]``. A patch closes when its
+ accumulated surprisal reaches ``budget_bits`` (or ``max_len`` /
+ end-of-stream forces it).
+ """
+ if len(data) == 0:
+ return np.zeros(0, dtype=np.int64)
+ s = self.surprise(data)
+ n = len(s)
+ cum = np.concatenate([[0.0], np.cumsum(s, dtype=np.float64)])
+ bounds = [0]
+ start = 0
+ searchsorted = np.searchsorted
+ min_len, max_len, budget = self.min_len, self.max_len, self.budget_bits
+ while start < n:
+ target = cum[start] + budget
+ b = int(searchsorted(cum, target, side="left"))
+ if b < start + min_len:
+ b = start + min_len
+ elif b > start + max_len:
+ b = start + max_len
+ if b > n:
+ b = n
+ bounds.append(b)
+ start = b
+ # drop a degenerate trailing boundary at exactly n produced twice
+ if len(bounds) > 1 and bounds[-1] == bounds[-2]:
+ bounds.pop()
+ return np.asarray(bounds, dtype=np.int64)
+
+ def segment(self, data: bytes) -> list[bytes]:
+ b = self.boundaries(data)
+ return [data[b[i] : b[i + 1]] for i in range(len(b) - 1)]
+
+ def segment_ids(self, data: bytes) -> list[int]:
+ return [fnv1a64(p) for p in self.segment(data)]
+
+ # ---------------------------------------------------------- calibration
+ def calibrate(self, sample: bytes, target_len: float = 4.5, iters: int = 10) -> float:
+ """Binary-search the surprisal budget to hit a target average patch
+ length on a calibration sample. Returns the chosen budget."""
+ lo, hi = 1.0, 64.0
+ for _ in range(iters):
+ mid = 0.5 * (lo + hi)
+ self.budget_bits = mid
+ b = self.boundaries(sample)
+ avg = len(sample) / max(len(b) - 1, 1)
+ if avg < target_len:
+ lo = mid
+ else:
+ hi = mid
+ self.budget_bits = 0.5 * (lo + hi)
+ return self.budget_bits
+
+ # ------------------------------------------------------------- metrics
+ def stats(self, patches: list[bytes]) -> dict:
+ lens = np.array([len(p) for p in patches], dtype=np.float64)
+ return {
+ "n_patches": int(len(patches)),
+ "avg_len": float(lens.mean()) if len(lens) else 0.0,
+ "min_len": int(lens.min()) if len(lens) else 0,
+ "max_len": int(lens.max()) if len(lens) else 0,
+ "p50_len": float(np.percentile(lens, 50)) if len(lens) else 0.0,
+ "p90_len": float(np.percentile(lens, 90)) if len(lens) else 0.0,
+ "bytes": int(lens.sum()),
+ }
+
+ # ---------------------------------------------------------- (de)hydrate
+ def state_dict(self) -> dict:
+ return {
+ "budget_bits": self.budget_bits,
+ "min_len": self.min_len,
+ "max_len": self.max_len,
+ "alpha": self.alpha,
+ "log2p": self.log2p.astype(np.float32),
+ }
+
+ def load_state_dict(self, sd: dict) -> None:
+ self.budget_bits = float(sd["budget_bits"])
+ self.min_len = int(sd["min_len"])
+ self.max_len = int(sd["max_len"])
+ self.alpha = float(sd["alpha"])
+ self.log2p = np.asarray(sd["log2p"], dtype=np.float32)
diff --git a/results/hashing/lever2_sparse/code/python/spira/evaluate.py b/results/hashing/lever2_sparse/code/python/spira/evaluate.py
new file mode 100644
index 0000000000000000000000000000000000000000..2c7efcc706c6c9ca1a2f182c5dd501b9ed0c98dd
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/python/spira/evaluate.py
@@ -0,0 +1,353 @@
+#!/usr/bin/env python3
+"""SPIRA evaluation harness v2 — proofs + hierarchy ablation + replay.
+
+Produces artifacts/metrics.json with:
+ 0. vocab coverage : readout-vocabulary coverage curve (Zipf knee)
+ 1. compression : EPT vs byte-level BPE (matched vocab) vs gzip-9
+ 2. prediction : unigram / bigram / SNN (fast-only) / hierarchical
+ cortex / AM / fused, on held-out test + a slice of the
+ TRAINED region (memorization reference)
+ 3. one-shot : single-pass teaching of an unseen book -> exact recall
+ 3b. replay : hippocampal replay -> cortical consolidation curve,
+ AM integrity after replay, and interference on test
+ 4. correction : recall vs number of corrupted context lanes
+ 5. generation : samples, speed, synaptic-op accounting
+
+Sections are resumable: completed sections are skipped when metrics.json
+already contains them, so the harness can be re-invoked across process
+boundaries (each call loads the checkpoint fresh; the replay experiment is
+self-contained in one section).
+"""
+from __future__ import annotations
+
+import argparse
+import json
+import os
+import time
+
+import numpy as np
+
+from .baselines import (BigramBaseline, UnigramBaseline, bpe_encode,
+ dict_bits, gzip_bits_per_byte, stream_entropy_bits)
+from .ept import EPT
+from .hashing import fnv1a64
+from .model import SPIRA
+
+
+def distinct_n(text: str, n: int) -> float:
+ toks = text.split()
+ if len(toks) < n:
+ return 0.0
+ grams = [" ".join(toks[i : i + n]) for i in range(len(toks) - n + 1)]
+ return len(set(grams)) / len(grams)
+
+
+def dump(metrics: dict, path: str) -> None:
+ with open(path, "w") as f:
+ json.dump(metrics, f, indent=2, ensure_ascii=False)
+
+
+def main() -> None:
+ ap = argparse.ArgumentParser()
+ ap.add_argument("--model", required=True)
+ ap.add_argument("--train", required=True)
+ ap.add_argument("--test", required=True)
+ ap.add_argument("--oneshot", required=True)
+ ap.add_argument("--out", required=True)
+ ap.add_argument("--eval-positions", type=int, default=60_000)
+ ap.add_argument("--replay-tokens", type=int, default=100_000)
+ ap.add_argument("--replay-stages", type=int, default=4)
+ args = ap.parse_args()
+
+ train = open(args.train, "rb").read()
+ test = open(args.test, "rb").read()
+ oneshot = open(args.oneshot, "rb").read()
+ model = SPIRA.load(args.model)
+ metrics: dict = {}
+ if os.path.exists(args.out):
+ try:
+ metrics = json.load(open(args.out))
+ print(f"(resuming: {len(metrics)} section(s) already present)")
+ except Exception:
+ metrics = {}
+ # restore the train id stream for baselines / corruption / coverage
+ t0 = time.perf_counter()
+ train_patches = model.ept.segment(train)
+ train_ids = np.fromiter((fnv1a64(p) for p in train_patches), dtype=np.uint64,
+ count=len(train_patches))
+ model._ids_train = train_ids
+ print(f"prep: segmented train ({len(train_ids)} patches) in {time.perf_counter()-t0:.1f}s")
+ if model.core.hier:
+ cal = model.calibrate_fusion(train[:60_000])
+ print(f"prep: fusion calibration sigma_fast={cal['sigma_fast']:.4f} "
+ f"sigma_slow={cal['sigma_slow']:.4f} scale={cal['scale']:.6f} "
+ f"beta={model.core.beta:.4f}")
+ if "fusion_calibration" not in metrics:
+ metrics["fusion_calibration"] = {**cal, "beta": float(model.core.beta)}
+ dump(metrics, args.out)
+ if "model_meta" not in metrics:
+ metrics.update({"model_meta": model.meta, "config": vars(model.cfg)})
+ dump(metrics, args.out)
+
+ # ============================================ 0. vocab coverage curve =====
+ if "vocab_coverage_curve" not in metrics:
+ print("== [0/7] readout-vocabulary coverage curve ==")
+ uniq, cnt = np.unique(train_ids, return_counts=True)
+ order = np.lexsort((uniq, -cnt)) # count desc, id asc (build order)
+ sorted_ids = uniq[order]
+ test_ids_local = np.fromiter(
+ (fnv1a64(p) for p in model.ept.segment(test)), dtype=np.uint64,
+ count=len(model.ept.segment(test)))
+ one_ids_local = np.fromiter(
+ (fnv1a64(p) for p in model.ept.segment(oneshot[:60_000])), dtype=np.uint64,
+ count=len(model.ept.segment(oneshot[:60_000])))
+ curve = []
+ for V in (4096, 6144, 8192, 12288, 16384, 24576, 32768):
+ top = sorted_ids[:V]
+ cov_t = float(np.isin(test_ids_local, top).mean())
+ cov_o = float(np.isin(one_ids_local, top).mean())
+ curve.append({"vocab": int(V), "cov_test": round(cov_t, 4),
+ "cov_oneshot": round(cov_o, 4)})
+ print(f" V={V:>6}: held-out test coverage={cov_t:.4f} "
+ f"oneshot coverage={cov_o:.4f}")
+ metrics["vocab_coverage_curve"] = curve
+ metrics["vocab_coverage"] = {
+ "distinct_train_patches": int(len(uniq)),
+ "note": "fraction of held-out target patches inside the top-V train vocabulary"}
+ dump(metrics, args.out)
+
+ # ================================================== 1. compression =====
+ if "compression" not in metrics:
+ print("== [1/7] compression: EPT vs BPE vs gzip ==")
+ comp = {}
+ gz_bpb, gz_s = gzip_bits_per_byte(test)
+ comp["gzip"] = {"bits_per_byte": gz_bpb, "seconds": gz_s}
+ for vs in (4096, 16384):
+ r = bpe_encode(train[:4_000_000], test, vs)
+ h0 = stream_entropy_bits(r["ids"], order=0)
+ h1 = stream_entropy_bits(r["ids"], order=1)
+ db = dict_bits(r["vocab_size"], r["vocab_bytes"])
+ comp[f"bpe_{vs}"] = {
+ "vocab_size": r["vocab_size"],
+ "n_tokens": int(len(r["ids"])),
+ "avg_token_bytes": len(test) / len(r["ids"]),
+ "stream_bits_unigram": h0,
+ "stream_bits_bigram": h1,
+ "dict_bits": db,
+ "bits_per_byte_unigram": (h0 * len(r["ids"]) + db) / len(test),
+ "bits_per_byte_bigram": (h1 * len(r["ids"]) + db) / len(test),
+ "train_s": r["train_s"],
+ }
+ t0 = time.perf_counter()
+ ept_patches = model.ept.segment(test)
+ ept_seg_s = time.perf_counter() - t0
+ ept_ids = np.fromiter((fnv1a64(p) for p in ept_patches), dtype=np.uint64,
+ count=len(ept_patches))
+ h0 = stream_entropy_bits(ept_ids, order=0)
+ h1 = stream_entropy_bits(ept_ids, order=1)
+ reg_ids = model.registry.ids
+ in_train = model.registry.has(ept_ids)
+ known_ids = ept_ids[in_train]
+ pos = np.searchsorted(reg_ids, np.unique(known_ids))
+ lens = np.diff(model.registry.offsets)[pos].astype(np.float64)
+ ept_dict_bits = float(lens.sum() * 8 + 32 * len(lens))
+ novelty = float((~in_train).mean())
+ comp["ept"] = {
+ "n_tokens": int(len(ept_ids)),
+ "avg_token_bytes": float(len(test) / len(ept_ids)),
+ "distinct_in_test": int(len(np.unique(ept_ids))),
+ "stream_bits_unigram": h0,
+ "stream_bits_bigram": h1,
+ "dict_bits_test_local": ept_dict_bits,
+ "bits_per_byte_unigram": (h0 * len(ept_ids) + ept_dict_bits) / len(test),
+ "bits_per_byte_bigram": (h1 * len(ept_ids) + ept_dict_bits) / len(test),
+ "novelty_rate": novelty,
+ "bytes_in_novel_patches": float(sum(len(p) for p, k in zip(ept_patches, in_train) if not k)),
+ "segment_s": ept_seg_s,
+ "MB_per_s": len(test) / 1e6 / max(ept_seg_s, 1e-9),
+ }
+ metrics["compression"] = comp
+ dump(metrics, args.out)
+ for k, v in comp.items():
+ print(f" {k}: {json.dumps({kk: round(vv, 4) if isinstance(vv, float) else vv for kk, vv in v.items() if 'bits_per_byte' in kk or 'novelty' in kk or 'avg_token' in kk})}")
+
+ # ================================================== 2. prediction =====
+ if "prediction" not in metrics:
+ print("== [2/7] next-patch prediction: held-out test + trained region ==")
+ ev = model.eval_stream(test, max_positions=args.eval_positions)
+ print(f" TEST: fused={ev['fused_acc']:.4f} (hier={ev['hier_acc']:.4f}, "
+ f"fast={ev['snn_acc']:.4f}, am={ev['am_acc']:.4f}, coverage={ev['vocab_coverage']:.3f})")
+ # memorization reference: the FINAL training region (tokens ~550k-600k,
+ # where the model's operating point was warm-matched; SNN region 0-600k,
+ # AM region 0-1.2M). Earlier regions are legitimately drifted under
+ # continual plasticity — that is the forgetting curve, not a bug.
+ ev_tr = model.eval_stream(train[2_600_000:2_800_000], max_positions=8_000)
+ print(f" TRAINED-REGION: fused={ev_tr['fused_acc']:.4f} "
+ f"(hier={ev_tr['hier_acc']:.4f}, am={ev_tr['am_acc']:.4f})")
+ # baselines over the same test stream, in-vocab positions
+ tp = model.ept.segment(test)
+ tids = np.fromiter((fnv1a64(p) for p in tp), dtype=np.uint64, count=len(tp))
+ tcols = model.cols_of(tids)[: args.eval_positions + 1]
+ V = model.cfg.vocab_size
+ inv_mask = tcols != V
+ ok_pos = inv_mask[:-1] & inv_mask[1:]
+ prev_in = tcols[:-1][ok_pos].astype(np.int64)
+ cur_in = tcols[1:][ok_pos].astype(np.int64)
+ train_cols = model.cols_of(train_ids[:600_000])
+ uni = UnigramBaseline(train_cols, V)
+ bi = BigramBaseline(train_cols, V)
+ pred = {
+ "spira_test": ev,
+ "spira_trained_region": ev_tr,
+ "unigram_acc": uni.accuracy(cur_in),
+ "bigram_acc": bi.accuracy(prev_in, cur_in),
+ "n_baseline_positions": int(len(cur_in)),
+ "note": "baselines evaluated on in-vocab target positions of the same stream; "
+ "compare with spira_test.*_invocab",
+ }
+ metrics["prediction"] = pred
+ dump(metrics, args.out)
+ print(f" baselines (in-vocab): unigram={pred['unigram_acc']:.4f} "
+ f"bigram={pred['bigram_acc']:.4f} vs spira fast_invocab={ev['snn_acc_invocab']:.4f} "
+ f"hier_invocab={ev['hier_acc_invocab']:.4f} fused_invocab={ev['fused_acc_invocab']:.4f}")
+
+ # ==================================================== 3. one-shot =====
+ if "one_shot" not in metrics:
+ print("== [3/7] one-shot learning: teach the unseen book ONCE ==")
+ book = oneshot[:60_000]
+ generalization = model.eval_stream(book, max_positions=8_000)
+ t0 = time.perf_counter()
+ taught = model.teach_bytes(book)
+ teach_s = time.perf_counter() - t0
+ recall = model.eval_stream(book, max_positions=8_000)
+ oneshot_metrics = {
+ "book_bytes": len(book),
+ "before_teaching": generalization,
+ "teaching": {**taught, "seconds": teach_s},
+ "after_one_pass": recall,
+ }
+ metrics["one_shot"] = oneshot_metrics
+ dump(metrics, args.out)
+ print(f" before: fused={generalization['fused_acc']:.4f} am={generalization['am_acc']:.4f}")
+ print(f" teach: {taught['tokens']} tokens, {taught['new_patches']} new patches in {teach_s:.1f}s")
+ print(f" after ONE pass: am recall={recall['am_acc']:.4f} fused={recall['fused_acc']:.4f}")
+
+ # ===================================== 3b. replay -> consolidation =====
+ if "replay" not in metrics:
+ print("== [4/7] hippocampal replay -> cortical consolidation ==")
+ book = oneshot[:60_000]
+ if not model.episodes:
+ taught = model.teach_bytes(book)
+ print(f" (re-taught for this section: {taught['tokens']} tokens)")
+ before = model.eval_stream(book, use_am=False, max_positions=8_000)
+ print(f" cortex-only BEFORE replay: hier={before['hier_acc']:.4f} "
+ f"(in-vocab {before['hier_acc_invocab']:.4f}, fast={before['snn_acc']:.4f})")
+ curve = []
+ stage = max(1, args.replay_tokens // args.replay_stages)
+ for i in range(args.replay_stages):
+ r = model.replay(stage, log=lambda s: print(f" {s}"))
+ probe = model.eval_stream(book, use_am=False, max_positions=2_000)
+ curve.append({
+ "replayed_tokens": (i + 1) * stage,
+ "hier_acc": probe["hier_acc"],
+ "hier_acc_invocab": probe["hier_acc_invocab"],
+ "snn_acc": probe["snn_acc"],
+ "replay_acc": r.get("accuracy"),
+ "beta": r.get("beta"),
+ })
+ print(f" after {(i+1)*stage} replayed tokens: hier={probe['hier_acc']:.4f} "
+ f"(in-vocab {probe['hier_acc_invocab']:.4f}) beta={r.get('beta'):.3f}")
+ after = model.eval_stream(book, use_am=False, max_positions=8_000)
+ am_after = model.eval_stream(book, max_positions=8_000)
+ interference_core = model.eval_stream(test, use_am=False, max_positions=8_000)
+ interference_fused = model.eval_stream(test, max_positions=8_000)
+ metrics["replay"] = {
+ "replay_tokens": int(args.replay_tokens),
+ "stage_tokens": int(stage),
+ "before": before,
+ "curve": curve,
+ "after": after,
+ "am_recall_after_replay": am_after,
+ "interference_test_core_only": interference_core,
+ "interference_test_fused": interference_fused,
+ "pre_replay_test": metrics.get("prediction", {}).get("spira_test"),
+ "note": "the shipped checkpoint is PRE-replay; this section runs in-memory",
+ }
+ dump(metrics, args.out)
+ print(f" cortex-only AFTER replay: hier={after['hier_acc']:.4f} "
+ f"(in-vocab {after['hier_acc_invocab']:.4f})")
+ print(f" AM recall after replay: {am_after['am_acc']:.4f} (must be intact)")
+ print(f" interference on test: core {interference_core['hier_acc']:.4f} / "
+ f"fused {interference_fused['fused_acc']:.4f}")
+
+ # ================================================== 4. correction =====
+ if "correction" not in metrics:
+ print("== [5/7] correction: recall vs corrupted context lanes ==")
+ corr = {}
+ for k in (0, 1, 2, 3):
+ r = model.eval_stream(oneshot[:60_000], corrupt_lanes=k, max_positions=8_000)
+ corr[f"corrupt_{k}_of_4"] = {kk: r[kk] for kk in ("am_acc", "am_acc_invocab", "fused_acc")}
+ print(f" corrupt {k}/4 lanes: am={r['am_acc']:.4f} fused={r['fused_acc']:.4f}")
+ metrics["correction"] = corr
+ dump(metrics, args.out)
+
+ # ================================================ 5. generation ======
+ if "generation" not in metrics:
+ print("== [6/7] generation ==")
+ gens = {}
+ prompts = {
+ "english": b"The old man looked at the ",
+ "code": b"def process(data):\n ",
+ "french": b"Il etait une fois un ",
+ }
+ for name, p in prompts.items():
+ t0 = time.perf_counter()
+ g = model.generate(p, n_tokens=150, temperature=0.7, top_k=8, seed=42)
+ dt = time.perf_counter() - t0
+ text = g.decode("utf-8", "replace")
+ gens[name] = {
+ "prompt": p.decode("utf-8", "replace"),
+ "output": text,
+ "chars_per_s": len(text) / max(dt, 1e-9),
+ "distinct1": distinct_n(text, 1),
+ "distinct2": distinct_n(text, 2),
+ }
+ print(f" [{name}] {len(text)} chars @ {len(text)/max(dt,1e-9):.0f} chars/s")
+ print(f" {text[:180]!r}")
+ metrics["generation"] = gens
+ dump(metrics, args.out)
+
+ # ================================================ 6. efficiency ======
+ if "efficiency" not in metrics:
+ print("== [7/7] efficiency accounting ==")
+ d_in, k, n = model.cfg.d_in, model.cfg.k_in, model.cfg.n_res
+ V = model.cfg.vocab_size
+ n_g = model.cfg.n_g
+ win = model.cfg.win
+ slow_amortized = (n_g * (V + 1) + n * n_g + n_g * n_g) / win
+ macs = {
+ "input_gather": k * n,
+ "recurrent": n * n,
+ "readout_fast": n * V,
+ "readout_slow_amortized": slow_amortized,
+ "total_per_token": k * n + n * n + n * V + slow_amortized,
+ }
+ metrics["efficiency"] = {
+ "synaptic_macs_per_token": macs,
+ "vs_transformer_reference": {
+ "gpt2_small_params": 124e6,
+ "gpt2_train_flops_per_token": 6 * 124e6,
+ "spira_vs_gpt2_ops_ratio": macs["total_per_token"] / (6 * 124e6),
+ },
+ }
+ dump(metrics, args.out)
+ print(f" {macs['total_per_token']/1e6:.2f}M MACs/token "
+ f"(fast readout {macs['readout_fast']/1e6:.2f}M, slow amortized "
+ f"{slow_amortized/1e6:.2f}M) -> "
+ f"{(6*124e6)/macs['total_per_token']:.0f}x fewer ops/token than GPT-2-small training")
+
+ print(f"metrics -> {args.out}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/results/hashing/lever2_sparse/code/python/spira/export_deploy.py b/results/hashing/lever2_sparse/code/python/spira/export_deploy.py
new file mode 100644
index 0000000000000000000000000000000000000000..037cb572b12502bc35601337de4aaaf5dee090dd
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/python/spira/export_deploy.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python3
+"""Export a trained SPIRA model as a compact JSON artifact for the web demo.
+
+The TypeScript port (src/lib/spira/*) is compatible with the Python
+prototype: FNV-1a-64 / splitmix64 / mulberry32 are shared specs, the input
+and recurrent weights are REGENERATED from the seed in the browser, and only
+the learned matrices (W_out, W_out_G, W_rec after STDP), the Markov table,
+the patch registry, the hippocampal entries, and the learned homeostatic
+state are shipped (binary packed as base64).
+
+Format v2 adds the hierarchical slow area (G): its fixed projections ship
+dense (they are small), its readout ships int8-quantized like the fast one,
+and the learned state includes the slow homeostatic scalars, the top-down
+gain beta, and the measured variance-matching fusion scale.
+
+Usage:
+ python3 -m spira.export_deploy --model artifacts/spira_model.npz \
+ --out artifacts/spira_deploy.json [--am-cap 100000]
+"""
+from __future__ import annotations
+
+import argparse
+import base64
+import json
+
+import numpy as np
+
+from .model import SPIRA
+
+
+def b64(arr: np.ndarray) -> str:
+ return base64.b64encode(np.ascontiguousarray(arr).tobytes()).decode("ascii")
+
+
+def main() -> None:
+ ap = argparse.ArgumentParser()
+ ap.add_argument("--model", required=True)
+ ap.add_argument("--out", required=True)
+ ap.add_argument("--am-cap", type=int, default=80_000)
+ ap.add_argument("--am-min-count", type=int, default=2)
+ args = ap.parse_args()
+
+ model = SPIRA.load(args.model)
+ cfg = model.cfg
+ core = model.core
+
+ # ---- W_out: per-column int8 quantization -----------------------------
+ W = core.W_out.astype(np.float32) # (n_res, n_out)
+ n_res, n_out = W.shape
+ col_max = np.abs(W).max(axis=0)
+ col_max[col_max == 0] = 1.0
+ scale = (col_max / 127.0).astype(np.float32)
+ Wq = np.round(W / scale[None, :]).astype(np.int8)
+
+ # ---- W_rec after STDP: sparse triplets (row=pre, col=post) -----------
+ rec = core.W_rec
+ rows, cols = np.nonzero(rec)
+ vals = rec[rows, cols].astype(np.float32)
+ rec_entries = np.stack([rows.astype(np.int16), cols.astype(np.int16)], axis=1).astype(np.int16)
+
+ # ---- hippocampus: deduplicated entries, binary packed ----------------
+ entries = model.am.top_entries(min_count=args.am_min_count, cap=args.am_cap)
+ n_e = len(entries)
+ # pack: 4 x uint32 lanes + uint64 patch id + uint8 count = 25 bytes/entry
+ packed = np.zeros((n_e, 25), dtype=np.uint8)
+ for i, (k, v, c) in enumerate(entries):
+ kl = k.astype("G and G recurrent
+ "w_ing_b64": b64(core.W_inG), # (n_res, n_g) float32
+ "w_recg_b64": b64(core.W_recG), # (n_g, n_g) float32
+ "w_outg_q_b64": b64(WGq),
+ "w_outg_scale_b64": b64(g_scale),
+ }
+
+ deploy = {
+ "format": "spira-deploy-v2",
+ "config": {
+ "d_in": cfg.d_in, "k_in": cfg.k_in, "n_res": cfg.n_res,
+ "vocab_size": cfg.vocab_size, "seed": cfg.seed,
+ "in_fanout": core.in_fanout, "rec_fanout": core.rec_fanout,
+ "inh_frac": core.inh_frac, "lam": core.lam, "base_thr": core.base_thr,
+ "thr_min": core.thr_min, "thr_max": core.thr_max, "refrac": core.refrac,
+ "tau_trace": core.tau_trace, "w_in_scale": core.w_in_scale,
+ "w_rec_scale": core.w_rec_scale, "target_rate": core.target_rate,
+ "eta_homeo": core.eta_homeo,
+ "hierarchy": bool(cfg.hierarchy), "n_g": cfg.n_g, "win": cfg.win,
+ "am_m": cfg.am_m, "am_min_lanes": cfg.am_min_lanes,
+ "am_size": 1 << 20, # browser-side table is smaller
+ "beta_am": cfg.beta_am, "am_override": cfg.am_override,
+ "temperature": cfg.temperature, "top_k": cfg.top_k,
+ },
+ "ept": {
+ "budget_bits": model.ept.budget_bits, "min_len": model.ept.min_len,
+ "max_len": model.ept.max_len, "alpha": model.ept.alpha,
+ # 256x256 float32 log2-probs (row = prev byte); TS negates for surprise
+ "log2p_b64": b64(model.ept.log2p.astype(np.float32)),
+ },
+ "reservoir": {
+ "w_rec_rows": b64(rows.astype(np.int32)),
+ "w_rec_cols": b64(cols.astype(np.int32)),
+ "w_rec_vals_b64": b64(vals),
+ "w_rec_n": int(len(rows)),
+ },
+ "readout": {
+ "shape": [int(n_res), int(n_out)],
+ "vocab_ids_hex": [hex(int(x)) for x in model.vocab_ids],
+ "w_out_q_b64": b64(Wq),
+ "w_out_scale_b64": b64(scale),
+ },
+ "hier": hier,
+ "am": {
+ "n_entries": n_e,
+ "packed_b64": b64(flat),
+ "entry_bytes": 25,
+ },
+ "registry": {
+ "n": int(len(reg.ids)),
+ "ids_b64": b64(reg.ids.astype(" {args.out} ({sz/1e6:.1f} MB)")
+ print(f" vocab {len(model.vocab_ids)} | registry {len(reg.ids)} | am entries {n_e} "
+ f"| W_out {Wq.shape} int8 | W_rec triplets {len(rows)}"
+ + (f" | hier n_g={core.n_g} win={core.win} beta={core.beta:.4f}" if core.hier else ""))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/results/hashing/lever2_sparse/code/python/spira/hashing.py b/results/hashing/lever2_sparse/code/python/spira/hashing.py
new file mode 100644
index 0000000000000000000000000000000000000000..a570b6b294a10f80d5375aff011f42e496466be8
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/python/spira/hashing.py
@@ -0,0 +1,88 @@
+"""Deterministic hashing utilities shared between the Python prototype and the
+TypeScript web port.
+
+Every function here is specified to be bit-identical to its TypeScript
+counterpart (see web demo ``src/lib/spira/hashing.ts``). All arithmetic is
+64-bit unsigned wrapped (Python ints / BigInt in TS) or 32-bit unsigned where
+noted. No platform-dependent behaviour is allowed in this module.
+"""
+from __future__ import annotations
+
+MASK32 = 0xFFFFFFFF
+MASK64 = 0xFFFFFFFFFFFFFFFF
+
+FNV_OFFSET_BASIS = 0xCBF29CE484222325
+FNV_PRIME_64 = 0x100000001B3
+
+# Salts for hippocampal lane keys (one per context slot).
+LANE_SALTS = (
+ 0x9E3779B97F4A7C15,
+ 0xBF58476D1CE4E5B9,
+ 0x94D049BB133111EB,
+ 0x2545F4914F6DDC1D,
+)
+
+
+def fnv1a64(data: bytes, seed: int = 0) -> int:
+ """FNV-1a 64-bit hash of a byte string, with an optional seed XORed into
+ the offset basis. Used to content-address EPT patches."""
+ h = (FNV_OFFSET_BASIS ^ (seed & MASK64)) & MASK64
+ for b in data:
+ h ^= b
+ h = (h * FNV_PRIME_64) & MASK64
+ return h
+
+
+def splitmix64(x: int) -> int:
+ """splitmix64 finalizer (MurmurHash3 helper). 64-bit in, 64-bit out."""
+ z = (x + 0x9E3779B97F4A7C15) & MASK64
+ z = ((z ^ (z >> 30)) * 0xBF58476D1CE4E5B9) & MASK64
+ z = ((z ^ (z >> 27)) * 0x94D049BB133111EB) & MASK64
+ return (z ^ (z >> 31)) & MASK64
+
+
+def lane_key32(patch_id: int, lane: int) -> int:
+ """32-bit key for one hippocampal lane (context slot ``lane``).
+
+ High 32 bits of splitmix64 give excellent avalanche while staying
+ representable as a JS ``number`` (via >>> ops) in the TypeScript port.
+ """
+ return splitmix64(patch_id ^ LANE_SALTS[lane]) >> 32
+
+
+class Mulberry32:
+ """mulberry32 PRNG (bryc, public domain).
+
+ Produces the exact same float sequence as the TS implementation, so
+ network weights regenerated from a seed are bit-identical across
+ languages. Returns uniforms in [0, 1).
+ """
+
+ __slots__ = ("state",)
+
+ def __init__(self, seed: int) -> None:
+ self.state = seed & MASK32
+
+ def next_float(self) -> float:
+ self.state = (self.state + 0x6D2B79F5) & MASK32
+ t = self.state
+ t = ((t ^ (t >> 15)) * (t | 1)) & MASK32
+ t = (t ^ (t + ((((t ^ (t >> 7)) * (t | 61)) & MASK32)))) & MASK32
+ return ((t ^ (t >> 14)) & MASK32) / 4294967296.0
+
+ def next_weight(self, scale: float) -> float:
+ """Symmetric uniform weight in [-scale, scale]."""
+ return (self.next_float() * 2.0 - 1.0) * scale
+
+
+def input_neurons(patch_id: int, d_in: int, k_in: int) -> list[int]:
+ """Map a patch id to ``k_in`` input-neuron indices (hashing trick).
+
+ No embedding table: the projection is a pure function of the patch id,
+ so any patch ever seen (or never seen) projects consistently.
+ """
+ out = []
+ for j in range(k_in):
+ h = splitmix64(patch_id ^ (0x51ED270B733D4C31 + j * 0x9E3779B97F4A7C15))
+ out.append((h >> 32) % d_in)
+ return out
diff --git a/results/hashing/lever2_sparse/code/python/spira/hippocampus.py b/results/hashing/lever2_sparse/code/python/spira/hippocampus.py
new file mode 100644
index 0000000000000000000000000000000000000000..9aa57691cce8eec3685b53365cba819032be93ac
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/python/spira/hippocampus.py
@@ -0,0 +1,222 @@
+"""Hippocampal one-shot associative memory.
+
+Biological motivation (complementary learning systems): a fast, episodic,
+one-shot memory next to a slow statistical cortex (the spiking core).
+
+Key design — hybrid addressing (dentate-gyrus separation + CA3 completion):
+ * The key of a memory is the last ``m`` tokens (patches), one 32-bit lane
+ per context slot.
+ * PRIMARY address: a hash of the FULL key (pattern separation — every
+ distinct context gets its own slot, so capacity is real).
+ * SECONDARY addresses: one per lane (auto-associative backup probes — a
+ query with a corrupted context still reaches the entry through its
+ intact lanes).
+ * Retrieval is two-tier: a full-key match at the primary address
+ dominates; otherwise candidates matching >= min_lanes lanes vote by
+ lane-match count x log evidence count.
+
+This yields both capacity AND graceful degradation: corrupting 1 of 4
+context tokens still retrieves the original continuation through the
+intact lanes.
+"""
+from __future__ import annotations
+
+import numpy as np
+
+from .hashing import LANE_SALTS, splitmix64
+
+
+class Hippocampus:
+ def __init__(
+ self,
+ m: int = 4,
+ size: int = 1 << 23,
+ min_lanes: int = 3,
+ ) -> None:
+ self.m = m
+ self.size = size
+ self.min_lanes = min_lanes
+ # slot storage (vals are stable uint64 PATCH IDS, never indices)
+ self.keys = np.zeros((size, m), dtype=np.uint32)
+ self.vals = np.zeros(size, dtype=np.uint64)
+ self.counts = np.zeros(size, dtype=np.uint8)
+ self.used = np.zeros(size, dtype=np.bool_)
+ self.n_writes = 0
+
+ # ---------------------------------------------------------------- utils
+ def primary_addr(self, lane_keys: np.ndarray) -> int:
+ """Pattern-separation hash of the FULL key -> primary slot
+ (dentate-gyrus style: every distinct context gets its own address)."""
+ z = (int(lane_keys[0])
+ ^ ((int(lane_keys[1]) << 8 | int(lane_keys[1]) >> 24) & 0xFFFFFFFF)
+ ^ ((int(lane_keys[2]) << 16 | int(lane_keys[2]) >> 16) & 0xFFFFFFFF)
+ ^ ((int(lane_keys[3]) << 24 | int(lane_keys[3]) >> 8) & 0xFFFFFFFF))
+ return splitmix64(z) % self.size
+
+ def loo_addr(self, lane_keys: np.ndarray, l: int) -> int:
+ """Leave-one-out hash of the key minus lane l -> CA3 completion slot.
+
+ A query whose lane l is corrupted can still compute this address
+ from its intact lanes and reach the stored entry."""
+ a = [int(lane_keys[i]) for i in range(self.m) if i != l]
+ z = a[0] ^ (((a[1] << 13) | (a[1] >> 19)) & 0xFFFFFFFF) \
+ ^ (((a[2] << 26) | (a[2] >> 6)) & 0xFFFFFFFF)
+ return splitmix64(z ^ (0x9E3779B9 + l * 0x85EBCA6B)) % self.size
+
+ @staticmethod
+ def lane_keys(patch_ids) -> np.ndarray:
+ """(m,) uint32 lane keys for a context of m patch ids."""
+ out = np.empty(len(patch_ids), dtype=np.uint32)
+ for lane, pid in enumerate(patch_ids):
+ out[lane] = splitmix64(int(pid) ^ LANE_SALTS[lane]) >> 32
+ return out
+
+ def lane_keys_stream(self, patch_ids: np.ndarray) -> np.ndarray:
+ """Vectorized lane keys for a whole token stream: (T, m) uint32."""
+ T = len(patch_ids)
+ out = np.empty((T, self.m), dtype=np.uint32)
+ for lane in range(self.m):
+ # splitmix64 on an array of uint64 ids, take high 32 bits
+ z = patch_ids.astype(np.uint64) ^ np.uint64(LANE_SALTS[lane])
+ z = z + np.uint64(0x9E3779B97F4A7C15)
+ z = (z ^ (z >> np.uint64(30))) * np.uint64(0xBF58476D1CE4E5B9)
+ z = (z ^ (z >> np.uint64(27))) * np.uint64(0x94D049BB133111EB)
+ z = z ^ (z >> np.uint64(31))
+ out[:, lane] = (z >> np.uint64(32)).astype(np.uint32)
+ return out
+
+ # ---------------------------------------------------------------- write
+ def write(self, lane_keys: np.ndarray, val: int) -> None:
+ """One-shot write of (context -> continuation patch id).
+
+ Stores the entry at its PRIMARY (full-key hash) slot — pattern
+ separation gives every distinct context its own address — plus
+ best-effort copies at the m lane slots for corrupted-cue retrieval.
+ """
+ # primary slot: exact-context capacity
+ paddr = self.primary_addr(lane_keys)
+ if not self.used[paddr]:
+ self.keys[paddr] = lane_keys
+ self.vals[paddr] = val
+ self.counts[paddr] = 1
+ self.used[paddr] = True
+ elif np.array_equal(self.keys[paddr], lane_keys):
+ if self.vals[paddr] == val:
+ if self.counts[paddr] < 255:
+ self.counts[paddr] += 1
+ else:
+ c = int(self.counts[paddr])
+ if c > 1:
+ self.counts[paddr] = c - 1
+ else:
+ self.vals[paddr] = val
+ self.counts[paddr] = 1
+ elif int(self.counts[paddr]) <= 1:
+ # evict unconsolidated memories only (keep consolidated ones)
+ self.keys[paddr] = lane_keys
+ self.vals[paddr] = val
+ self.counts[paddr] = 1
+ # leave-one-out completion slots: robust to one corrupted lane
+ for l in range(self.m):
+ addr = self.loo_addr(lane_keys, l)
+ if not self.used[addr]:
+ self.keys[addr] = lane_keys
+ self.vals[addr] = val
+ self.counts[addr] = 1
+ self.used[addr] = True
+ elif np.array_equal(self.keys[addr], lane_keys):
+ if self.vals[addr] == val:
+ if self.counts[addr] < 255:
+ self.counts[addr] += 1
+ # else: a different key occupies this completion slot — keep it
+ self.n_writes += 1
+
+ def write_stream(self, lane_stream: np.ndarray, vals: np.ndarray) -> None:
+ """Bulk one-shot write over a stream (val[t] follows context of
+ lane_stream[t])."""
+ for t in range(len(vals)):
+ self.write(lane_stream[t], int(vals[t]))
+
+ # ---------------------------------------------------------------- query
+ def query(self, lane_keys: np.ndarray):
+ """Query with the current context. Returns (patch_id, weight) or
+ (None, 0.0).
+
+ Two-tier voting: a candidate matching ALL m lanes dominates any
+ partial match (a full-key entry must never lose to a partial match
+ with a higher count); within the winning tier, votes scale with
+ lane-match count x log evidence count.
+ """
+ votes: dict[int, float] = {}
+ max_match: dict[int, int] = {}
+ # primary probe: exact full-key retrieval
+ paddr = self.primary_addr(lane_keys)
+ if self.used[paddr] and np.array_equal(self.keys[paddr], lane_keys):
+ v = int(self.vals[paddr])
+ c = int(self.counts[paddr])
+ votes[v] = votes.get(v, 0.0) + self.m * (1.0 + np.log1p(c))
+ max_match[v] = self.m
+ # leave-one-out probes: corrupted-cue completion (CA3)
+ for l in range(self.m):
+ addr = self.loo_addr(lane_keys, l)
+ if not self.used[addr]:
+ continue
+ match = int(np.count_nonzero(self.keys[addr] == lane_keys))
+ if match >= self.min_lanes:
+ v = int(self.vals[addr])
+ c = int(self.counts[addr])
+ w = match * (1.0 + np.log1p(c))
+ votes[v] = votes.get(v, 0.0) + w
+ if match > max_match.get(v, 0):
+ max_match[v] = match
+ if not votes:
+ return None, 0.0
+ if max(max_match.values()) == self.m:
+ votes = {v: w for v, w in votes.items() if max_match[v] == self.m}
+ best_v, best_w = max(votes.items(), key=lambda kv: kv[1])
+ return best_v, best_w
+
+ # ---------------------------------------------------------------- stats
+ def stats(self) -> dict:
+ n_used = int(self.used.sum())
+ return {
+ "slots": self.size,
+ "used": n_used,
+ "load_factor": n_used / self.size,
+ "n_writes": self.n_writes,
+ }
+
+ def _slots_of(self, lane_keys: np.ndarray) -> list[int]:
+ """All derivable slot addresses of a key: primary + leave-one-out."""
+ out = [self.primary_addr(lane_keys)]
+ for l in range(self.m):
+ out.append(self.loo_addr(lane_keys, l))
+ return out
+
+ def top_entries(self, registry=None, min_count: int = 2, cap: int | None = None):
+ """Deduplicated (lane_keys, val, count) list for export/eval, sorted by
+ count descending.
+
+ Dedup is EXACT: every slot an entry occupies is derivable from its
+ key (the primary full-key hash plus the m leave-one-out hashes), so
+ we mark all slots that actually hold this key. (Collisions may have
+ blocked some redundant writes — those slots hold a different key and
+ are not marked.)
+ """
+ visited = np.zeros(self.size, dtype=np.bool_)
+ items = []
+ idx = np.nonzero(self.used)[0]
+ for addr in idx:
+ if visited[addr]:
+ continue
+ k = self.keys[addr]
+ c = int(self.counts[addr])
+ for a in self._slots_of(k):
+ if self.used[a] and np.array_equal(self.keys[a], k):
+ visited[a] = True
+ if c >= min_count:
+ items.append((k.copy(), int(self.vals[addr]), c))
+ items.sort(key=lambda it: it[2], reverse=True)
+ if cap is not None:
+ items = items[:cap]
+ return items
diff --git a/results/hashing/lever2_sparse/code/python/spira/model.py b/results/hashing/lever2_sparse/code/python/spira/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..62d5da5b837454655cf748e295d5c2bae03278af
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/python/spira/model.py
@@ -0,0 +1,869 @@
+"""SPIRA — Spiking Plastic Recurrent Architecture.
+
+Full system pipeline:
+
+ raw bytes ──EPT──▶ content-addressed patches ──hashing trick──▶ input spikes
+ │ │
+ │ LIF reservoir
+ │ (STDP, Dale)
+ │ │
+ │ three-factor
+ │ readout (R-STDP)
+ ▼ ▼
+ hippocampal associative memory ──fused──▶ prediction
+
+ generation runs the same loop closed: predicted patch is fed back as
+ input spikes, one patch (multi-byte) at a time.
+"""
+from __future__ import annotations
+
+import json
+import time
+from dataclasses import dataclass, field, asdict
+
+import numpy as np
+
+from .ept import EPT
+from .hashing import fnv1a64, splitmix64
+from .hippocampus import Hippocampus
+from .spiking import SpikingCore
+
+UNK_COL = -1 # sentinel before adding the +1 offset
+
+
+@dataclass
+class SPIRAConfig:
+ # EPT
+ target_avg_len: float = 4.5
+ min_len: int = 2
+ max_len: int = 32
+ alpha: float = 0.5
+ # spiking core
+ d_in: int = 1024
+ k_in: int = 12
+ n_res: int = 512
+ vocab_size: int = 16384
+ seed: int = 20261022
+ # hierarchical multi-scale cortex (v2)
+ hierarchy: bool = True
+ n_g: int = 256
+ win: int = 8
+ eta_pos: float = 0.01
+ eta_r: float = 0.01
+ eta_stdp: float = 0.0015
+ # hippocampus
+ am_size: int = 1 << 23
+ am_m: int = 4
+ am_min_lanes: int = 3
+ # training
+ snn_tokens: int = 600_000
+ am_tokens: int = 1_200_000
+ epochs: int = 2
+ # hippocampal replay -> cortical consolidation
+ replay_tokens: int = 180_000
+ replay_slice: int = 512
+ # v3 cortex fixes (Muse)
+ direct_input: bool = True
+ trace_taus: tuple = (0.4, 0.8, 0.95)
+ direct_tau: float = 0.5
+ structured_inputs: bool = True
+ k_tri: int = 6
+ # generation / fusion
+ beta_am: float = 0.5
+ am_override: float = 6.0
+ temperature: float = 0.8
+ top_k: int = 8
+
+
+class PatchRegistry:
+ """Compact content-addressed patch storage.
+
+ Sorted uint64 id array + offsets into a single concatenated byte buffer.
+ Lookup is O(log n) via searchsorted (vectorizable). Also stores counts.
+ """
+
+ def __init__(self) -> None:
+ self.ids = np.zeros(0, dtype=np.uint64) # sorted unique
+ self.counts = np.zeros(0, dtype=np.uint32)
+ self.offsets = np.zeros(0, dtype=np.uint64) # len = n+1
+ self.buffer = b""
+
+ @classmethod
+ def build(cls, ids: np.ndarray, patches: list[bytes], keep: set[int] | None = None) -> "PatchRegistry":
+ reg = cls()
+ id2bytes: dict[int, bytes] = {}
+ for i, b in zip(ids.tolist(), patches):
+ if keep is not None and i not in keep:
+ continue
+ id2bytes[i] = b # last occurrence wins; identical anyway
+ if not id2bytes:
+ return reg
+ reg.ids = np.fromiter(id2bytes.keys(), dtype=np.uint64, count=len(id2bytes))
+ reg.ids.sort()
+ buf = bytearray()
+ offsets = np.zeros(len(reg.ids) + 1, dtype=np.uint64)
+ for j, pid in enumerate(reg.ids.tolist()):
+ b = id2bytes[pid]
+ offsets[j] = len(buf)
+ buf.extend(b)
+ offsets[-1] = len(buf)
+ reg.offsets = offsets
+ reg.buffer = bytes(buf)
+ # counts from the stream
+ uniq, cnt = np.unique(ids, return_counts=True)
+ pos = np.searchsorted(reg.ids, uniq)
+ pos_ok = (pos < len(reg.ids)) & (reg.ids[np.minimum(pos, len(reg.ids) - 1)] == uniq)
+ reg.counts = np.zeros(len(reg.ids), dtype=np.uint32)
+ reg.counts[pos[pos_ok]] = cnt[pos_ok].astype(np.uint32)
+ return reg
+
+ def __len__(self) -> int:
+ return len(self.ids)
+
+ def has(self, ids: np.ndarray | int) -> np.ndarray | bool:
+ if len(self.ids) == 0:
+ return np.zeros(len(ids), dtype=bool) if isinstance(ids, np.ndarray) else False
+ if isinstance(ids, (int, np.integer)):
+ pos = np.searchsorted(self.ids, np.uint64(ids))
+ return bool(pos < len(self.ids) and self.ids[min(pos, len(self.ids) - 1)] == ids)
+ pos = np.searchsorted(self.ids, ids)
+ pos_c = np.minimum(pos, len(self.ids) - 1)
+ return (pos < len(self.ids)) & (self.ids[pos_c] == ids)
+
+ def bytes_of(self, pid: int) -> bytes | None:
+ pos = int(np.searchsorted(self.ids, np.uint64(pid)))
+ if pos >= len(self.ids) or self.ids[pos] != np.uint64(pid):
+ return None
+ a, b = int(self.offsets[pos]), int(self.offsets[pos + 1])
+ return self.buffer[a:b]
+
+ def index_of(self, pid: int) -> int:
+ """Registry index of a patch id, or -1."""
+ pos = int(np.searchsorted(self.ids, np.uint64(pid)))
+ if pos >= len(self.ids) or self.ids[pos] != np.uint64(pid):
+ return -1
+ return pos
+
+ def extend(self, id2bytes: dict[int, bytes]) -> int:
+ """Append new patches (one-shot episodic learning).
+
+ Returns the number of patches added. Keeps arrays sorted.
+ """
+ if not id2bytes:
+ return 0
+ cand = np.array(sorted(id2bytes.keys()), dtype=np.uint64)
+ cand = cand[~self.has(cand)]
+ if len(cand) == 0:
+ return 0
+ n_old = len(self.ids)
+ merged = np.concatenate([self.ids, cand])
+ order = np.argsort(merged, kind="stable")
+ merged = merged[order]
+ old_lens = np.diff(self.offsets).astype(np.uint64)
+ new_lens = np.array([len(id2bytes[int(i)]) for i in cand], dtype=np.uint64)
+ old_off = self.offsets[:-1]
+ out = bytearray()
+ offsets = np.zeros(len(merged) + 1, dtype=np.uint64)
+ for k, idx in enumerate(order.tolist()):
+ if idx < n_old:
+ a, b = int(old_off[idx]), int(old_off[idx] + old_lens[idx])
+ out.extend(self.buffer[a:b])
+ else:
+ out.extend(id2bytes[int(cand[idx - n_old])])
+ offsets[k] = len(out)
+ offsets[-1] = len(out)
+ self.ids = merged
+ self.offsets = offsets
+ self.buffer = bytes(out)
+ self.counts = np.concatenate([self.counts, np.zeros(len(cand), dtype=np.uint32)])[order]
+ return len(cand)
+
+
+class SPIRA:
+ EPI_CAP_TOKENS = 2_000_000 # hippocampal episodic-trace ring cap
+
+ def __init__(self, cfg: SPIRAConfig) -> None:
+ self.cfg = cfg
+ self.ept = EPT(budget_bits=16.0, min_len=cfg.min_len, max_len=cfg.max_len, alpha=cfg.alpha)
+ self.core = SpikingCore(
+ d_in=cfg.d_in, k_in=cfg.k_in, n_res=cfg.n_res,
+ n_out=cfg.vocab_size + 1, seed=cfg.seed,
+ hier=cfg.hierarchy, n_g=cfg.n_g, win=cfg.win,
+ trace_taus=tuple(cfg.trace_taus), direct_input=cfg.direct_input,
+ direct_tau=cfg.direct_tau,
+ )
+ self._row_cache: dict[int, np.ndarray] = {}
+ self.am = Hippocampus(m=cfg.am_m, size=cfg.am_size, min_lanes=cfg.am_min_lanes)
+ self.registry = PatchRegistry()
+ self.vocab_ids: np.ndarray = np.zeros(0, dtype=np.uint64) # col -> id
+ self.n_out = cfg.vocab_size + 1
+ self.meta: dict = {}
+ # inference-time fusion calibration (variance matching): the raw slow
+ # readout operates at a different score scale than the fast one, so the
+ # top-down prior is rescaled by sigma_fast/sigma_slow — measured once
+ # on a reference stream (calibrate_fusion), never trained.
+ self.fusion: dict = {"scale": 1.0, "sigma_fast": None, "sigma_slow": None}
+ # episodic traces retained for hippocampal replay (CA3-style sequence
+ # store; the AM itself only keeps hashed associations)
+ self.episodes: list[np.ndarray] = []
+
+ # ================================================================ build
+ @classmethod
+ def build(cls, train_bytes: bytes, cfg: SPIRAConfig, log=print) -> "SPIRA":
+ m = cls(cfg)
+ fit_slice = train_bytes[: 2_000_000]
+ calib_slice = train_bytes[2_000_000: 2_400_000]
+ log("[spira] fitting EPT byte-level Markov model ...")
+ m.ept.fit(fit_slice)
+ if calib_slice:
+ budget = m.ept.calibrate(calib_slice, target_len=cfg.target_avg_len)
+ log(f"[spira] calibrated surprisal budget = {budget:.2f} bits "
+ f"(target avg patch len {cfg.target_avg_len})")
+ log("[spira] segmenting full train stream ...")
+ t0 = time.perf_counter()
+ patches = m.ept.segment(train_bytes)
+ ids = np.fromiter((fnv1a64(p) for p in patches), dtype=np.uint64, count=len(patches))
+ seg_s = time.perf_counter() - t0
+ st = m.ept.stats(patches)
+ log(f"[spira] {st['n_patches']} patches, avg len {st['avg_len']:.2f} B "
+ f"({st['bytes']/1e6:.1f} MB segmented in {seg_s:.1f}s, "
+ f"{st['bytes']/1e6/max(seg_s,1e-9):.2f} MB/s)")
+ uniq, cnt = np.unique(ids, return_counts=True)
+ log(f"[spira] distinct patches in train: {len(uniq)}")
+ # vocabulary: top-V by count (deterministic tie-break: larger id first)
+ order = np.lexsort((uniq, -cnt))[: cfg.vocab_size]
+ m.vocab_ids = np.sort(uniq[order]).astype(np.uint64)
+ # registry: vocab + anything with count >= 2 (repeatable content)
+ keep = set(m.vocab_ids.tolist()) | set(uniq[cnt >= 2].tolist())
+ log(f"[spira] building patch registry ({len(keep)} ids) ...")
+ m.registry = PatchRegistry.build(ids, patches, keep=keep)
+ m.meta = {
+ "train_bytes": len(train_bytes),
+ "n_patches": st["n_patches"],
+ "avg_patch_len": st["avg_len"],
+ "distinct_patches": int(len(uniq)),
+ "registry_size": len(m.registry),
+ "budget_bits": m.ept.budget_bits,
+ "segmentation_MB_per_s": st["bytes"] / 1e6 / max(seg_s, 1e-9),
+ }
+ m._ids_train = ids
+ m._patches_train = None # registry carries everything; free ~100MB
+ return m
+
+ # =========================================================== array prep
+ @staticmethod
+ def input_neurons_stream(ids: np.ndarray, d_in: int, k_in: int) -> np.ndarray:
+ """Vectorized input-neuron projection: (T, k_in) int32."""
+ T = len(ids)
+ out = np.empty((T, k_in), dtype=np.int32)
+ u64 = ids.astype(np.uint64)
+ for j in range(k_in):
+ salt = (0x51ED270B733D4C31 + j * 0x9E3779B97F4A7C15) & 0xFFFFFFFFFFFFFFFF
+ z = u64 ^ np.uint64(salt)
+ z = z + np.uint64(0x9E3779B97F4A7C15)
+ z = (z ^ (z >> np.uint64(30))) * np.uint64(0xBF58476D1CE4E5B9)
+ z = (z ^ (z >> np.uint64(27))) * np.uint64(0x94D049BB133111EB)
+ z = z ^ (z >> np.uint64(31))
+ out[:, j] = ((z >> np.uint64(32)) % np.uint64(d_in)).astype(np.int32)
+ return out
+
+ def cols_of(self, ids: np.ndarray) -> np.ndarray:
+ """Vocabulary column per patch id (UNK -> last column)."""
+ V = self.cfg.vocab_size
+ pos = np.searchsorted(self.vocab_ids, ids)
+ pos_c = np.minimum(pos, V - 1)
+ ok = (pos < V) & (self.vocab_ids[pos_c] == ids)
+ cols = np.where(ok, pos_c, V).astype(np.int64) # V = UNK column
+ return cols
+
+ # ------------------------------------------------------- v3 input rows
+ def _structured_row(self, pid: int, pbytes: bytes | None) -> np.ndarray:
+ """Input-neuron row for one patch: (k_in - k_tri) whole-patch hash
+ neurons + k_tri byte-trigram hash neurons. Patches sharing trigrams
+ share input neurons, so similar contexts produce similar reservoir
+ states (v1/v2 rows were pure whole-patch hashes: fully orthogonal).
+ Falls back to the v2 row when the patch bytes are unknown."""
+ from .hashing import fnv1a64, input_neurons, splitmix64
+ cfg = self.cfg
+ if not cfg.structured_inputs or pbytes is None:
+ return np.asarray(input_neurons(pid, cfg.d_in, cfg.k_in), dtype=np.int32)
+ k_whole = cfg.k_in - cfg.k_tri
+ row = list(input_neurons(pid, cfg.d_in, k_whole))
+ grams: set[bytes] = set()
+ if len(pbytes) >= 3:
+ grams = {pbytes[i:i + 3] for i in range(len(pbytes) - 2)}
+ elif len(pbytes) == 2:
+ grams = {pbytes}
+ cand = sorted({splitmix64(fnv1a64(g)) % cfg.d_in for g in grams})
+ tri = cand[: cfg.k_tri]
+ while len(tri) < cfg.k_tri: # short patches: fill from whole-hash salts
+ tri.append(int(input_neurons(pid, cfg.d_in, cfg.k_tri + len(tri))[-1]))
+ return np.asarray(row + tri, dtype=np.int32)
+
+ def neuron_rows(self, ids: np.ndarray, patches: list[bytes] | None = None) -> np.ndarray:
+ """(T, k_in) input rows; structured when enabled, v2-identical else."""
+ cfg = self.cfg
+ if not cfg.structured_inputs:
+ return self.input_neurons_stream(ids, cfg.d_in, cfg.k_in)
+ by_id: dict[int, bytes] = {}
+ if patches is not None:
+ for pid, pb in zip(ids.tolist(), patches):
+ by_id.setdefault(pid, pb)
+ rows = np.empty((len(ids), cfg.k_in), dtype=np.int32)
+ cache = self._row_cache
+ for t, pid in enumerate(ids.tolist()):
+ r = cache.get(pid)
+ if r is None:
+ pb = by_id.get(pid)
+ if pb is None:
+ pb = self.registry.bytes_of(pid)
+ r = self._structured_row(pid, pb)
+ cache[pid] = r
+ rows[t] = r
+ return rows
+
+ def prepare(self) -> None:
+ """Precompute training arrays for the SNN and AM subsets only."""
+ cfg = self.cfg
+ ids = self._ids_train
+ n_snn = min(cfg.snn_tokens, len(ids) - 1)
+ n_am = min(cfg.am_tokens, len(ids) - 1)
+ log = print
+ log(f"[spira] precomputing projections for {n_snn} SNN + {n_am} AM tokens ...")
+ t0 = time.perf_counter()
+ self._neurons = self.neuron_rows(ids[:n_snn])
+ self._cols = self.cols_of(ids[: n_snn + 1])
+ # AM: val = registry index of the NEXT token (skip unregistered)
+ am_ids = ids[:n_am]
+ reg_idx = np.full(n_am, -1, dtype=np.int64)
+ pos = np.searchsorted(self.registry.ids, am_ids)
+ pos_c = np.minimum(pos, len(self.registry.ids) - 1)
+ ok = (pos < len(self.registry.ids)) & (self.registry.ids[pos_c] == am_ids)
+ reg_idx[ok] = pos_c[ok]
+ self._reg_idx = reg_idx
+ ls = self.am.lane_keys_stream(am_ids)
+ # AM contexts (diagonal keys): ctx[r, l] = lane key of token r+l at
+ # slot l; the context ending at t = r+m-1 continues with token r+m.
+ m = self.am.m
+ n_ctx = len(ls) - m
+ ctx = np.empty((n_ctx, m), dtype=np.uint32)
+ for lane in range(m):
+ ctx[:, lane] = ls[lane : lane + n_ctx, lane]
+ self._am_ctx = ctx
+ log(f" done in {time.perf_counter()-t0:.1f}s")
+
+ # ================================================================ train
+ def train(self, log_fn=print, ckpt_path: str | None = None) -> dict:
+ cfg = self.cfg
+ n_snn = len(self._neurons)
+ n_ctx_am = len(self._am_ctx)
+ history = {"epochs": []}
+ for ep in range(cfg.epochs):
+ log_fn(f"[spira] === SNN epoch {ep+1}/{cfg.epochs} ({n_snn} ticks) ===")
+ res = self.core.train_pass(
+ self._neurons[:n_snn], self._cols[1 : n_snn + 1],
+ log_every=10_000,
+ log_fn=lambda d, ep=ep: log_fn(
+ f" tick {d['tick']}/{d['total']} acc={d['acc_ema']:.3f} "
+ f"dop={d['dopamine_ema']:+.3f} {d['ticks_per_sec']:.0f} t/s"),
+ record_raster_from=(n_snn - 1500 if ep == cfg.epochs - 1 else None),
+ )
+ raster = res.pop("raster", None)
+ if raster and ckpt_path:
+ ticks = np.concatenate([np.full(len(sp), t, dtype=np.int32) for t, sp in raster])
+ neurons_r = np.concatenate([sp for _, sp in raster]).astype(np.int32)
+ np.savez_compressed(ckpt_path + ".raster.npz", ticks=ticks, neurons=neurons_r)
+ history["epochs"].append({k: v for k, v in res.items()})
+ if ckpt_path:
+ self.save(ckpt_path)
+ # hippocampal one-shot pass over the (larger) AM stream
+ log_fn(f"[spira] === hippocampus one-shot write pass ({n_ctx_am} contexts) ===")
+ t0 = time.perf_counter()
+ m = self.am.m
+ ctx = self._am_ctx[:n_ctx_am]
+ vals = self._ids_train[m : m + n_ctx_am].astype(np.uint64)
+ self.am.write_stream(ctx, vals)
+ log_fn(f" wrote {n_ctx_am} associations in "
+ f"{time.perf_counter()-t0:.1f}s; {self.am.stats()}")
+ history["am"] = self.am.stats()
+ if ckpt_path:
+ self.save(ckpt_path)
+ return history
+
+ # =============================================================== predict
+ def _scores(self, x: np.ndarray) -> np.ndarray:
+ """Behavioural scores: fast readout + variance-matched top-down slow
+ prior (if the hierarchical cortex is active). No hippocampal vote."""
+ u = (x - self.core.x_mean) @ self.core.W_out
+ if self.core.hier:
+ u = u + np.float32(self.core.beta * self.fusion["scale"]) * self.core.u_slow
+ return u
+
+ def calibrate_fusion(self, data: bytes, n_tokens: int = 3000) -> dict:
+ """Measure fast/slow readout score scales on a reference stream and set
+ the fusion normalization sigma_fast/sigma_slow.
+
+ The slow readout's raw scores live at a different (much larger) scale
+ than the fast one; fusing them raw lets even a tiny beta swamp the fast
+ argmax. Variance matching bounds the top-down prior's contribution to
+ beta * sigma_fast — the same units the fast readout itself uses. Pure
+ measurement, no plasticity (same spirit as the EPT budget calibration).
+ """
+ patches = self.ept.segment(data)
+ ids = np.fromiter((fnv1a64(p) for p in patches), dtype=np.uint64,
+ count=len(patches))[: n_tokens + 1]
+ neurons = self.neuron_rows(ids[:-1], patches[:-1])
+ snap = self.core.snapshot()
+ w_rec_snap = self.core.W_rec.copy()
+ self.core.reset_dynamics()
+ self._win_count = 0
+ sig_f: list[float] = []
+ sig_s: list[float] = []
+ for t in range(len(ids) - 1):
+ x = self.core.step(neurons[t])
+ if self.core.hier:
+ self._win_count += 1
+ if self._win_count % self.core.win == 0:
+ self.core.step_G()
+ if len(sig_s) < 400 or len(sig_s) % 8 == 0:
+ sig_s.append(float(np.std(self.core.u_slow)))
+ u_fast = (x - self.core.x_mean) @ self.core.W_out
+ if len(sig_f) < 400 or len(sig_f) % 8 == 0:
+ sig_f.append(float(np.std(u_fast)))
+ self.core.restore(snap)
+ self.core.W_rec = w_rec_snap
+ sf = float(np.mean(sig_f)) if sig_f else 1.0
+ ss = float(np.mean(sig_s)) if sig_s else 1.0
+ self.fusion = {"scale": sf / max(ss, 1e-9), "sigma_fast": sf, "sigma_slow": ss}
+ return dict(self.fusion)
+
+ def _feed(self, pid: int) -> np.ndarray:
+ """Feed one token: fast step (+ slow step at window boundaries)."""
+ x = self.core.step(self._neuron_row(pid))
+ if self.core.hier:
+ self._win_count += 1
+ if self._win_count % self.core.win == 0:
+ self.core.step_G()
+ return x
+
+ def _col_of_id(self, pid: int) -> int | None:
+ """Vocab column of a patch id, or None if out of vocabulary."""
+ V = self.cfg.vocab_size
+ col = int(np.searchsorted(self.vocab_ids, np.uint64(pid)))
+ if col < V and self.vocab_ids[col] == np.uint64(pid):
+ return col
+ return None
+
+ def fuse_scores(self, x: np.ndarray, last_ids: list[int]):
+ """Combine behavioural scores (fast + top-down slow prior) with a
+ hippocampal vote.
+
+ Returns (fused_scores, am_val, am_weight, bypass_id).
+ """
+ u = self._scores(x)
+ am_val, am_w = None, 0.0
+ bypass_id = None
+ if len(last_ids) >= self.am.m:
+ lanes = self.am.lane_keys(last_ids[-self.am.m :])
+ am_val, am_w = self.am.query(lanes)
+ if am_val is None:
+ return u, am_val, am_w, None
+ pid = int(am_val)
+ col = self._col_of_id(pid)
+ if col is not None:
+ fused = u.copy()
+ fused[col] += self.cfg.beta_am * am_w
+ return fused, am_val, am_w, None
+ if am_w >= self.cfg.am_override and self.registry.bytes_of(pid) is not None:
+ bypass_id = pid # strong episodic recall outside vocabulary
+ return u, am_val, am_w, bypass_id
+
+ def generate(self, prompt: bytes, n_tokens: int = 120, temperature: float | None = None,
+ top_k: int | None = None, use_am: bool = True, seed: int | None = None,
+ on_token=None) -> bytes:
+ """Closed-loop generation: predicted patches are fed back as spikes."""
+ cfg = self.cfg
+ temperature = cfg.temperature if temperature is None else temperature
+ top_k = cfg.top_k if top_k is None else top_k
+ rng = np.random.default_rng(seed if seed is not None else int(time.time_ns() & 0x7FFFFFFF))
+ self.core.reset_dynamics()
+ self._win_count = 0
+ patches = self.ept.segment(prompt)
+ if not patches:
+ return prompt
+ ids = [fnv1a64(p) for p in patches]
+ out = bytearray(prompt)
+ V = cfg.vocab_size
+ UNK = V # UNK column index
+ # warm-up: feed the entire prompt (state now reflects the last patch)
+ x = np.zeros(self.core.n_res, dtype=np.float32)
+ for pid in ids:
+ x = self._feed(pid)
+ for step in range(n_tokens):
+ if use_am:
+ fused, am_val, am_w, bypass_id = self.fuse_scores(x, ids)
+ else:
+ fused, bypass_id = self._scores(x), None
+ if bypass_id is not None:
+ chosen_id = bypass_id
+ else:
+ scores = np.asarray(fused, dtype=np.float64).copy()
+ scores[UNK] = -np.inf # cannot emit UNK bytes
+ k = max(1, min(top_k, V))
+ top = np.argpartition(scores, -k)[-k:]
+ z = (scores[top] - scores[top].max()) / max(temperature, 1e-6)
+ w = np.exp(z)
+ w /= w.sum()
+ pick = int(top[rng.choice(len(top), p=w)])
+ chosen_id = int(self.vocab_ids[pick])
+ b = self.registry.bytes_of(chosen_id)
+ if b is None:
+ break # unknown emission: stop rather than corrupt
+ out.extend(b)
+ ids.append(chosen_id)
+ x = self._feed(chosen_id)
+ if on_token is not None:
+ on_token(step, b)
+ return bytes(out)
+
+ def _neuron_row(self, pid: int) -> np.ndarray:
+ r = self._row_cache.get(pid)
+ if r is None:
+ r = self._structured_row(pid, self.registry.bytes_of(pid))
+ self._row_cache[pid] = r
+ return r
+
+ # ============================================================= one-shot
+ def teach_bytes(self, data: bytes) -> dict:
+ """ONE-SHOT episodic teaching: segment, register unseen patches, and
+ write every context -> continuation into the hippocampus — a single
+ pass, no gradients, no epochs, no repetition."""
+ patches = self.ept.segment(data)
+ ids = np.fromiter((fnv1a64(p) for p in patches), dtype=np.uint64, count=len(patches))
+ return self.teach_ids(ids, patches)
+
+ def teach_ids(self, ids: np.ndarray, patches: list[bytes] | None = None,
+ episodic: bool = True) -> dict:
+ n = len(ids)
+ # 0) retain the episodic trace for hippocampal replay (the sequence
+ # the cortex will re-run during "sleep") — only for genuinely
+ # episodic teaching, not for the corpus baseline fill
+ if episodic:
+ self._remember_episode(ids)
+ # 1) register unseen patches so continuations are always storable
+ known = self.registry.has(ids)
+ if patches is not None:
+ new_map: dict[int, bytes] = {}
+ for i, b in zip(ids[~known].tolist(), (p for p, k in zip(patches, known) if not k)):
+ if i not in new_map:
+ new_map[i] = b
+ n_new = self.registry.extend(new_map)
+ else:
+ n_new = 0
+ # 2) write associations (vals are stable patch ids)
+ lane = self.am.lane_keys_stream(ids)
+ m = self.am.m
+ n_ctx = n - m
+ ctx = np.empty((n_ctx, m), dtype=np.uint32)
+ for li in range(m):
+ ctx[:, li] = lane[li : li + n_ctx, li]
+ vals = ids[m : m + n_ctx].astype(np.uint64)
+ self.am.write_stream(ctx, vals)
+ return {
+ "tokens": int(n),
+ "new_patches": int(n_new),
+ "associations": int(n_ctx),
+ "episode_tokens": int(n),
+ }
+
+ # ================================================================ replay
+ def _remember_episode(self, ids: np.ndarray) -> None:
+ """Append to the hippocampal episodic trace (ring-capped)."""
+ if len(ids) < 2:
+ return
+ self.episodes.append(np.asarray(ids, dtype=np.uint64))
+ total = sum(len(e) for e in self.episodes)
+ while total > self.EPI_CAP_TOKENS and len(self.episodes) > 1:
+ total -= len(self.episodes[0])
+ self.episodes.pop(0)
+
+ def replay(self, n_tokens: int | None = None, slice_len: int | None = None,
+ seed: int = 0, log=print) -> dict:
+ """Hippocampal replay -> cortical consolidation (closing the loop).
+
+ Random slices of the episodic traces retained by the hippocampus are
+ re-run through the cortex in full training mode: the same local rules
+ (three-factor readout delta, modulated recurrent STDP, dopaminergic
+ RPE, slow-area learning) now act on material the cortex never saw
+ externally. One-shot memories are gradually consolidated into slow
+ cortical weights — the complementary-systems loop, closed.
+
+ Biologically this is Sharpewave-ripple-like offline replay: the cortex
+ does not re-run isolated (context -> continuation) pairs but short
+ SEQUENCES, so reservoir state statistics match the awake stream.
+ """
+ cfg = self.cfg
+ n_tokens = cfg.replay_tokens if n_tokens is None else n_tokens
+ slice_len = cfg.replay_slice if slice_len is None else slice_len
+ if not self.episodes:
+ return {"replayed_tokens": 0, "note": "no episodic traces to replay"}
+ rng = np.random.default_rng(seed)
+ weights = np.array([len(e) for e in self.episodes], dtype=np.float64)
+ weights /= weights.sum()
+ chunks: list[np.ndarray] = []
+ got = 0
+ while got < n_tokens:
+ e = self.episodes[int(rng.choice(len(self.episodes), p=weights))]
+ start = int(rng.integers(0, max(1, len(e) - slice_len)))
+ take = min(slice_len, len(e) - start)
+ chunks.append(e[start : start + take])
+ got += take
+ ids = np.concatenate(chunks)
+ neurons = self.neuron_rows(ids[:-1])
+ cols = self.cols_of(ids)[1:]
+ log(f"[replay] re-running {len(ids)} cortical tokens sampled from "
+ f"{len(self.episodes)} episodic trace(s) (slice {slice_len})")
+ res = self.core.train_pass(
+ neurons, cols, log_every=25_000,
+ log_fn=lambda d: log(f" tick {d['tick']}/{d['total']} acc={d['acc_ema']:.3f} "
+ f"beta={d.get('beta')} {d['ticks_per_sec']:.0f} t/s"),
+ )
+ res.pop("raster", None)
+ return {"replayed_tokens": int(len(ids)), **res}
+
+ # ================================================================ eval
+ def eval_stream(self, data: bytes, use_am: bool = True, teach_am_first: bool = False,
+ corrupt_lanes: int = 0, seed: int = 0, max_positions: int | None = None) -> dict:
+ """Evaluate next-patch prediction on a byte stream.
+
+ Metrics for the SNN readout alone, the hippocampus alone, and the
+ fused system — both over all positions and over in-vocab targets only
+ (targets outside the readout vocabulary cannot be predicted by the
+ readout, but the hippocampus can still retrieve them).
+ """
+ from .hashing import lane_key32
+ patches = self.ept.segment(data)
+ ids = np.fromiter((fnv1a64(p) for p in patches), dtype=np.uint64, count=len(patches))
+ n = len(ids)
+ cols = self.cols_of(ids)
+ V = self.cfg.vocab_size
+ if teach_am_first:
+ # ONE-SHOT teaching pass (registers new patches too)
+ taught = self.teach_ids(ids, patches)
+ # SNN inference pass in the TRAINING regime: the reservoir keeps its
+ # modulated-STDP plasticity (the operating point is part of the
+ # learned system) while the readout stays frozen for measurement.
+ snap = self.core.snapshot()
+ w_rec_snap = self.core.W_rec.copy()
+ neurons = self.neuron_rows(ids, patches)
+ lane = self.am.lane_keys_stream(ids)
+ # diagonal context-key stream: ctxq[r] = key of context tokens r..r+m-1
+ m_ctx = self.am.m
+ n_ctxq = n - m_ctx + 1
+ ctxq = np.empty((n_ctxq, m_ctx), dtype=np.uint32)
+ for li in range(m_ctx):
+ ctxq[:, li] = lane[li : li + n_ctxq, li]
+ rng = np.random.default_rng(seed)
+ train_ids = self._ids_train if hasattr(self, "_ids_train") else ids
+ tot = inv = 0
+ snn_ok = snn_ok_inv = am_ok = am_ok_inv = fused_ok = fused_ok_inv = 0
+ hier_ok = hier_ok_inv = 0
+ stop = n - 1 if max_positions is None else min(n - 1, max_positions)
+ x = np.zeros(self.core.n_res, dtype=np.float32)
+ for t in range(stop):
+ x = self.core.step(neurons[t])
+ target_col = int(cols[t + 1])
+ target_id = int(ids[t + 1])
+ u_fast = (x - self.core.x_mean) @ self.core.W_out
+ if self.core.hier:
+ u = u_fast + np.float32(self.core.beta * self.fusion["scale"]) * self.core.u_slow
+ hier_pred = int(np.argmax(u[:V])) # cortex (fast + top-down)
+ else:
+ u = u_fast
+ hier_pred = None
+ pred = int(np.argmax(u_fast[:V])) # fast-area-only ablation
+ # keep training-regime reservoir dynamics (readout frozen)
+ self.core.learn_reservoir(hier_pred if hier_pred is not None else pred,
+ target_col, x, u=u_fast)
+ if self.core.hier and (t + 1) % self.core.win == 0:
+ self.core.step_G()
+ # hippocampal query with optional context corruption
+ am_val, am_w = None, 0.0
+ if use_am and t >= m_ctx - 1:
+ ctx_lane = ctxq[t - m_ctx + 1].copy()
+ if corrupt_lanes > 0:
+ pidxs = rng.choice(m_ctx, size=min(corrupt_lanes, m_ctx), replace=False)
+ for pidx in pidxs:
+ rand_id = int(train_ids[rng.integers(0, len(train_ids))])
+ ctx_lane[pidx] = lane_key32(rand_id, int(pidx))
+ am_val, am_w = self.am.query(ctx_lane)
+ am_id = int(am_val) if am_val is not None else None
+ am_hit = am_id == target_id
+ # fused prediction (hierarchical cortex + hippocampal vote)
+ fused_pred, bypass = (hier_pred if hier_pred is not None else pred), False
+ if am_id is not None:
+ col = self._col_of_id(am_id)
+ if col is not None:
+ fused = u.copy()
+ fused[col] += self.cfg.beta_am * am_w
+ fused_pred = int(np.argmax(fused))
+ elif am_w >= self.cfg.am_override:
+ bypass = True
+ fused_hit = am_hit if bypass else (fused_pred == target_col)
+ tot += 1
+ if target_col != V:
+ inv += 1
+ if pred == target_col:
+ snn_ok_inv += 1
+ if hier_pred is not None and hier_pred == target_col:
+ hier_ok_inv += 1
+ if am_hit:
+ am_ok_inv += 1
+ if fused_hit:
+ fused_ok_inv += 1
+ if pred == target_col:
+ snn_ok += 1
+ if hier_pred is not None and hier_pred == target_col:
+ hier_ok += 1
+ if am_hit:
+ am_ok += 1
+ if fused_hit:
+ fused_ok += 1
+ self.core.restore(snap)
+ self.core.W_rec = w_rec_snap
+ return {
+ "n_positions": tot,
+ "vocab_coverage": inv / max(tot, 1),
+ "snn_acc": snn_ok / max(tot, 1),
+ "hier_acc": hier_ok / max(tot, 1),
+ "am_acc": am_ok / max(tot, 1),
+ "fused_acc": fused_ok / max(tot, 1),
+ "snn_acc_invocab": snn_ok_inv / max(inv, 1),
+ "hier_acc_invocab": hier_ok_inv / max(inv, 1),
+ "am_acc_invocab": am_ok_inv / max(inv, 1),
+ "fused_acc_invocab": fused_ok_inv / max(inv, 1),
+ "corrupt_lanes": corrupt_lanes,
+ }
+
+ # =========================================================== save/load
+ def save(self, path: str, am_cap: int = 1_500_000) -> None:
+ """Checkpoint everything. ALL hippocampal entries are packed (a
+ one-shot episodic memory must persist single-occurrence traces!) in a
+ single memory-frugal pass.
+
+ AM packing dedups EXACTLY: every slot an entry occupies is derivable
+ from its key (primary full-key hash + leave-one-out hashes), so each
+ logical entry is packed once with its surviving copies marked.
+ """
+ from array import array
+ cfg = self.cfg
+ am = self.am
+ visited = np.zeros(am.size, dtype=np.bool_)
+ keys_buf = array("I")
+ vals_buf = array("Q")
+ counts_buf = array("B")
+ for addr in np.nonzero(am.used)[0]:
+ if visited[addr]:
+ continue
+ k = am.keys[addr]
+ c = int(am.counts[addr])
+ for a in am._slots_of(k):
+ if am.used[a] and np.array_equal(am.keys[a], k):
+ visited[a] = True
+ keys_buf.extend(k.tolist())
+ vals_buf.append(int(am.vals[addr]))
+ counts_buf.append(min(c, 255))
+ if len(vals_buf) >= am_cap:
+ break
+ n_e = len(vals_buf)
+ if n_e == 0:
+ am_keys = np.zeros((0, am.m), dtype=np.uint32)
+ am_vals = np.zeros(0, dtype=np.uint64)
+ am_counts = np.zeros(0, dtype=np.uint8)
+ else:
+ am_keys = np.frombuffer(keys_buf, dtype=np.uint32).reshape(n_e, am.m).copy()
+ am_vals = np.frombuffer(vals_buf, dtype=np.uint64).copy()
+ am_counts = np.frombuffer(counts_buf, dtype=np.uint8).copy()
+ np.savez_compressed(
+ path,
+ config=json.dumps(asdict(cfg)),
+ meta=json.dumps(self.meta),
+ fusion=json.dumps(self.fusion),
+ log2p=self.ept.log2p,
+ ept_params=np.array([self.ept.budget_bits, self.ept.min_len, self.ept.max_len, self.ept.alpha]),
+ W_rec=self.core.W_rec, W_out=self.core.W_out,
+ W_out_G=(self.core.W_outG if self.core.hier
+ else np.zeros((0, 0), dtype=np.float32)),
+ inhibitory=self.core.inhibitory,
+ vocab_ids=self.vocab_ids,
+ reg_ids=self.registry.ids, reg_offsets=self.registry.offsets,
+ reg_counts=self.registry.counts,
+ reg_buffer=np.frombuffer(self.registry.buffer, dtype=np.uint8),
+ am_keys=am_keys, am_vals=am_vals, am_counts=am_counts,
+ core_state=json.dumps({
+ k: (v if isinstance(v, float) else v.tolist())
+ for k, v in self.core.snapshot().items()
+ }),
+ )
+
+ @classmethod
+ def load(cls, path: str) -> "SPIRA":
+ z = np.load(path, allow_pickle=False)
+ cfg = SPIRAConfig(**json.loads(str(z["config"])))
+ m = cls(cfg)
+ if "fusion" in z:
+ m.fusion = json.loads(str(z["fusion"]))
+ m.ept.log2p = z["log2p"].astype(np.float32)
+ p = z["ept_params"]
+ m.ept.budget_bits, m.ept.min_len, m.ept.max_len, m.ept.alpha = (float(p[0]), int(p[1]), int(p[2]), float(p[3]))
+ m.core.W_rec = z["W_rec"].astype(np.float32)
+ m.core.W_out = z["W_out"].astype(np.float32)
+ m.core.inhibitory = z["inhibitory"].astype(np.bool_)
+ w_rec_max = 3.0 * m.core.w_rec_scale
+ m.core._rec_lo = np.where(m.core.inhibitory, -w_rec_max, 0.0).astype(np.float32)
+ m.core._rec_hi = np.where(m.core.inhibitory, 0.0, w_rec_max).astype(np.float32)
+ if "W_out_G" in z and cfg.hierarchy and z["W_out_G"].size > 0:
+ m.core.W_outG = z["W_out_G"].astype(np.float32)
+ else:
+ # v1 checkpoint: hierarchy absent — disable the slow area
+ cfg.hierarchy = False
+ m.core.hier = False
+ m.core.W_outG = None
+ m.core.reset()
+ if "core_state" in z:
+ st = json.loads(str(z["core_state"]))
+ restored = {}
+ for k, v in st.items():
+ if k in ("baseline", "beta"):
+ restored[k] = float(v)
+ else:
+ restored[k] = np.asarray(v, dtype=np.float32 if k not in ("refr",) else np.int8)
+ m.core.restore(restored)
+ m.vocab_ids = z["vocab_ids"].astype(np.uint64)
+ m.registry.ids = z["reg_ids"].astype(np.uint64)
+ m.registry.offsets = z["reg_offsets"].astype(np.uint64)
+ m.registry.counts = z["reg_counts"].astype(np.uint32)
+ m.registry.buffer = z["reg_buffer"].tobytes()
+ m.meta = json.loads(str(z["meta"]))
+ # rebuild hippocampus from packed entries: each entry returns to its
+ # derivable slots (primary full-key + leave-one-out), with the same
+ # best-effort collision policy as a live write — entries whose slots
+ # are taken by a different key are simply not redundantly copied.
+ keys = z["am_keys"]; vals = z["am_vals"]; counts = z["am_counts"]
+ am = m.am
+ for i in range(len(vals)):
+ k, v, c = keys[i], int(vals[i]), int(counts[i])
+ paddr = am.primary_addr(k)
+ if not am.used[paddr] or np.array_equal(am.keys[paddr], k):
+ am.keys[paddr] = k
+ am.vals[paddr] = v
+ am.counts[paddr] = c
+ am.used[paddr] = True
+ for lane in range(am.m):
+ addr = am.loo_addr(k, lane)
+ if not am.used[addr]:
+ am.keys[addr] = k
+ am.vals[addr] = v
+ am.counts[addr] = c
+ am.used[addr] = True
+ return m
diff --git a/results/hashing/lever2_sparse/code/python/spira/spiking.py b/results/hashing/lever2_sparse/code/python/spira/spiking.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ef5d95bae9f5c3a683ee1d5af4e857331ad0eea
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/python/spira/spiking.py
@@ -0,0 +1,599 @@
+"""Spiking core: LIF reservoir + reward-modulated (three-factor) readout.
+
+Paradigm properties — no backpropagation, no gradients, no autodiff:
+ * Leaky integrate-and-fire (LIF) neurons with refractory periods and
+ homeostatic adaptive thresholds;
+ * Dale's law: each reservoir neuron is permanently excitatory or
+ inhibitory (20% inhibitory);
+ * Readout learning is a three-factor rule: eligibility (Hebbian pre/post
+ coincidence = reservoir trace x outcome) gated by a dopaminergic reward
+ prediction error d = r - baseline(r);
+ * Recurrent synapses follow a light reward-modulated STDP (trace-based),
+ sign-constrained to respect Dale's law;
+ * One simulation tick = one token (event-time, not wall-clock ms).
+
+All weights are constructed deterministically from a seeded mulberry32 PRNG
+so the TypeScript port regenerates bit-identical connectivity.
+"""
+from __future__ import annotations
+
+import numpy as np
+
+from .hashing import Mulberry32
+
+
+class SpikingCore:
+ def __init__(
+ self,
+ d_in: int = 1024,
+ k_in: int = 12,
+ n_res: int = 512,
+ n_out: int = 4097, # 4096 vocab + 1 UNK column
+ seed: int = 20261022,
+ in_fanout: int = 8,
+ rec_fanout: int = 24,
+ inh_frac: float = 0.50,
+ lam: float = 0.85, # membrane leak
+ base_thr: float = 1.0,
+ thr_min: float = 0.4,
+ thr_max: float = 8.0,
+ refrac: int = 2, # ticks
+ tau_trace: float = 0.40, # reservoir spike-trace decay
+ w_in_scale: float = 3.0,
+ w_rec_scale: float = 0.25,
+ w_clip: float = 4.0,
+ eta_delta: float = 0.5, # local Rescorla-Wagner delta rate (LMS-normalized)
+ eta_stdp: float = 0.0015, # recurrent modulated STDP rate
+ eta_homeo: float = 0.002, # adaptive-threshold rate
+ target_rate: float = 0.06, # target per-neuron firing probability/tick
+ baseline_momentum: float = 0.995,
+ # ---- hierarchical slow area G (multi-scale cortex, v2) ----
+ hier: bool = True,
+ n_g: int = 256, # slow-area neurons
+ win: int = 8, # fast ticks per slow step
+ w_g_scale: float = 6.0, # L -> G feedforward weight scale
+ w_recg_scale: float = 0.15, # G recurrent scale (fixed, no STDP)
+ lam_g: float = 0.6, # slow-area membrane leak
+ tau_trace_g: float = 0.5, # slow-area spike-trace decay
+ target_rate_g: float = 0.10, # target firing per slow step
+ eta_homeo_g: float = 0.01,
+ eta_delta_g: float = 2.0, # slow-readout delta rate (8x fewer updates)
+ eta_beta: float = 0.02, # top-down gain learning rate
+ beta_init: float = 0.25,
+ beta_max: float = 2.0,
+ # ---- v3 (Muse): multi-timescale traces + direct input pathway ----
+ trace_taus: tuple = (0.4,), # reservoir trace decays; readout sees ALL banks
+ direct_input: bool = False, # readout also sees a decayed trace of the
+ # exact input-neuron pattern (ESN-standard
+ # [state; input] readout, omitted in v1/v2)
+ direct_tau: float = 0.5, # decay of the direct input trace
+ direct_gain: float = 1.0,
+ ) -> None:
+ self.d_in, self.k_in, self.n_res, self.n_out = d_in, k_in, n_res, n_out
+ self.seed = seed
+ self.in_fanout, self.rec_fanout = in_fanout, rec_fanout
+ self.inh_frac = inh_frac
+ self.lam, self.base_thr = lam, base_thr
+ self.thr_min, self.thr_max = thr_min, thr_max
+ self.refrac = refrac
+ self.tau_trace = tau_trace
+ self.w_in_scale, self.w_rec_scale = w_in_scale, w_rec_scale
+ self.w_clip = w_clip
+ self.eta_delta, self.eta_stdp = eta_delta, eta_stdp
+ self.eta_homeo, self.target_rate = eta_homeo, target_rate
+ self.baseline_momentum = baseline_momentum
+ self.hier = hier
+ self.n_g, self.win = n_g, win
+ self.w_g_scale, self.w_recg_scale = w_g_scale, w_recg_scale
+ self.lam_g, self.tau_trace_g = lam_g, tau_trace_g
+ self.target_rate_g, self.eta_homeo_g = target_rate_g, eta_homeo_g
+ self.eta_delta_g = eta_delta_g
+ self.eta_beta, self.beta0, self.beta_max = eta_beta, beta_init, beta_max
+ # v3 structural params
+ self.trace_taus = tuple(float(t) for t in trace_taus)
+ self.direct_input = bool(direct_input)
+ self.direct_tau, self.direct_gain = float(direct_tau), float(direct_gain)
+ self.n_banks = len(self.trace_taus)
+ self.n_state = self.n_res * self.n_banks + (self.d_in if self.direct_input else 0)
+
+ # ------------------------------------------------ deterministic wiring
+ rng = Mulberry32(seed)
+ # Input -> reservoir: sparse fan-out per input neuron, dense storage.
+ self.W_in = np.zeros((d_in, n_res), dtype=np.float32)
+ for i in range(d_in):
+ for _ in range(in_fanout):
+ t = int(rng.next_float() * n_res)
+ self.W_in[i, t] += rng.next_weight(w_in_scale)
+ # Reservoir recurrent: sparse fan-out per source, Dale's law by source.
+ self.W_rec = np.zeros((n_res, n_res), dtype=np.float32)
+ self.inhibitory = np.zeros(n_res, dtype=np.bool_)
+ w_rec_max = 3.0 * w_rec_scale
+ for j in range(n_res):
+ is_inh = rng.next_float() < inh_frac
+ self.inhibitory[j] = is_inh
+ sign = -1.0 if is_inh else 1.0
+ for _ in range(rec_fanout):
+ t = int(rng.next_float() * n_res)
+ self.W_rec[j, t] += sign * abs(rng.next_weight(w_rec_scale))
+ # Keep Dale's law under plasticity:
+ # excitatory rows clipped to [0, w_rec_max], inhibitory to [-w_rec_max, 0]
+ self._rec_lo = np.where(self.inhibitory, -w_rec_max, 0.0).astype(np.float32)
+ self._rec_hi = np.where(self.inhibitory, 0.0, w_rec_max).astype(np.float32)
+ self.W_rec = np.clip(self.W_rec, self._rec_lo[:, None], self._rec_hi[:, None])
+
+ # Readout: small seeded init, learned by the three-factor rule.
+ rng2 = Mulberry32(seed + 1)
+ self.W_out = np.zeros((self.n_state, n_out), dtype=np.float32) # v3: n_state rows
+ # sparse-ish init: each column connected from a random 25% of neurons
+ for c in range(n_out):
+ for _ in range(n_res // 4):
+ r = int(rng2.next_float() * n_res)
+ self.W_out[r, c] += rng2.next_weight(0.05)
+
+ # ------------------------------------------ slow area G (hierarchy)
+ # Wired from SEPARATE PRNG streams (seed+2 / seed+3) so the fast-area
+ # sequences above are byte-identical to v1 — the TS port depends on
+ # the exact call order.
+ if hier:
+ rng3 = Mulberry32(seed + 2)
+ # L -> G: per fast-source fanout 2. Sign follows Dale's law of the
+ # PRESYNAPTIC fast neuron: excitatory cells excite G, inhibitory
+ # cells inhibit it (G sees the pooled fast spike volley).
+ self.W_inG = np.zeros((n_res, n_g), dtype=np.float32)
+ for i in range(n_res):
+ sign = -1.0 if self.inhibitory[i] else 1.0
+ for _ in range(2):
+ t = int(rng3.next_float() * n_g)
+ self.W_inG[i, t] += sign * abs(rng3.next_weight(w_g_scale))
+ # G recurrent: sparse, Dale by source, FIXED (slower areas
+ # plasticize slower — G plasticity lives in its readout only)
+ self.W_recG = np.zeros((n_g, n_g), dtype=np.float32)
+ g_rec_max = 3.0 * w_recg_scale
+ self.inhibitory_g = np.zeros(n_g, dtype=np.bool_)
+ for j in range(n_g):
+ is_inh = rng3.next_float() < 0.5
+ self.inhibitory_g[j] = is_inh
+ sign = -1.0 if is_inh else 1.0
+ for _ in range(8):
+ t = int(rng3.next_float() * n_g)
+ self.W_recG[j, t] += sign * abs(rng3.next_weight(w_recg_scale))
+ self._recg_lo = np.where(self.inhibitory_g, -g_rec_max, 0.0).astype(np.float32)
+ self._recg_hi = np.where(self.inhibitory_g, 0.0, g_rec_max).astype(np.float32)
+ self.W_recG = np.clip(self.W_recG, self._recg_lo[:, None], self._recg_hi[:, None])
+ # G readout: same seeded sparse init pattern as the fast readout
+ rng4 = Mulberry32(seed + 3)
+ self.W_outG = np.zeros((n_g, n_out), dtype=np.float32)
+ for c in range(n_out):
+ for _ in range(n_g // 4):
+ r = int(rng4.next_float() * n_g)
+ self.W_outG[r, c] += rng4.next_weight(0.05)
+
+ self.reset()
+
+ # ----------------------------------------------------------------- state
+ def reset(self) -> None:
+ self.v = np.zeros(self.n_res, dtype=np.float32)
+ self.thr = np.full(self.n_res, self.base_thr, dtype=np.float32)
+ self.rhat = np.full(self.n_res, self.target_rate, dtype=np.float32)
+ self.refr = np.zeros(self.n_res, dtype=np.int8)
+ self.x = np.zeros(self.n_state, dtype=np.float32) # v3: augmented readout state
+ self.x_prev = np.zeros(self.n_res, dtype=np.float32) # reservoir trace t-1 (STDP)
+ self.x_mean = np.zeros(self.n_state, dtype=np.float32)
+ self.x_eff = np.zeros(self.n_state, dtype=np.float32)
+ self._banks = np.zeros((self.n_banks, self.n_res), dtype=np.float32)
+ self._direct = np.zeros(self.d_in if self.direct_input else 0, dtype=np.float32)
+ self.s = np.zeros(self.n_res, dtype=np.float32) # last spike vector
+ self.baseline = 0.0
+ self.tick = 0
+ if self.hier:
+ self.v_G = np.zeros(self.n_g, dtype=np.float32)
+ self.thr_G = np.full(self.n_g, self.base_thr, dtype=np.float32)
+ self.rhat_G = np.full(self.n_g, self.target_rate_g, dtype=np.float32)
+ self.x_G = np.zeros(self.n_g, dtype=np.float32)
+ self.x_mean_G = np.zeros(self.n_g, dtype=np.float32)
+ self.s_G = np.zeros(self.n_g, dtype=np.float32)
+ self.win_spikes = np.zeros(self.n_res, dtype=np.float32)
+ self.u_slow = np.zeros(self.n_out, dtype=np.float32)
+ self.beta = self.beta0
+
+ # ------------------------------------------------------------- snapshots
+ def snapshot(self) -> dict:
+ """Full dynamical state (the homeostatic scalars are LEARNED state —
+ thresholds and the trace mean co-adapt with the readout)."""
+ d = {
+ "v": self.v.copy(), "thr": self.thr.copy(), "rhat": self.rhat.copy(),
+ "refr": self.refr.copy(), "x": self.x.copy(), "x_prev": self.x_prev.copy(),
+ "x_mean": self.x_mean.copy(), "s": self.s.copy(), "baseline": self.baseline,
+ "banks": self._banks.copy(), "direct": self._direct.copy(),
+ }
+ if self.hier:
+ d.update({
+ "v_G": self.v_G.copy(), "thr_G": self.thr_G.copy(),
+ "rhat_G": self.rhat_G.copy(), "x_G": self.x_G.copy(),
+ "x_mean_G": self.x_mean_G.copy(), "s_G": self.s_G.copy(),
+ "win_spikes": self.win_spikes.copy(), "u_slow": self.u_slow.copy(),
+ "beta": self.beta,
+ })
+ return d
+
+ def restore(self, st: dict) -> None:
+ self.v = st["v"].copy()
+ self.thr = st["thr"].copy()
+ self.rhat = st["rhat"].copy()
+ self.refr = st["refr"].copy()
+ self.x = st["x"].copy()
+ self.x_prev = st["x_prev"].copy()
+ self.x_mean = st["x_mean"].copy()
+ self.s = st["s"].copy()
+ self.baseline = st["baseline"]
+ if "banks" in st:
+ self._banks = st["banks"].copy()
+ self._direct = st["direct"].copy()
+ else: # reconstruct banks from the composed state vector
+ nb = self.n_banks * self.n_res
+ self._banks = self.x[:nb].reshape(self.n_banks, self.n_res).copy()
+ if self.direct_input:
+ self._direct = self.x[nb:].copy()
+ if self.hier and "v_G" in st:
+ self.v_G = st["v_G"].copy()
+ self.thr_G = st["thr_G"].copy()
+ self.rhat_G = st["rhat_G"].copy()
+ self.x_G = st["x_G"].copy()
+ self.x_mean_G = st["x_mean_G"].copy()
+ self.s_G = st["s_G"].copy()
+ self.win_spikes = st["win_spikes"].copy()
+ self.u_slow = st["u_slow"].copy()
+ self.beta = st["beta"]
+
+ def reset_dynamics(self) -> None:
+ """Reset transient dynamics but KEEP learned homeostatic scalars
+ (thresholds, rate estimates, trace mean, top-down gain) — used before
+ generation."""
+ thr, rhat, x_mean = self.thr, self.rhat, self.x_mean
+ if self.hier:
+ thr_G, rhat_G, x_mean_G, beta = self.thr_G, self.rhat_G, self.x_mean_G, self.beta
+ self.reset()
+ self.thr, self.rhat, self.x_mean = thr, rhat, x_mean
+ if self.hier:
+ self.thr_G, self.rhat_G, self.x_mean_G, self.beta = thr_G, rhat_G, x_mean_G, beta
+
+ # ------------------------------------------------------------- inference
+ def step(self, input_idx) -> np.ndarray:
+ """Advance one tick with the given active input neurons.
+
+ Returns the post-synaptic trace ``x`` (the state used for readout).
+ """
+ W_in, W_rec = self.W_in, self.W_rec
+ I = W_in[input_idx].sum(axis=0, dtype=np.float32)
+ I += self.s @ W_rec
+ v = self.lam * self.v + I
+ can = self.refr == 0
+ v[~can] = 0.0
+ spikes = (v >= self.thr) & can
+ v[spikes] = 0.0
+ np.subtract(self.refr, 1, out=self.refr, where=self.refr > 0)
+ self.refr[spikes] = self.refrac
+ self.v = v
+ self.s = spikes.astype(np.float32)
+ # homeostatic threshold via EMA firing-rate estimate
+ self.rhat += 0.02 * (self.s - self.rhat)
+ self.thr += self.eta_homeo * (self.rhat - self.target_rate)
+ np.clip(self.thr, self.thr_min, self.thr_max, out=self.thr)
+ # traces (v3): x_prev keeps the BANK-0 (fast) reservoir trace for STDP;
+ # the readout state x is the concatenation of all trace banks plus the
+ # direct input trace — context older than one tick survives in the
+ # slow banks and in the direct trace's decayed identity history.
+ self.x_prev = self._banks[0].copy()
+ for i, tau in enumerate(self.trace_taus):
+ if i == 0:
+ self._banks[i] = tau * self._banks[i] + self.s
+ else:
+ # slow banks are NORMALIZED traces (decay-weighted averages):
+ # a raw tau=0.95 sum would sit at ~20x the fast bank's scale
+ # and swamp both the readout geometry and the LMS rate.
+ self._banks[i] = tau * self._banks[i] + (1.0 - tau) * self.s
+ if self.direct_input:
+ self._direct *= np.float32(self.direct_tau)
+ np.add.at(self._direct, input_idx, np.float32(self.direct_gain))
+ self.x = np.concatenate([*self._banks, self._direct])
+ elif self.n_banks > 1:
+ self.x = np.concatenate([*self._banks])
+ else:
+ self.x = self._banks[0]
+ # slow EMA of the trace: homeostatic "synaptic scaling" analogue used
+ # to mean-center the readout input (kills the shared dense background
+ # that otherwise dominates column norms)
+ self.x_mean = 0.999 * self.x_mean + 0.001 * self.x
+ self.x_eff = self.x - self.x_mean
+ self.tick += 1
+ if self.hier:
+ self.win_spikes += self.s
+ return self.x
+
+ def scores(self, x: np.ndarray) -> np.ndarray:
+ """Readout scores from a (raw) trace — centers with the EMA mean."""
+ return (x - self.x_mean) @ self.W_out
+
+ # ------------------------------------------------- slow area (hierarchy)
+ def step_G(self) -> None:
+ """Advance the slow area one slow step (one window of ``win`` fast
+ ticks).
+
+ Input: the pooled fast-area spike volley over the window (bottom-up,
+ sign-preserving). Output: the cached slow readout ``u_slow``, used as
+ a top-down prior fused into the fast prediction with gain ``beta``.
+ Pure inference dynamics (homeostasis included, same regime as the
+ fast area); learning happens in ``learn_G``.
+ """
+ c = self.win_spikes * np.float32(1.0 / self.win)
+ I = c @ self.W_inG
+ I += self.s_G @ self.W_recG
+ v = self.lam_g * self.v_G + I
+ spikes = v >= self.thr_G
+ v[spikes] = 0.0
+ self.v_G = v
+ self.s_G = spikes.astype(np.float32)
+ self.rhat_G += 0.05 * (self.s_G - self.rhat_G)
+ self.thr_G += self.eta_homeo_g * (self.rhat_G - self.target_rate_g)
+ np.clip(self.thr_G, self.thr_min, self.thr_max, out=self.thr_G)
+ self.x_G = self.tau_trace_g * self.x_G + self.s_G
+ self.x_mean_G = 0.999 * self.x_mean_G + 0.001 * self.x_G
+ self.win_spikes[:] = 0.0
+ self.u_slow = (self.x_G - self.x_mean_G) @ self.W_outG
+
+ def learn_G(self, target: int, d: float) -> int:
+ """Delta-rule update on the SLOW readout, gated by the same dopaminergic
+ RPE that gates the fast one (a global neuromodulator broadcasts to both
+ areas — each readout computes its own local error from its own
+ activity). ``target`` is the majority vocabulary column of the NEXT
+ window. Returns 1 if the slow readout's own top prediction matches it.
+ """
+ x_effG = self.x_G - self.x_mean_G
+ u = self.u_slow
+ V = self.n_out - 1
+ own_pred = int(np.argmax(u[:V]))
+ correct = 1 if own_pred == target else 0
+ nx = 1.0 / (float(x_effG @ x_effG) + 1e-6)
+ k = min(16, V)
+ act = np.argpartition(u[:V], -k)[-k:]
+ if target < V:
+ cols = np.concatenate([act, np.array([target], dtype=np.int64)])
+ desired = np.zeros(len(cols), dtype=np.float32)
+ desired[-1] = 1.0
+ else:
+ cols = act
+ desired = np.zeros(len(cols), dtype=np.float32)
+ errs = u[cols] - desired
+ gate = float(np.clip(1.0 + d, 0.25, 2.0))
+ eta = np.float32(self.eta_delta_g * gate * nx)
+ W = self.W_outG
+ W[:, cols] -= eta * errs[None, :] * x_effG[:, None]
+ W[:, cols] = np.clip(W[:, cols], -self.w_clip, self.w_clip)
+ return correct
+
+ # ------------------------------------------------------------- learning
+ def learn(self, pred: int, target: int, x: np.ndarray,
+ u: np.ndarray | None = None, active_k: int = 16) -> tuple[int, float, float]:
+ """Local delta-rule readout update (Rescorla-Wagner) gated by a
+ dopaminergic reward-prediction error, + modulated recurrent STDP.
+
+ Each readout unit computes its OWN prediction error from its own
+ activity (no gradients, no chain rule, no backprop): units in the
+ active top-k set and the instructive target unit move their weights
+ to reduce (score - desired). The learning rate is gated by dopamine
+ d = reward - baseline (RPE), the classical Rescorla-Wagner / TD
+ account of neuromodulation.
+
+ Returns (correct, reward, dopamine).
+ """
+ correct = 1 if pred == target else 0
+ reward = float(correct)
+ self.baseline = self.baseline_momentum * self.baseline + (1 - self.baseline_momentum) * reward
+ d = reward - self.baseline # dopaminergic RPE
+
+ W_out = self.W_out
+ x_eff = x - self.x_mean
+ nx = 1.0 / (float(x_eff @ x_eff) + 1e-6) # LMS normalization
+ V = self.n_out - 1
+ if u is None:
+ u = x_eff @ W_out
+ # active set: top-k scored columns (+ target if in vocabulary)
+ k = min(active_k, V)
+ act = np.argpartition(u[:V], -k)[-k:]
+ if target < V:
+ cols = np.concatenate([act, np.array([target], dtype=np.int64)])
+ else:
+ cols = act
+ desired = np.zeros(len(cols), dtype=np.float32)
+ if target < V:
+ desired[-1] = 1.0 # one-hot with margin 1
+ errs = u[cols] - desired
+ # dopamine gates plasticity amplitude (dips shrink, bursts amplify)
+ gate = float(np.clip(1.0 + d, 0.25, 2.0))
+ eta = np.float32(self.eta_delta * gate * nx)
+ W_out[:, cols] -= eta * errs[None, :] * x_eff[:, None]
+ # clip in place (fancy-indexed views need explicit writeback)
+ W_out[:, cols] = np.clip(W_out[:, cols], -self.w_clip, self.w_clip)
+
+ # light reward-modulated STDP on recurrent synapses of spiked neurons
+ if self.s.any():
+ spiked = np.nonzero(self.s)[0]
+ W_rec = self.W_rec
+ delta = np.float32(self.eta_stdp * d)
+ # pre-trace (x_prev) paired with post spikes, gated by dopamine
+ W_rec[:, spiked] += delta * self.x_prev[:, None]
+ np.clip(W_rec[:, spiked], self._rec_lo[:, None], self._rec_hi[:, None],
+ out=W_rec[:, spiked])
+ # top-down gain: TRUST dynamics, gated by the same RPE (a
+ # noradrenergic gain-modulation analogue) with counterfactual credit:
+ # fused right + fast wrong -> the slow prior SAVED the choice -> trust builds (additive)
+ # fused wrong + fast right -> the slow prior CORRUPTED it -> trust decays (multiplicative)
+ # Trust building slowly and decaying fast (loss aversion) lets the
+ # system keep a genuinely informative slow area while driving a
+ # noise- or frequency-prior-dominated one to beta ~ 0.
+ if self.hier and target < V:
+ pred_fast = int(np.argmax(u[:V]))
+ if pred_fast != target and correct: # slow saved it
+ self.beta = min(self.beta + self.eta_beta * gate, self.beta_max)
+ elif pred_fast == target and not correct: # slow corrupted it
+ self.beta *= float(0.98) ** gate
+ if self.beta < 1e-4:
+ self.beta = 0.0
+ else:
+ us_t = float(self.u_slow[target])
+ us_p = float(self.u_slow[pred_fast])
+ norm = abs(us_t) + abs(us_p) + 1e-6
+ margin = float(np.tanh(3.0 * (us_t - us_p) / norm))
+ self.beta = float(np.clip(
+ self.beta + 0.25 * self.eta_beta * gate * margin,
+ 0.0, self.beta_max))
+ return correct, reward, d
+
+ def learn_reservoir(self, pred: int, target: int, x: np.ndarray,
+ u: np.ndarray | None = None) -> tuple[int, float, float]:
+ """Training-regime dynamics WITHOUT readout plasticity: same reward,
+ same dopaminergic RPE, same recurrent STDP — only the W_out delta
+ update is skipped. Used at inference so the reservoir runs in its
+ training operating regime (continual plasticity, frozen readout)."""
+ correct = 1 if pred == target else 0
+ reward = float(correct)
+ self.baseline = self.baseline_momentum * self.baseline + (1 - self.baseline_momentum) * reward
+ d = reward - self.baseline
+ if self.s.any():
+ spiked = np.nonzero(self.s)[0]
+ W_rec = self.W_rec
+ delta = np.float32(self.eta_stdp * d)
+ W_rec[:, spiked] += delta * self.x_prev[:, None]
+ W_rec[:, spiked] = np.clip(W_rec[:, spiked], self._rec_lo[:, None], self._rec_hi[:, None])
+ return correct, reward, d
+
+ # ------------------------------------------------------- training driver
+ def train_pass(
+ self,
+ neurons: np.ndarray, # (T, k_in) int32 active input neurons per tick
+ cols: np.ndarray, # (T,) int64 target column per tick (col of token t+1)
+ log_every: int = 5000,
+ log_fn=None,
+ decay_every: int = 1024,
+ decay: float = 1e-4,
+ record_raster_from: int | None = None,
+ ) -> dict:
+ """One epoch over a token stream (teacher forcing on the next token).
+
+ ``neurons[t]`` drives the reservoir at tick t; the prediction made
+ from the resulting state is scored against ``cols[t]``.
+ """
+ self.reset()
+ T = len(cols)
+ acc_ema = None
+ d_ema = 0.0
+ n_correct = 0
+ n_correct_fast = 0
+ raster: list[tuple[int, np.ndarray]] = []
+ V_vocab = self.n_out - 1 # UNK occupies the last column
+ import time
+ t0 = time.perf_counter()
+ for t in range(T):
+ x = self.step(neurons[t])
+ u = (x - self.x_mean) @ self.W_out
+ if self.hier:
+ # behavioural prediction = fast readout + top-down slow prior
+ fused = u + np.float32(self.beta) * self.u_slow
+ pred = int(np.argmax(fused[:V_vocab]))
+ else:
+ pred = int(np.argmax(u[:V_vocab])) # vocabulary-only prediction
+ correct, reward, d = self.learn(pred, int(cols[t]), x, u=u)
+ n_correct += correct
+ if self.hier:
+ pred_fast = int(np.argmax(u[:V_vocab]))
+ if pred_fast == int(cols[t]):
+ n_correct_fast += 1
+ if (t + 1) % self.win == 0:
+ self.step_G()
+ if t + 1 < T:
+ seg = cols[t + 1 : min(t + 1 + self.win, T)]
+ g_target = int(np.bincount(seg).argmax())
+ self.learn_G(g_target, d)
+ acc_ema = reward if acc_ema is None else 0.999 * acc_ema + 0.001 * reward
+ d_ema = 0.999 * d_ema + 0.001 * d
+ if record_raster_from is not None and t >= record_raster_from:
+ raster.append((t, np.nonzero(self.s)[0].astype(np.int16)))
+ if (t + 1) % log_every == 0 and log_fn is not None:
+ dt = time.perf_counter() - t0
+ log_fn({
+ "tick": t + 1, "total": T,
+ "acc_ema": round(acc_ema, 4),
+ "acc_fast_ema": (round(0.999 * (n_correct_fast / max(t + 1, 1)), 4)
+ if self.hier else None),
+ "beta": (round(self.beta, 3) if self.hier else None),
+ "dopamine_ema": round(d_ema, 4),
+ "ticks_per_sec": round((t + 1) / max(dt, 1e-9), 1),
+ "elapsed_s": round(dt, 1),
+ })
+ if (t + 1) % decay_every == 0:
+ self.W_out *= np.float32(1.0 - decay)
+ if self.hier:
+ self.W_outG *= np.float32(1.0 - decay)
+ dt = time.perf_counter() - t0
+ return {
+ "ticks": T,
+ "accuracy": n_correct / max(T, 1),
+ "accuracy_fast_only": (n_correct_fast / max(T, 1)) if self.hier else None,
+ "beta": float(self.beta) if self.hier else None,
+ "acc_ema_final": acc_ema,
+ "elapsed_s": dt,
+ "ticks_per_sec": T / max(dt, 1e-9),
+ "raster": raster,
+ }
+
+ # ------------------------------------------------------------ (de)hydrate
+ def state_dict(self) -> dict:
+ sd = {
+ "config": {
+ "d_in": self.d_in, "k_in": self.k_in, "n_res": self.n_res,
+ "n_out": self.n_out, "seed": self.seed,
+ "in_fanout": self.in_fanout, "rec_fanout": self.rec_fanout,
+ "inh_frac": self.inh_frac, "lam": self.lam,
+ "base_thr": self.base_thr, "refrac": self.refrac,
+ "tau_trace": self.tau_trace,
+ "w_in_scale": self.w_in_scale, "w_rec_scale": self.w_rec_scale,
+ "w_clip": self.w_clip, "eta_delta": self.eta_delta, "eta_stdp": self.eta_stdp,
+ "eta_homeo": self.eta_homeo,
+ "target_rate": self.target_rate,
+ "hier": self.hier, "n_g": self.n_g, "win": self.win,
+ "w_g_scale": self.w_g_scale, "w_recg_scale": self.w_recg_scale,
+ "lam_g": self.lam_g, "tau_trace_g": self.tau_trace_g,
+ "target_rate_g": self.target_rate_g, "eta_homeo_g": self.eta_homeo_g,
+ "eta_delta_g": self.eta_delta_g,
+ "eta_beta": self.eta_beta, "beta_init": self.beta0, "beta_max": self.beta_max,
+ "trace_taus": list(self.trace_taus), "direct_input": self.direct_input,
+ "direct_tau": self.direct_tau, "direct_gain": self.direct_gain,
+ },
+ "W_rec": self.W_rec.astype(np.float32),
+ "W_out": self.W_out.astype(np.float32),
+ "inhibitory": self.inhibitory,
+ }
+ if self.hier:
+ sd["W_out_G"] = self.W_outG.astype(np.float32)
+ return sd
+
+ def load_state_dict(self, sd: dict) -> None:
+ cfg = sd["config"]
+ self.__dict__.update(cfg)
+ # v3 derived structure (defaults reproduce v2 for old checkpoints)
+ self.trace_taus = tuple(float(t) for t in getattr(self, "trace_taus", (self.tau_trace,)))
+ self.direct_input = bool(getattr(self, "direct_input", False))
+ self.n_banks = len(self.trace_taus)
+ self.n_state = int(sd["W_out"].shape[0])
+ self.W_rec = np.asarray(sd["W_rec"], dtype=np.float32)
+ self.W_out = np.asarray(sd["W_out"], dtype=np.float32)
+ self.inhibitory = np.asarray(sd["inhibitory"], dtype=np.bool_)
+ w_rec_max = 3.0 * self.w_rec_scale
+ self._rec_lo = np.where(self.inhibitory, -w_rec_max, 0.0).astype(np.float32)
+ self._rec_hi = np.where(self.inhibitory, 0.0, w_rec_max).astype(np.float32)
+ if "W_out_G" in sd and self.hier:
+ self.W_outG = np.asarray(sd["W_out_G"], dtype=np.float32)
+ else:
+ # v1 checkpoint without the slow area
+ self.hier = False
+ self.reset()
diff --git a/results/hashing/lever2_sparse/code/python/spira/train.py b/results/hashing/lever2_sparse/code/python/spira/train.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b5362f318f92ef7e6cd9f4116e6d6e3c17b3b4e
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/python/spira/train.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python3
+"""SPIRA training CLI.
+
+Usage:
+ python3 -m spira.train --data data/train.bin \
+ --out artifacts/spira_model.npz \
+ [--snn-tokens 600000] [--am-tokens 1200000] [--epochs 2] [--quick]
+
+Writes:
+ : model checkpoint (npz)
+ .train_log.jsonl : tick-level progress log
+ .history.json : final training history
+"""
+from __future__ import annotations
+
+import argparse
+import json
+import sys
+import time
+
+from .model import SPIRA, SPIRAConfig
+
+
+def main() -> None:
+ ap = argparse.ArgumentParser()
+ ap.add_argument("--data", required=True)
+ ap.add_argument("--out", required=True)
+ ap.add_argument("--snn-tokens", type=int, default=600_000)
+ ap.add_argument("--am-tokens", type=int, default=1_200_000)
+ ap.add_argument("--epochs", type=int, default=2)
+ ap.add_argument("--vocab", type=int, default=4096)
+ ap.add_argument("--n-res", type=int, default=512)
+ ap.add_argument("--target-avg-len", type=float, default=4.5)
+ ap.add_argument("--quick", action="store_true", help="tiny smoke-test run")
+ args = ap.parse_args()
+
+ cfg = SPIRAConfig(
+ vocab_size=args.vocab,
+ n_res=args.n_res,
+ snn_tokens=args.snn_tokens,
+ am_tokens=args.am_tokens,
+ epochs=args.epochs,
+ target_avg_len=args.target_avg_len,
+ )
+ if args.quick:
+ cfg.snn_tokens, cfg.am_tokens, cfg.epochs = 20_000, 20_000, 1
+
+ data = open(args.data, "rb").read()
+ t0 = time.perf_counter()
+
+ log_path = args.out + ".train_log.jsonl"
+ log_f = open(log_path, "w")
+
+ def log(msg: str) -> None:
+ print(msg, flush=True)
+ log_f.write(json.dumps({"t": round(time.perf_counter() - t0, 1), "msg": msg}) + "\n")
+ log_f.flush()
+
+ def tick_log(d: dict) -> None:
+ log_f.write(json.dumps({"t": round(time.perf_counter() - t0, 1), **d}) + "\n")
+ log_f.flush()
+
+ model = SPIRA.build(data, cfg, log=log)
+ model.prepare()
+ # free the patch list — the registry carries everything we need
+ model._patches_train = None
+
+ log("[spira] training starts")
+ history = model.train(
+ log_fn=lambda msg: tick_log({"msg": msg}) or print(msg, flush=True),
+ ckpt_path=args.out,
+ )
+ history["build_meta"] = model.meta
+ history["config"] = {k: v for k, v in vars(cfg).items()}
+ history["wall_clock_s"] = time.perf_counter() - t0
+ with open(args.out + ".history.json", "w") as f:
+ json.dump(history, f, indent=2)
+ model.save(args.out)
+ log(f"[spira] DONE in {history['wall_clock_s']:.0f}s -> {args.out}")
+ log_f.close()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/results/hashing/lever2_sparse/code/selftest_AH1/verdict_AH1.json b/results/hashing/lever2_sparse/code/selftest_AH1/verdict_AH1.json
new file mode 100644
index 0000000000000000000000000000000000000000..3ef7bcb88bea1b4d618a2d2c57da5b928aff4feb
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/selftest_AH1/verdict_AH1.json
@@ -0,0 +1,221 @@
+{
+ "cand": "AH1 (eta_ah=1e-3, rho=0.1, Q in [0,0.5], figé en éval)",
+ "ref": "ref (eta_ah=0, budget égal)",
+ "corpus": "broad/old_local_v1",
+ "snn_tokens": 24000,
+ "epochs": 2,
+ "max_positions": 4000,
+ "windows_measured": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_not_measured": [
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen",
+ "aucun gain significatif sur une fenêtre fraîche",
+ "perte(s) significative(s) : fc2"
+ ],
+ "losses": [
+ "fc2"
+ ],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2600,
+ "n_invocab_clean_cand": 2600,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 98.46153846153847,
+ "acc_cand_pct": 98.46153846153847,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 42,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a58d536c9af78bbf8451905f7c68222576dfc096bfd3b52f300d992b5a9240b4"
+ },
+ "fc2": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2544,
+ "n_invocab_clean_cand": 2544,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 8.254716981132075,
+ "acc_cand_pct": 7.70440251572327,
+ "delta_pct": -0.550314465408805,
+ "b_ref_only": 24,
+ "c_cand_only": 10,
+ "mcnemar_p": 0.024306510109454393,
+ "boot_ci95_delta_pct": [
+ -1.1080551822495261,
+ -0.03875856449594405
+ ],
+ "boot_p": 0.0444,
+ "n_blocks": 37,
+ "sig_gain": false,
+ "sig_loss": true,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ },
+ "fresh_en": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2847,
+ "n_invocab_clean_cand": 2847,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 1.2293642430628733,
+ "acc_cand_pct": 1.1239901650860555,
+ "delta_pct": -0.10537407797681775,
+ "b_ref_only": 11,
+ "c_cand_only": 8,
+ "mcnemar_p": 0.6476058959960938,
+ "boot_ci95_delta_pct": [
+ -0.416815013513543,
+ 0.17800087275434376
+ ],
+ "boot_p": 0.572,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ },
+ "fresh_fr": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 1557,
+ "n_invocab_clean_cand": 1557,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 30,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ },
+ "test20k": {
+ "n_positions": 4000,
+ "n_clean": 4000,
+ "n_invocab_clean_ref": 2801,
+ "n_invocab_clean_cand": 2801,
+ "invocab_identical": true,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.8211353088182792,
+ "acc_cand_pct": 0.7497322384862549,
+ "delta_pct": -0.07140307033202431,
+ "b_ref_only": 4,
+ "c_cand_only": 2,
+ "mcnemar_p": 0.6875,
+ "boot_ci95_delta_pct": [
+ -0.24673951357067336,
+ 0.10556039405894535
+ ],
+ "boot_p": 0.5462,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 17883
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 2.576304133253307,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 95.88523432828516,
+ "ci95": [
+ 95.17631636781792,
+ 96.55817642997651
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 2.394531229823895,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 96.06700723171457,
+ "ci95": [
+ 95.40164839357195,
+ 96.71787864908593
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": 0.18177290342940466,
+ "ci95": [
+ 0.024249240736329017,
+ 0.34262003170707644
+ ],
+ "ci95_boot_positions_seed25": [
+ 0.03944741090992139,
+ 0.326473583105809
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "note": "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+ },
+ "script_sha256": "450e7feac9688962fbcf28b21da574cfcc169caa4b5af454635db0748599840f",
+ "inputs_sha256": {
+ "ref__seen.npz": "a508542b6c6d1f4aafcb3c94fed843be7b4d5f4d136aeefca81cdee31d62eac8",
+ "ref__fc2.npz": "73ac8b9f777a42e223852450ef3c795122651893358407d53632f277f41f6003",
+ "ref__fresh_en.npz": "e2563d51b3677e4521e579c7e95afde18924ba8a7cee05c24f8ced0976b7817e",
+ "ref__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "ref__test20k.npz": "3c304dcbb48c6907b519fd42cf95bd817f52343dc588d478aa4273292d99fd4d",
+ "AH1__seen.npz": "a8f2e55db3debd594f07eb4df826bd41bcfcfd54cf685b69946a7ccdb94f9108",
+ "AH1__fc2.npz": "50ee8648bba55b661a87f850078a6fbac7f3edde95ba0621081c046fad4e89b3",
+ "AH1__fresh_en.npz": "8ae4cbd7ccb335eb702b77e14193fc29962daea196e28d7436471a833f1dab3d",
+ "AH1__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "AH1__test20k.npz": "6a64e0ea7498e0e83e1521cf1d273751fcfad5e2f0207490dc1c271a564e8faf"
+ },
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178",
+ "mask_path": "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+}
\ No newline at end of file
diff --git a/results/hashing/lever2_sparse/code/selftest_AH1/verdict_AH1.md b/results/hashing/lever2_sparse/code/selftest_AH1/verdict_AH1.md
new file mode 100644
index 0000000000000000000000000000000000000000..0357fc63a5f28c703f0261df34535edf80e1eded
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/selftest_AH1/verdict_AH1.md
@@ -0,0 +1,22 @@
+# Verdict levier 2 — AH1 (eta_ah=1e-3, rho=0.1, Q in [0,0.5], figé en éval) contre ref (eta_ah = 0, budget égal), old_local_v1 court
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche; perte(s) significative(s) : fc2
+
+Précision fused sur les cibles invocab (%), 4000 positions par fenêtre, appariement par position.
+
+| fenêtre | n apparié | AH1 % | réf % | Δ pts | b (réf seule) / c (AH1 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 4000 | 98.462 | 98.462 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fc2 | 4000 | 7.704 | 8.255 | -0.550 | 24/10 | 0.0243 | [-1.108 ; -0.039] | PERTE |
+| fresh_en | 4000 | 1.124 | 1.229 | -0.105 | 11/8 | 0.648 | [-0.417 ; +0.178] | n.s. |
+| fresh_fr | 4000 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test20k strict (old_local_v1/test.bin, union old ∪ broad) | 4000 | 0.750 | 0.821 | -0.071 | 4/2 | 0.688 | [-0.247 ; +0.106] | n.s. |
+| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+
+test20k strict : 0 positions exclues sur 4000 (0 par old_local_v1, 0 par broad_local_v1), octets évalués jusqu'à 17883.
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k ; test_v3 non mesuré) : AH1 +96.067 pts [IC95 +95.402 ; +96.718] (fraîche 2.395 %) ; réf +95.885 pts [+95.176 ; +96.558] (fraîche 2.576 %) ; différence AH1 − réf +0.182 [blocs 512 o seed 0 : +0.024 ; +0.343] [positions seed 25 : +0.039 ; +0.326].
+
+Script sha256 450e7feac9688962fbcf28b21da574cfcc169caa4b5af454635db0748599840f ; masque sha256 50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178.
+
diff --git a/results/hashing/lever2_sparse/code/selftest_AH1/verdict_SP_selftest.py b/results/hashing/lever2_sparse/code/selftest_AH1/verdict_SP_selftest.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f92467e4b8a7f96e0e4f8748fe27dd0ca1f169a
--- /dev/null
+++ b/results/hashing/lever2_sparse/code/selftest_AH1/verdict_SP_selftest.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict levier 2 SPARSITÉ (SP1/SP2, argument 1) — copie de lever2/verdict_AH1/verdict_AH1.py, SEULS changements :
+bras candidat lu dans lever2_sparse/short_old, sortie dans lever2_sparse/verdict_, libellés. Témoin, masque et protocole identiques.
+(ex-docstring AH1) verdict levier 2 AH1 (eta_ah=1e-3) contre le témoin à budget égal ref (eta_ah=0), méthode banc v4.1
+(copie adaptée de m7_v41/strict/verdict_m7_v41_strict.py ; lecture seule des hits short_old/{ref,AH1}__*.npz, aucun modèle chargé).
+Fenêtres MESURÉES par run_l2.py (4000 positions chacune) : seen (= old_local_v1/train[:200000]), fc2, fresh_en, fresh_fr, test20k
+(= old_local_v1/test.bin, sha ce0526c6…, PAS broad_local_v1/test.bin ; masque strict propre recalculé : verdict_AH1/mask_oldtest_strict.npz,
+union old_local_v1 ∪ broad_local_v1). queries et test_v3 : NON évalués par les bras → absents (non mesurables). neither_code exclu.
+hit = fused_hit & invocab. Appariement par position si tgt_start et tgt_len identiques (vérifié). McNemar exact bilatéral = DÉCISION (p<0,05).
+Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un générateur seed 0, fenêtres dans l'ordre WIN, apparié ; stat = acc invocab.
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k strict ; test_v3 non mesuré). Bootstrap secondaire par positions, seed 25.
+Critère utilisateur : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche ET aucune perte significative sur une fenêtre valide ; sinon REJETÉ."""
+import sys, os, json, math, hashlib, numpy as np
+D = "/workspace/spira_shared/hashing_gen/lever2/short_old"; RT, CT = "ref", sys.argv[1]; assert CT == "AH1"
+DC = "/workspace/spira_shared/hashing_gen/lever2/short_old"; OP = "/workspace/spira_shared/hashing_gen/lever2_sparse/code/selftest_AH1"
+MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+DESC = {'AH1': 'AH1 (eta_ah=1e-3, rho=0.1, Q in [0,0.5], figé en éval)', 'SP1': 'SP1 (k-WTA k=51 sur les spikes, N=512, rho=0.1)', 'SP2': 'SP2 (seuil adaptatif theta += 1e-3*(s-0.1), theta0=0, figé en éval)'}[CT]
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k"]; GAPW = FRESH
+NOT_MEASURED = ["queries", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+os.makedirs(OP, exist_ok=True); MS = np.load(MASKP)
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{DC}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_union": int((bo | bb_).sum()),
+ "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum())
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k])); p = binp(b, c)
+ ia, ib = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k
+ acc_a, acc_b = 100 * (ha & k).sum() / ia.sum(), 100 * (hb & k).sum() / ib.sum()
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], A["invocab"].astype(bool)[k], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], B["invocab"].astype(bool)[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, A["invocab"].astype(bool))
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "n_invocab_clean_ref": int(ia.sum()), "n_invocab_clean_cand": int(ib.sum()), "invocab_identical": inv_same,
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)", "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"])}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+R2 = np.random.default_rng(25); BP = {}
+for w in WIN:
+ k, ha_, hb_, iv_ = KEEP[w]; m_ = k & iv_; r_ = ha_[m_].astype(np.float64); c_ = hb_[m_].astype(np.float64); n_ = len(r_); ar = np.empty(NB); ac = np.empty(NB)
+ for t in range(NB):
+ i = R2.integers(0, n_, n_); ar[t] = r_[i].mean(); ac[t] = c_[i].mean()
+ BP[w] = (100 * ar, 100 * ac)
+dgp = (BP["seen"][1] - np.mean([BP[w][1] for w in GAPW], axis=0)) - (BP["seen"][0] - np.mean([BP[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"]["ci95_boot_positions_seed25"] = [float(x) for x in np.percentile(dgp, [2.5, 97.5])]
+gap["windows"] = GAPW; gap["note"] = "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+out = {"cand": DESC, "ref": "ref (eta_ah=0, budget égal)", "corpus": "broad/old_local_v1", "snn_tokens": 24000, "epochs": 2, "max_positions": 4000,
+ "windows_measured": WIN, "windows_not_measured": NOT_MEASURED, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap,
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D if a == RT else DC}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN},
+ "mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest(), "mask_path": MASKP}
+json.dump(out, open(f"{OP}/verdict_{CT}.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict levier 2 — {DESC} contre ref (eta_ah = 0, budget égal), old_local_v1 court\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused sur les cibles invocab (%), 4000 positions par fenêtre, appariement par position.", "",
+ f"| fenêtre | n apparié | {CT} % | réf % | Δ pts | b (réf seule) / c ({CT} seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ nm = "test20k strict (old_local_v1/test.bin, union old ∪ broad)" if w == "test20k" else w
+ md.append(f"| {nm} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "",
+ f"test20k strict : {EX['excluded_union']} positions exclues sur 4000 ({EX['excluded_by_old_local_v1']} par old_local_v1, {EX['excluded_by_broad_local_v1']} par broad_local_v1), octets évalués jusqu'à {EX['max_byte_evaluated']}.", "",
+ f"Écart seen − moyenne fraîche ({', '.join(GAPW)} ; test_v3 non mesuré) : {CT} {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence {CT} − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [blocs 512 o seed 0 : {gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}] [positions seed 25 : {gap['cand_minus_ref']['ci95_boot_positions_seed25'][0]:+.3f} ; {gap['cand_minus_ref']['ci95_boot_positions_seed25'][1]:+.3f}].", "",
+ f"Script sha256 {out['script_sha256']} ; masque sha256 {out['mask_sha256']}.", ""]
+open(f"{OP}/verdict_{CT}.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/lever2_sparse/code/verdict_SP.py b/results/hashing/lever2_sparse/code/verdict_SP.py
index 820fac4006c17634fbfb758ec7e161ae9db57321..5eb46f3d4fb4bc5b439596b6711185f3cb95e679 100644
--- a/results/hashing/lever2_sparse/code/verdict_SP.py
+++ b/results/hashing/lever2_sparse/code/verdict_SP.py
@@ -9,6 +9,9 @@ union old_local_v1 ∪ broad_local_v1). queries et test_v3 : NON évalués par l
hit = fused_hit & invocab. Appariement par position si tgt_start et tgt_len identiques (vérifié). McNemar exact bilatéral = DÉCISION (p<0,05).
Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un générateur seed 0, fenêtres dans l'ordre WIN, apparié ; stat = acc invocab.
Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k strict ; test_v3 non mesuré). Bootstrap secondaire par positions, seed 25.
+Correctif v4.2 (Hashing 24 oct. ~09 h 39, Toronto ; original = verdict_SP.py.bak_0950) : positions gardées ssi in-vocab dans les DEUX bras (et propres) ;
+McNemar, taux (APPARIÉS, même dénominateur) et bootstrap sur ce seul ensemble. Tokenisation identique exigée (assert) ⇒ unités v4.2 = patches.
+Si invocab est identique entre bras (cas AH1/AH2), résultat identique à v4.1.
Critère utilisateur : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche ET aucune perte significative sur une fenêtre valide ; sinon REJETÉ."""
import sys, os, json, math, hashlib, numpy as np
D = "/workspace/spira_shared/hashing_gen/lever2/short_old"; RT, CT = "ref", sys.argv[1]; assert CT in ("SP1", "SP2")
@@ -38,26 +41,51 @@ for w in WIN:
EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_union": int((bo | bb_).sum()),
"max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
else: k = np.ones(na, bool)
- b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum())
- inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k])); p = binp(b, c)
- ia, ib = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k
- acc_a, acc_b = 100 * (ha & k).sum() / ia.sum(), 100 * (hb & k).sum() / ib.sum()
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ ia1, ib1 = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k; one_side = int((ia1 ^ ib1).sum())
+ k = k & A["invocab"].astype(bool) & B["invocab"].astype(bool) # v4.2 : in-vocab dans les DEUX bras
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); p = binp(b, c)
+ ia, ib = k.copy(), k.copy()
+ acc_a, acc_b = 100 * (ha & k).sum() / ia.sum(), 100 * (hb & k).sum() / ib.sum() # taux APPARIÉS (même dénominateur)
nbk = int(A["tgt_start"].max() // BLK + 1)
- sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], A["invocab"].astype(bool)[k], nbk)
- sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], B["invocab"].astype(bool)[k], nbk)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], k[k], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], k[k], nbk)
nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
idx = RNG.integers(0, m, (NB, m))
with np.errstate(invalid="ignore", divide="ignore"):
ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
- d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, A["invocab"].astype(bool))
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, k)
lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
- R[w] = {"n_positions": na, "n_clean": npair, "n_invocab_clean_ref": int(ia.sum()), "n_invocab_clean_cand": int(ib.sum()), "invocab_identical": inv_same,
+ R[w] = {"n_positions": na, "n_clean": npair, "n_invocab_clean_ref": int(ia.sum()), "n_invocab_clean_cand": int(ib.sum()), "invocab_identical": inv_same, "n_invocab_one_side_only_dropped": one_side, "method": "v4.2 : in-vocab deux bras, taux appariés",
"pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)", "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
"b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
"sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"])}
if w == "test20k": R[w]["strict_mask"] = EX
print(w, json.dumps(R[w]), flush=True)
+# --- 09 h 58 (Toronto), réserve Checker 09 h 45 : audit trained_frac du seen (fenêtre = old_local_v1/train[:200000]) ---
+# SNN entraîné sur ids[:snn_tokens] (model.prepare : neuron_rows(ids[:n_snn]), cols_of(ids[:n_snn+1])). Position i du seen : contexte = patch i,
+# cible = patch i+1, SI les cibles sont contiguës depuis le patch 1 (vérifié : tgt_start[0] = fin du patch 0, tgt_start[i+1] = tgt_start[i]+tgt_len[i])
+# ET si la segmentation de train[:200000] coïncide avec celle de train.bin sur ce préfixe (hypothèse EPT gauche→droite ; derniers octets évalués << 200000).
+# Entraînée ssi patch de contexte i < snn_tokens. trained_frac < 0,99 => seen NON COMPARABLE et ADOPTÉ impossible.
+TRAIN_OLD = "/workspace/spira_shared/broad/old_local_v1/train.bin"
+def _snn_tokens(path, arm):
+ v = {json.loads(l).get("snn_tokens") for l in open(path) if l.strip() and json.loads(l).get("arm") == arm and json.loads(l).get("window") == "seen"}
+ return v.pop() if len(v) == 1 else None
+_A = np.load(f"{D}/{RT}__seen.npz"); _st, _ln = _A["tgt_start"].astype(np.int64), _A["tgt_len"].astype(np.int64)
+_contig = bool(np.all(_st[1:] == _st[:-1] + _ln[:-1]) and _st[0] > 0 and _st[0] <= int(_ln.max()))
+_wsha = hashlib.sha256(open(TRAIN_OLD, "rb").read(200_000)).hexdigest(); _wok = _wsha == R["seen"]["window_sha256"]
+_ksnn = {"ref": _snn_tokens(f"{D}/results.jsonl", RT), "cand": _snn_tokens(f"{DC}/results.jsonl", CT)}
+_k, _ha, _hb, _iv = KEEP["seen"]; _ivb = _k & _iv & np.load(f"{DC}/{CT}__seen.npz")["invocab"].astype(bool); _ctx = np.arange(len(_st))
+SEEN_AUDIT = {"window_is_train_prefix_200000": _wok, "targets_contiguous_from_patch1": _contig, "snn_tokens": _ksnn,
+ "max_ctx_patch_index": int(_ctx.max()), "max_byte_evaluated": int((_st + _ln).max()), "invocab_both_n": int(_ivb.sum())}
+for side in ("ref", "cand"):
+ n_tr = int((_ivb & (_ctx < _ksnn[side])).sum()) if (_wok and _contig and _ksnn[side]) else None
+ SEEN_AUDIT[f"trained_invocab_n_{side}"] = n_tr; SEEN_AUDIT[f"trained_frac_{side}"] = (n_tr / max(1, int(_ivb.sum()))) if n_tr is not None else None
+SEEN_OK = all(SEEN_AUDIT[f"trained_frac_{x}"] is not None and SEEN_AUDIT[f"trained_frac_{x}"] >= 0.99 for x in ("ref", "cand"))
+SEEN_AUDIT["seen_comparable"] = SEEN_OK; print("seen_audit", json.dumps(SEEN_AUDIT), flush=True)
+FRESH_MEAN_NOTE = ("moyenne fraîche = fc2, fresh_en, fresh_fr, test20k strict SEULEMENT (test_v3 et queries non mesurés par les bras) : "
+ "l'écart seen − moyenne fraîche n'est PAS comparable à celui du banc v4 (qui inclut test_v3) ; décision non affectée")
gap = {}
for side, j in (("ref", 0), ("cand", 1)):
fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
@@ -73,24 +101,25 @@ for w in WIN:
BP[w] = (100 * ar, 100 * ac)
dgp = (BP["seen"][1] - np.mean([BP[w][1] for w in GAPW], axis=0)) - (BP["seen"][0] - np.mean([BP[w][0] for w in GAPW], axis=0))
gap["cand_minus_ref"]["ci95_boot_positions_seed25"] = [float(x) for x in np.percentile(dgp, [2.5, 97.5])]
-gap["windows"] = GAPW; gap["note"] = "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+gap["windows"] = GAPW; gap["note"] = FRESH_MEAN_NOTE + " ; neither_code exclu"; gap["comparable_to_bench_v4"] = False
L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
-dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+dec = "ADOPTÉ" if (SEEN_OK and R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
why = []
+if not SEEN_OK: why.append("seen NON COMPARABLE (audit trained_frac < 0,99 ou non vérifiable)")
if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
if L: why.append("perte(s) significative(s) : " + ", ".join(L))
out = {"cand": DESC, "ref": "ref (eta_ah=0, budget égal)", "corpus": "broad/old_local_v1", "snn_tokens": 24000, "epochs": 2, "max_positions": 4000,
"windows_measured": WIN, "windows_not_measured": NOT_MEASURED, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
"rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
- "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap,
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap, "seen_trained_audit": SEEN_AUDIT,
"script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
"inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D if a == RT else DC}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN},
"mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest(), "mask_path": MASKP}
json.dump(out, open(f"{OP}/verdict_{CT}.json", "w"), indent=1, ensure_ascii=False)
md = [f"# Verdict levier 2 — {DESC} contre ref (eta_ah = 0, budget égal), old_local_v1 court\n",
f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
- "Précision fused sur les cibles invocab (%), 4000 positions par fenêtre, appariement par position.", "",
+ "Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), 4000 positions par fenêtre, appariement par position (tokenisation identique vérifiée).", "",
f"| fenêtre | n apparié | {CT} % | réf % | Δ pts | b (réf seule) / c ({CT} seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
for w in WIN:
r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
@@ -98,6 +127,8 @@ for w in WIN:
md.append(f"| {nm} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
md += ["| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "",
f"test20k strict : {EX['excluded_union']} positions exclues sur 4000 ({EX['excluded_by_old_local_v1']} par old_local_v1, {EX['excluded_by_broad_local_v1']} par broad_local_v1), octets évalués jusqu'à {EX['max_byte_evaluated']}.", "",
+ f"Audit seen (trained_frac, positions in-vocab des deux bras dont le patch de contexte est dans ids[:snn_tokens]) : réf {SEEN_AUDIT['trained_frac_ref']} ({SEEN_AUDIT['trained_invocab_n_ref']}/{SEEN_AUDIT['invocab_both_n']}), {CT} {SEEN_AUDIT['trained_frac_cand']} ({SEEN_AUDIT['trained_invocab_n_cand']}/{SEEN_AUDIT['invocab_both_n']}) ; snn_tokens {SEEN_AUDIT['snn_tokens']} ; patch de contexte max {SEEN_AUDIT['max_ctx_patch_index']} ; fenêtre = train[:200000] {SEEN_AUDIT['window_is_train_prefix_200000']} ; cibles contiguës {SEEN_AUDIT['targets_contiguous_from_patch1']} → seen {'COMPARABLE' if SEEN_OK else 'NON COMPARABLE'}.", "",
+ f"Note : {FRESH_MEAN_NOTE}.", "",
f"Écart seen − moyenne fraîche ({', '.join(GAPW)} ; test_v3 non mesuré) : {CT} {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence {CT} − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [blocs 512 o seed 0 : {gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}] [positions seed 25 : {gap['cand_minus_ref']['ci95_boot_positions_seed25'][0]:+.3f} ; {gap['cand_minus_ref']['ci95_boot_positions_seed25'][1]:+.3f}].", "",
f"Script sha256 {out['script_sha256']} ; masque sha256 {out['mask_sha256']}.", ""]
open(f"{OP}/verdict_{CT}.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/lever2_sparse/relay/R1_predeclaration.md b/results/hashing/lever2_sparse/relay/R1_predeclaration.md
new file mode 100644
index 0000000000000000000000000000000000000000..f85fca89493e10837fa1e2da9e40864c97c3944b
--- /dev/null
+++ b/results/hashing/lever2_sparse/relay/R1_predeclaration.md
@@ -0,0 +1,10 @@
+
+## 2026-10-24 02 h 55 (heure de Toronto) — SPIRA Hashing — levier 2, bras SPARSITÉ : PRÉ-DÉCLARATION (aucun bras lancé)
+Règles locales, sans gradient ni perte globale. y = vecteur de spikes (0/1) de la couche spiking (réservoir LIF, N = n_res = 512), à chaque tick.
+- **SP1, k-WTA** : k = round(0,1·N) = 51 par tick (ρ = 0,1, même cible que AH). Parmi les neurones non réfractaires, les 51 de plus grande marge v − thr émettent, et eux seuls. Tri stable, départage par indice. Les perdants gardent leur potentiel. Actif en entraînement ET en éval. Aucun paramètre appris.
+- **SP2, seuil adaptatif homéostatique** : spike ssi v ≥ thr + θ_i ; θ_i += η_θ (y_i − ρ), ρ = 0,1, η_θ = 1e-3, θ initialisé à 0, non borné. Appris seulement pendant train_pass (comme Q des bras AH), figé en calibration et en éval. L'homéostasie du dépôt (thr, cible 0,06) n'est pas modifiée.
+- **Tout le reste est identique au témoin eta=0** : old_local_v1, snn_tokens 24 000 × 2 époques, MAXPOS 4000, cfg repo, porte mémoire interne. Code dans hashing_gen/lever2_sparse/code/ : run_sp.py = run_l2.py, dont seul antihebb.install est remplacé par sparse.install. Témoin RÉUTILISÉ : lever2/short_old/ref__*.npz et results.jsonl, pas relancé.
+- **Smoke test d'abord** : 400 ticks en train puis 300 en éval. On mesure le taux de décharge, et le mode « none » doit être bit à bit identique au témoin.
+- **Lancement en série**, chaque bras seulement si MemAvailable ≥ 5,2 Go (décimal, sondage toutes les 2 min) ET moins de 4 lourds, tous agents confondus (python avec RSS ≥ 300 Mo). setsid, nice 10, OMP_NUM_THREADS=1, PYTHONHASHSEED=0. En ce moment : 6 lourds (348162, 437490, 405144, 537926, 838852, 1036049), donc aucun bras ne part.
+- **Verdict** : même script que verdict_AH1 (copie, seuls les chemins et les libellés changent ; il reproduit verdict_AH1.json à l'identique). McNemar exact, bootstrap par blocs de 512 o, B = 10 000, seed 0. Fenêtres : seen, fc2, fresh_en, fresh_fr, test20k strict (masque old_local_v1/test.bin). queries et test_v3 ne sont pas évalués, neither_code est exclu. Écart seen − moyenne fraîche avec son IC. **ADOPTÉ seulement si gain significatif sur seen ET sur ≥ 1 fenêtre fraîche, sans perte significative.** Pas de 3e réglage, pas de push HF.
+— SPIRA Hashing
diff --git a/results/hashing/lever2_sparse/relay/R2_etat.md b/results/hashing/lever2_sparse/relay/R2_etat.md
new file mode 100644
index 0000000000000000000000000000000000000000..21cee9e8d31eced3a96dc52766b6962f5fbe346c
--- /dev/null
+++ b/results/hashing/lever2_sparse/relay/R2_etat.md
@@ -0,0 +1,12 @@
+
+## 2026-10-24 02 h 58 (heure de Toronto) — SPIRA Hashing — compare.py corrigé, manifests v2 (licences), smoke SPARSITÉ PASS, bras bloqués par la porte
+- **compare.py (lever2/code)** : scipy absent → McNemar exact bilatéral en pur Python (math.comb). p = Σ pmf ≤ pmf(observé)·(1+1e-7), plafonné à 1 ; pour p = 0,5 c'est identique à 2·min(queues). Original : compare.py.bak_scipy. Test test_compare_mcnemar.py : 10/10 p de verdict_AH1 et verdict_AH2 reproduits (écart ≤ 1e-12), dont fc2 24/10 → 0,024307. Exécution réelle ref vs AH1 OK. NB : compare.py donne des % sur toutes les positions et sans masque strict ; les verdicts font foi. final.sh et chain.sh (lever2/code) sont neutralisés (exit 1 en tête, originaux en *.bak_relay non exécutables) : plus aucune entrée « ÉCHEC » automatique.
+- **Licences** : recount_div1/manifest_multi_lang_v1_v2.json (sha f166f318…) et manifest_corpus_diverse_v1_v2.json (sha 2eb30d27…), script make_manifests_v2.py. Les v1 restent intacts (538030611…, c2f664ba…). multi_lang_v1, d'après build_stage1.json : 58 dépôts, dont MIT 29 / 103 479 151 o, Apache-2.0 21 / 98 874 011 o, BSD-3-Clause 6 / 26 999 928 o, curl (MIT/X derivative) 1 / 8 391 247 o, zlib 1 / 1 029 227 o. Aucune licence manquante, aucune non permissive selon le classement du build. 6 dépôts ont plusieurs fichiers de licence mais un seul libellé enregistré (django, ripgrep, serde, cargo, alacritty, libuv). corpus_gutenberg_v2, broad_gutenberg_v1 et broad_local_v1 : aucun champ licence → « non consignée », soit 54,86 % des octets de corpus_diverse_v1. **→ Checker : audit des deux v2 demandé.**
+- **Smoke SPARSITÉ** (smoke/smoke_sp.json) : 400 ticks en train + 300 en éval.
+ - Témoin : 0,0656 / 0,0686.
+ - SP1 : exactement 51 spikes à chaque tick, train et éval, taux 0,0996 = 51/512.
+ - SP2 : 0,0658 / 0,0690 ; θ moyen −0,0137, θ figé en éval. 400 ticks ne suffisent pas pour juger la convergence de SP2 vers 0,1.
+ - Mode « none » bit à bit identique au témoin antihebb(0) (spikes, W_out, W_rec, thr).
+ - ⚠ Pic RSS du smoke : 4028 Mo, à cause des copies de 4 cœurs ; je l'avais estimé à ~1 Go. Porte ouverte à 5,33 Go, donc la marge de 4 Go a probablement été entamée pendant environ 1 min. Pas d'OOM, tous les lourds sont vivants. Les bras eux-mêmes ne font pas de copie ; le témoin identique était à 0,88 Go.
+- **Bras** : chaîne code/chain_sp.sh, PID 1049321, setsid nice 10. Elle n'écrit pas dans le relais et ne signale aucun process. SP1 puis SP2, chacun seulement si MemAvailable ≥ 5,2 Go et moins de 4 lourds. **Bloqué** en ce moment : 6 lourds (348162, 405144, 437490, 537926, 838852, 1036049), 5,34 Go. Estimation grossière : porte ouverte vers 08 h 30 (fin de 1036049, 537926, 348162), puis ~50 à 80 min par bras. Verdicts automatiques dans lever2_sparse/verdict_SP{1,2}/, entrée relais à la main ensuite.
+— SPIRA Hashing
diff --git a/results/hashing/lever2_sparse/relay/R3_SP1_1106.md b/results/hashing/lever2_sparse/relay/R3_SP1_1106.md
new file mode 100644
index 0000000000000000000000000000000000000000..7c191dd245e2d08307a9dbeffa30d24c6fcd47fe
--- /dev/null
+++ b/results/hashing/lever2_sparse/relay/R3_SP1_1106.md
@@ -0,0 +1,6 @@
+
+### SPIRA Hashing — verdict levier 2 SP1 (k-WTA k=51) consigné + état — 11 h 06 (Toronto)
+- Verdict SP1 (hashing_gen/lever2_sparse/verdict_SP1/verdict_SP1.md, 10 h 43, verdict_SP.py sha256 7a6d5414…a2deb) : **REJETÉ** — seen 98,462 vs 98,462 (0/0) ; fc2 −0,236 n.s. ; fresh_en −0,457 pt, b/c 19/6, p=0,0146, IC95 [−0,799 ; −0,142] → PERTE ; fresh_fr +0,064 n.s. ; test20k strict −0,107 n.s. (test20k non strict jamais cité). Ressources SP1 r2 : min MemAvailable 6,28 Go, max VmRSS 900 Mo.
+- Recompte Checker 10 h 52–53 déjà fait : **PASS**, chiffres identiques. Rejet non dû au seul « pas de gain seen » (perte fresh_en significative), donc pas de recompte règle patron requis. SP1 jeté, final.
+- En cours : SP2 PID 90522 ; cov b v3 r2 15953 (tick 310k/5,49M) ; cov b broad r2 16884 (tick 300k/1,96M) ; v1b fix1 : build EXIT 0 à 10 h 48 (min MemAvailable 6,17 Go, max VmRSS 513 Mo), manifest en attente de porte (lourds = 4 : 15242 15953 16884 90522), STATUS RUNNING. Lourds Hashing+Checker = 4 (pas > 4). MemAvailable ≈ 8,8 Go. Rien tué, rien poussé.
+— SPIRA Hashing
diff --git a/results/hashing/lever2_sparse/relay/R4_reponse_relay_1115.md b/results/hashing/lever2_sparse/relay/R4_reponse_relay_1115.md
new file mode 100644
index 0000000000000000000000000000000000000000..57cad0633a38fc06f1d63f8328c1b90343f9d667
--- /dev/null
+++ b/results/hashing/lever2_sparse/relay/R4_reponse_relay_1115.md
@@ -0,0 +1,17 @@
+
+### Lu/appliqué — Hashing — 11 h 16 (Toronto) — réponse Relay 11 h 15
+- **SP2** PID 90522 (chain_sp_r2 15288) : SNN 2/2 époques finies (époque 2 tick 20 000/24 000 à 1 755 s, 25 t/s) ; passe d'écriture hippocampe faite à 1 933 s (11 h 16 ; SP1 : 1 843 s). Profil SP1 (DONE à 2 708 s) ⇒ **DONE SP2 ≈ 11 h 30–11 h 31**, verdict automatique par chain_sp_r2 via verdict_SP.py 7a6d5414 dans la seconde qui suit. Chaîne SP terminée après SP2 (aucun autre bras).
+- **cov b v3 r2** PID 15953 : tick 360 000/5 490 997 (époque 1/2) à 4 559 s (11 h 15). Débit 78,7–83,3 ticks/s (moyen depuis 10k : 80,2). Reste 10 621 994 ticks SNN ⇒ **fin SNN ≈ dim. 22 h 40 – lun. 00 h 05** (hors passe AM/éval).
+- **cov b broad r2** PID 16884 : tick 360 000/1 960 514 (époque 1/2) à 4 578 s (11 h 16). Débit 79–84 ticks/s. Reste 3 561 028 ticks SNN ⇒ **fin SNN ≈ sam. 23 h 00 – 23 h 50** (hors passe AM/éval).
+- **v1b fix1** (porte 21358) : STATUS RUNNING ; build EXIT 0 à 10 h 48 (min MemAvailable 6 170 595 328 o, max VmRSS 512 856 kB) ; manifest en attente : dernier « gate wait » 11 h 14 : MemAvailable 7,70 Go, lourds = 4 (15242 15953 16884 90522), porte = lourds < 4 comptés sur toute la box. Ouverture attendue à la fin de SP2 (~11 h 31) si aucun autre lourd n'apparaît ; le manifest part alors automatiquement. Comptage box-wide maintenu en attendant la décision de Philippe-Antoine.
+- **Push SP1 : rien poussé.** Le PASS Checker 10 h 52/10 h 53 porte sur le recompte (arithmétique + décision REJET) et sur son propre push 9c1c8ab7 ; il ne nomme ni verdict_SP1.md ni verdict_SP1.json ni le log. Fichiers inspectés (agrégats seulement : aucun hits, spans, masque, vecteur par position ni texte d'éval) :
+ - hashing_gen/lever2_sparse/verdict_SP1/verdict_SP1.md — 2 505 o — sha256 6666a2bd95db8f7a22c80906c84614037e51c3394ae6688e6f115163bcf962fa
+ - hashing_gen/lever2_sparse/verdict_SP1/verdict_SP1.json — 7 631 o — sha256 bdc61bfb88c34774a0e297f90e2703907ca876ad78a3249dfc3e24dd92edb6a1
+ - hashing_gen/lever2_sparse/logs/verdict_SP1.log (→ verdict_SP1.log.txt) — 6 544 o — sha256 81eab34457a07f76f9bc9be465c7848480bc3766341a750d680c28b124fc9850
+ - Cible prévue : results/hashing/lever2_sparse/verdict_SP1/ (ajout seul) ; script = results/hashing/lever2_sparse/code_v42/verdict_SP_r1.py (sha 7a6d5414, déjà sur HF, pas re-poussé).
+ - **Checker : PASS de push demandé** sur ces 3 fichiers (noms + sha256 ci-dessus).
+- Signe fresh_fr (réponse à la correction Checker 11 h 08), mesuré dans les fichiers : verdict_SP1.json acc_cand_pct 0,0642, acc_ref_pct 0,0, b_ref_only 0, c_cand_only 1 ; short_old.SP1.log fresh_fr fused_invocab_pct 0,064. Donc SP1 0,064 vs réf 0,000, Δ = +0,064 n.s. (le tableau Checker 10 h 53 donne aussi +0,064). REJET inchangé de toute façon.
+- **Verdict SP2** : règle pré-déclarée inchangée — ADOPTÉ seulement si meilleur sur seen ET sur le frais, avec les réserves Checker, via verdict_SP.py 7a6d5414. Montée en échelle seulement si SP2 ADOPTÉ, avec un témoin à budget égal.
+- Aucune éval broad_local_v1 hors positions propres (masque clean + masque union v4.2).
+- Rien tué, aucune porte modifiée, rien dans /tmp, checker/ et broad/ non touchés. MemAvailable 7,30 Go à 11 h 16.
+— SPIRA Hashing
diff --git a/results/hashing/lever2_sparse/short_old/results.jsonl b/results/hashing/lever2_sparse/short_old/results.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..73f7bc2629f1b91dbe955cd969a25195294df34b
--- /dev/null
+++ b/results/hashing/lever2_sparse/short_old/results.jsonl
@@ -0,0 +1,10 @@
+{"arm": "SP1", "mode": "SP1", "snn_tokens": 24000, "window": "seen", "n": 4000, "fused_invocab_pct": 98.462, "fused_all_pct": 98.0, "snn_invocab_pct": 40.462, "cal": {"scale": 1.0320894243874168, "sigma_fast": 0.09401657209357715, "sigma_slow": 0.09109343616167705}, "SP_train_cal": {"mode": "SP1", "k": 51, "N": 512, "rate_train": 0.099609375, "ticks_train": 48000, "spikes_per_tick_train_min_max": [51, 51], "rate_eval": 0.099609375, "ticks_eval": 3000, "spikes_per_tick_eval_min_max": [51, 51], "theta_mean": 0.0, "theta_min": 0.0, "theta_max": 0.0, "thr_mean": 2.899634838104248, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "SP_window": {"mode": "SP1", "k": 51, "N": 512, "rate_train": 0.099609375, "ticks_train": 48000, "spikes_per_tick_train_min_max": [51, 51], "rate_eval": 0.099609375, "ticks_eval": 4000, "spikes_per_tick_eval_min_max": [51, 51], "theta_mean": 0.0, "theta_min": 0.0, "theta_max": 0.0, "thr_mean": 2.899634838104248, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "train_acc": [0.044625, 0.14341666666666666], "eval_s": 130.8, "peak_rss_mb": 811.7}
+{"arm": "SP1", "mode": "SP1", "snn_tokens": 24000, "window": "fc2", "n": 4000, "fused_invocab_pct": 8.019, "fused_all_pct": 5.55, "snn_invocab_pct": 3.263, "cal": {"scale": 1.0320894243874168, "sigma_fast": 0.09401657209357715, "sigma_slow": 0.09109343616167705}, "SP_train_cal": {"mode": "SP1", "k": 51, "N": 512, "rate_train": 0.099609375, "ticks_train": 48000, "spikes_per_tick_train_min_max": [51, 51], "rate_eval": 0.099609375, "ticks_eval": 3000, "spikes_per_tick_eval_min_max": [51, 51], "theta_mean": 0.0, "theta_min": 0.0, "theta_max": 0.0, "thr_mean": 2.899634838104248, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "SP_window": {"mode": "SP1", "k": 51, "N": 512, "rate_train": 0.099609375, "ticks_train": 48000, "spikes_per_tick_train_min_max": [51, 51], "rate_eval": 0.099609375, "ticks_eval": 4000, "spikes_per_tick_eval_min_max": [51, 51], "theta_mean": 0.0, "theta_min": 0.0, "theta_max": 0.0, "thr_mean": 2.899634838104248, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "train_acc": [0.044625, 0.14341666666666666], "eval_s": 126.8, "peak_rss_mb": 812.9}
+{"arm": "SP1", "mode": "SP1", "snn_tokens": 24000, "window": "fresh_en", "n": 4000, "fused_invocab_pct": 0.773, "fused_all_pct": 0.55, "snn_invocab_pct": 0.808, "cal": {"scale": 1.0320894243874168, "sigma_fast": 0.09401657209357715, "sigma_slow": 0.09109343616167705}, "SP_train_cal": {"mode": "SP1", "k": 51, "N": 512, "rate_train": 0.099609375, "ticks_train": 48000, "spikes_per_tick_train_min_max": [51, 51], "rate_eval": 0.099609375, "ticks_eval": 3000, "spikes_per_tick_eval_min_max": [51, 51], "theta_mean": 0.0, "theta_min": 0.0, "theta_max": 0.0, "thr_mean": 2.899634838104248, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "SP_window": {"mode": "SP1", "k": 51, "N": 512, "rate_train": 0.099609375, "ticks_train": 48000, "spikes_per_tick_train_min_max": [51, 51], "rate_eval": 0.099609375, "ticks_eval": 4000, "spikes_per_tick_eval_min_max": [51, 51], "theta_mean": 0.0, "theta_min": 0.0, "theta_max": 0.0, "thr_mean": 2.899634838104248, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "train_acc": [0.044625, 0.14341666666666666], "eval_s": 244.3, "peak_rss_mb": 813.1}
+{"arm": "SP1", "mode": "SP1", "snn_tokens": 24000, "window": "fresh_fr", "n": 4000, "fused_invocab_pct": 0.064, "fused_all_pct": 0.025, "snn_invocab_pct": 0.0, "cal": {"scale": 1.0320894243874168, "sigma_fast": 0.09401657209357715, "sigma_slow": 0.09109343616167705}, "SP_train_cal": {"mode": "SP1", "k": 51, "N": 512, "rate_train": 0.099609375, "ticks_train": 48000, "spikes_per_tick_train_min_max": [51, 51], "rate_eval": 0.099609375, "ticks_eval": 3000, "spikes_per_tick_eval_min_max": [51, 51], "theta_mean": 0.0, "theta_min": 0.0, "theta_max": 0.0, "thr_mean": 2.899634838104248, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "SP_window": {"mode": "SP1", "k": 51, "N": 512, "rate_train": 0.099609375, "ticks_train": 48000, "spikes_per_tick_train_min_max": [51, 51], "rate_eval": 0.099609375, "ticks_eval": 4000, "spikes_per_tick_eval_min_max": [51, 51], "theta_mean": 0.0, "theta_min": 0.0, "theta_max": 0.0, "thr_mean": 2.899634838104248, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "train_acc": [0.044625, 0.14341666666666666], "eval_s": 132.3, "peak_rss_mb": 878.6}
+{"arm": "SP1", "mode": "SP1", "snn_tokens": 24000, "window": "test20k", "n": 4000, "fused_invocab_pct": 0.714, "fused_all_pct": 0.5, "snn_invocab_pct": 0.714, "cal": {"scale": 1.0320894243874168, "sigma_fast": 0.09401657209357715, "sigma_slow": 0.09109343616167705}, "SP_train_cal": {"mode": "SP1", "k": 51, "N": 512, "rate_train": 0.099609375, "ticks_train": 48000, "spikes_per_tick_train_min_max": [51, 51], "rate_eval": 0.099609375, "ticks_eval": 3000, "spikes_per_tick_eval_min_max": [51, 51], "theta_mean": 0.0, "theta_min": 0.0, "theta_max": 0.0, "thr_mean": 2.899634838104248, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "SP_window": {"mode": "SP1", "k": 51, "N": 512, "rate_train": 0.099609375, "ticks_train": 48000, "spikes_per_tick_train_min_max": [51, 51], "rate_eval": 0.099609375, "ticks_eval": 4000, "spikes_per_tick_eval_min_max": [51, 51], "theta_mean": 0.0, "theta_min": 0.0, "theta_max": 0.0, "thr_mean": 2.899634838104248, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "train_acc": [0.044625, 0.14341666666666666], "eval_s": 134.0, "peak_rss_mb": 878.6}
+{"arm": "SP2", "mode": "SP2", "snn_tokens": 24000, "window": "seen", "n": 4000, "fused_invocab_pct": 98.462, "fused_all_pct": 98.0, "snn_invocab_pct": 42.346, "cal": {"scale": 1.0584227105556867, "sigma_fast": 0.08620058581641785, "sigma_slow": 0.08144249453147252}, "SP_train_cal": {"mode": "SP2", "k": 51, "N": 512, "rate_train": 0.09024409993489584, "ticks_train": 48000, "spikes_per_tick_train_min_max": [6, 132], "rate_eval": 0.08046419270833334, "ticks_eval": 3000, "spikes_per_tick_eval_min_max": [9, 95], "theta_mean": -0.4684603214263916, "theta_min": -2.0818865299224854, "theta_max": 1.3757221698760986, "thr_mean": 3.193622589111328, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "SP_window": {"mode": "SP2", "k": 51, "N": 512, "rate_train": 0.09024409993489584, "ticks_train": 48000, "spikes_per_tick_train_min_max": [6, 132], "rate_eval": 0.04928955078125, "ticks_eval": 4000, "spikes_per_tick_eval_min_max": [5, 60], "theta_mean": -0.4684603214263916, "theta_min": -2.0818865299224854, "theta_max": 1.3757221698760986, "thr_mean": 3.193622589111328, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "train_acc": [0.051041666666666666, 0.12216666666666667], "eval_s": 136.9, "peak_rss_mb": 811.8}
+{"arm": "SP2", "mode": "SP2", "snn_tokens": 24000, "window": "fc2", "n": 4000, "fused_invocab_pct": 7.783, "fused_all_pct": 5.4, "snn_invocab_pct": 3.105, "cal": {"scale": 1.0584227105556867, "sigma_fast": 0.08620058581641785, "sigma_slow": 0.08144249453147252}, "SP_train_cal": {"mode": "SP2", "k": 51, "N": 512, "rate_train": 0.09024409993489584, "ticks_train": 48000, "spikes_per_tick_train_min_max": [6, 132], "rate_eval": 0.08046419270833334, "ticks_eval": 3000, "spikes_per_tick_eval_min_max": [9, 95], "theta_mean": -0.4684603214263916, "theta_min": -2.0818865299224854, "theta_max": 1.3757221698760986, "thr_mean": 3.193622589111328, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "SP_window": {"mode": "SP2", "k": 51, "N": 512, "rate_train": 0.09024409993489584, "ticks_train": 48000, "spikes_per_tick_train_min_max": [6, 132], "rate_eval": 0.04669677734375, "ticks_eval": 4000, "spikes_per_tick_eval_min_max": [4, 61], "theta_mean": -0.4684603214263916, "theta_min": -2.0818865299224854, "theta_max": 1.3757221698760986, "thr_mean": 3.193622589111328, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "train_acc": [0.051041666666666666, 0.12216666666666667], "eval_s": 134.1, "peak_rss_mb": 813.2}
+{"arm": "SP2", "mode": "SP2", "snn_tokens": 24000, "window": "fresh_en", "n": 4000, "fused_invocab_pct": 1.264, "fused_all_pct": 0.9, "snn_invocab_pct": 1.089, "cal": {"scale": 1.0584227105556867, "sigma_fast": 0.08620058581641785, "sigma_slow": 0.08144249453147252}, "SP_train_cal": {"mode": "SP2", "k": 51, "N": 512, "rate_train": 0.09024409993489584, "ticks_train": 48000, "spikes_per_tick_train_min_max": [6, 132], "rate_eval": 0.08046419270833334, "ticks_eval": 3000, "spikes_per_tick_eval_min_max": [9, 95], "theta_mean": -0.4684603214263916, "theta_min": -2.0818865299224854, "theta_max": 1.3757221698760986, "thr_mean": 3.193622589111328, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "SP_window": {"mode": "SP2", "k": 51, "N": 512, "rate_train": 0.09024409993489584, "ticks_train": 48000, "spikes_per_tick_train_min_max": [6, 132], "rate_eval": 0.04788037109375, "ticks_eval": 4000, "spikes_per_tick_eval_min_max": [5, 59], "theta_mean": -0.4684603214263916, "theta_min": -2.0818865299224854, "theta_max": 1.3757221698760986, "thr_mean": 3.193622589111328, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "train_acc": [0.051041666666666666, 0.12216666666666667], "eval_s": 145.6, "peak_rss_mb": 813.2}
+{"arm": "SP2", "mode": "SP2", "snn_tokens": 24000, "window": "fresh_fr", "n": 4000, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 1.0584227105556867, "sigma_fast": 0.08620058581641785, "sigma_slow": 0.08144249453147252}, "SP_train_cal": {"mode": "SP2", "k": 51, "N": 512, "rate_train": 0.09024409993489584, "ticks_train": 48000, "spikes_per_tick_train_min_max": [6, 132], "rate_eval": 0.08046419270833334, "ticks_eval": 3000, "spikes_per_tick_eval_min_max": [9, 95], "theta_mean": -0.4684603214263916, "theta_min": -2.0818865299224854, "theta_max": 1.3757221698760986, "thr_mean": 3.193622589111328, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "SP_window": {"mode": "SP2", "k": 51, "N": 512, "rate_train": 0.09024409993489584, "ticks_train": 48000, "spikes_per_tick_train_min_max": [6, 132], "rate_eval": 0.03980517578125, "ticks_eval": 4000, "spikes_per_tick_eval_min_max": [4, 57], "theta_mean": -0.4684603214263916, "theta_min": -2.0818865299224854, "theta_max": 1.3757221698760986, "thr_mean": 3.193622589111328, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "train_acc": [0.051041666666666666, 0.12216666666666667], "eval_s": 144.9, "peak_rss_mb": 877.8}
+{"arm": "SP2", "mode": "SP2", "snn_tokens": 24000, "window": "test20k", "n": 4000, "fused_invocab_pct": 0.714, "fused_all_pct": 0.5, "snn_invocab_pct": 0.571, "cal": {"scale": 1.0584227105556867, "sigma_fast": 0.08620058581641785, "sigma_slow": 0.08144249453147252}, "SP_train_cal": {"mode": "SP2", "k": 51, "N": 512, "rate_train": 0.09024409993489584, "ticks_train": 48000, "spikes_per_tick_train_min_max": [6, 132], "rate_eval": 0.08046419270833334, "ticks_eval": 3000, "spikes_per_tick_eval_min_max": [9, 95], "theta_mean": -0.4684603214263916, "theta_min": -2.0818865299224854, "theta_max": 1.3757221698760986, "thr_mean": 3.193622589111328, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "SP_window": {"mode": "SP2", "k": 51, "N": 512, "rate_train": 0.09024409993489584, "ticks_train": 48000, "spikes_per_tick_train_min_max": [6, 132], "rate_eval": 0.0473212890625, "ticks_eval": 4000, "spikes_per_tick_eval_min_max": [4, 72], "theta_mean": -0.4684603214263916, "theta_min": -2.0818865299224854, "theta_max": 1.3757221698760986, "thr_mean": 3.193622589111328, "thr_at_max_frac": 0.0, "thr_at_min_frac": 0.0}, "train_acc": [0.051041666666666666, 0.12216666666666667], "eval_s": 135.0, "peak_rss_mb": 877.8}
diff --git a/results/hashing/lever2_sparse/smoke/v42_identity_0958/new/verdict_AH1/verdict_AH1.json b/results/hashing/lever2_sparse/smoke/v42_identity_0958/new/verdict_AH1/verdict_AH1.json
new file mode 100644
index 0000000000000000000000000000000000000000..7e7ebea08cf41441fd33d4992a7949b32d4da9be
--- /dev/null
+++ b/results/hashing/lever2_sparse/smoke/v42_identity_0958/new/verdict_AH1/verdict_AH1.json
@@ -0,0 +1,248 @@
+{
+ "cand": "AH1 (smoke)",
+ "ref": "ref (eta_ah=0, budget égal)",
+ "corpus": "broad/old_local_v1",
+ "snn_tokens": 24000,
+ "epochs": 2,
+ "max_positions": 4000,
+ "windows_measured": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_not_measured": [
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen",
+ "aucun gain significatif sur une fenêtre fraîche",
+ "perte(s) significative(s) : fc2"
+ ],
+ "losses": [
+ "fc2"
+ ],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 4000,
+ "n_clean": 2600,
+ "n_invocab_clean_ref": 2600,
+ "n_invocab_clean_cand": 2600,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 98.46153846153847,
+ "acc_cand_pct": 98.46153846153847,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 42,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a58d536c9af78bbf8451905f7c68222576dfc096bfd3b52f300d992b5a9240b4"
+ },
+ "fc2": {
+ "n_positions": 4000,
+ "n_clean": 2544,
+ "n_invocab_clean_ref": 2544,
+ "n_invocab_clean_cand": 2544,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 8.254716981132075,
+ "acc_cand_pct": 7.70440251572327,
+ "delta_pct": -0.550314465408805,
+ "b_ref_only": 24,
+ "c_cand_only": 10,
+ "mcnemar_p": 0.024306510109454393,
+ "boot_ci95_delta_pct": [
+ -1.1080551822495261,
+ -0.03875856449594405
+ ],
+ "boot_p": 0.0444,
+ "n_blocks": 37,
+ "sig_gain": false,
+ "sig_loss": true,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ },
+ "fresh_en": {
+ "n_positions": 4000,
+ "n_clean": 2847,
+ "n_invocab_clean_ref": 2847,
+ "n_invocab_clean_cand": 2847,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 1.2293642430628733,
+ "acc_cand_pct": 1.1239901650860555,
+ "delta_pct": -0.10537407797681775,
+ "b_ref_only": 11,
+ "c_cand_only": 8,
+ "mcnemar_p": 0.6476058959960938,
+ "boot_ci95_delta_pct": [
+ -0.416815013513543,
+ 0.17800087275434376
+ ],
+ "boot_p": 0.572,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ },
+ "fresh_fr": {
+ "n_positions": 4000,
+ "n_clean": 1557,
+ "n_invocab_clean_ref": 1557,
+ "n_invocab_clean_cand": 1557,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 30,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ },
+ "test20k": {
+ "n_positions": 4000,
+ "n_clean": 2801,
+ "n_invocab_clean_ref": 2801,
+ "n_invocab_clean_cand": 2801,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.8211353088182792,
+ "acc_cand_pct": 0.7497322384862549,
+ "delta_pct": -0.07140307033202431,
+ "b_ref_only": 4,
+ "c_cand_only": 2,
+ "mcnemar_p": 0.6875,
+ "boot_ci95_delta_pct": [
+ -0.24673951357067336,
+ 0.10556039405894535
+ ],
+ "boot_p": 0.5462,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 17883
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 2.576304133253307,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 95.88523432828516,
+ "ci95": [
+ 95.17631636781792,
+ 96.55817642997651
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 2.394531229823895,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 96.06700723171457,
+ "ci95": [
+ 95.40164839357195,
+ 96.71787864908593
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": 0.18177290342940466,
+ "ci95": [
+ 0.024249240736329017,
+ 0.34262003170707644
+ ],
+ "ci95_boot_positions_seed25": [
+ 0.03944741090992139,
+ 0.326473583105809
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "note": "moyenne fraîche = fc2, fresh_en, fresh_fr, test20k strict SEULEMENT (test_v3 et queries non mesurés par les bras) : l'écart seen − moyenne fraîche n'est PAS comparable à celui du banc v4 (qui inclut test_v3) ; décision non affectée ; neither_code exclu",
+ "comparable_to_bench_v4": false
+ },
+ "seen_trained_audit": {
+ "window_is_train_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 24000,
+ "cand": 24000
+ },
+ "max_ctx_patch_index": 3999,
+ "max_byte_evaluated": 21049,
+ "invocab_both_n": 2600,
+ "trained_invocab_n_ref": 2600,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 2600,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "script_sha256": "4b89488edb11725434566f35d941282caba3a6487fadcd5f76b6e4621df6a19d",
+ "inputs_sha256": {
+ "ref__seen.npz": "a508542b6c6d1f4aafcb3c94fed843be7b4d5f4d136aeefca81cdee31d62eac8",
+ "ref__fc2.npz": "73ac8b9f777a42e223852450ef3c795122651893358407d53632f277f41f6003",
+ "ref__fresh_en.npz": "e2563d51b3677e4521e579c7e95afde18924ba8a7cee05c24f8ced0976b7817e",
+ "ref__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "ref__test20k.npz": "3c304dcbb48c6907b519fd42cf95bd817f52343dc588d478aa4273292d99fd4d",
+ "AH1__seen.npz": "a8f2e55db3debd594f07eb4df826bd41bcfcfd54cf685b69946a7ccdb94f9108",
+ "AH1__fc2.npz": "50ee8648bba55b661a87f850078a6fbac7f3edde95ba0621081c046fad4e89b3",
+ "AH1__fresh_en.npz": "8ae4cbd7ccb335eb702b77e14193fc29962daea196e28d7436471a833f1dab3d",
+ "AH1__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "AH1__test20k.npz": "6a64e0ea7498e0e83e1521cf1d273751fcfad5e2f0207490dc1c271a564e8faf"
+ },
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178",
+ "mask_path": "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+}
\ No newline at end of file
diff --git a/results/hashing/lever2_sparse/smoke/v42_identity_0958/new/verdict_AH1/verdict_AH1.md b/results/hashing/lever2_sparse/smoke/v42_identity_0958/new/verdict_AH1/verdict_AH1.md
new file mode 100644
index 0000000000000000000000000000000000000000..87bfe3f11d179e135495533b865bf67200f6d160
--- /dev/null
+++ b/results/hashing/lever2_sparse/smoke/v42_identity_0958/new/verdict_AH1/verdict_AH1.md
@@ -0,0 +1,26 @@
+# Verdict levier 2 — AH1 (smoke) contre ref (eta_ah = 0, budget égal), old_local_v1 court
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche; perte(s) significative(s) : fc2
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), 4000 positions par fenêtre, appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | n apparié | AH1 % | réf % | Δ pts | b (réf seule) / c (AH1 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 2600 | 98.462 | 98.462 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fc2 | 2544 | 7.704 | 8.255 | -0.550 | 24/10 | 0.0243 | [-1.108 ; -0.039] | PERTE |
+| fresh_en | 2847 | 1.124 | 1.229 | -0.105 | 11/8 | 0.648 | [-0.417 ; +0.178] | n.s. |
+| fresh_fr | 1557 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test20k strict (old_local_v1/test.bin, union old ∪ broad) | 2801 | 0.750 | 0.821 | -0.071 | 4/2 | 0.688 | [-0.247 ; +0.106] | n.s. |
+| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+
+test20k strict : 0 positions exclues sur 4000 (0 par old_local_v1, 0 par broad_local_v1), octets évalués jusqu'à 17883.
+
+Audit seen (trained_frac, positions in-vocab des deux bras dont le patch de contexte est dans ids[:snn_tokens]) : réf 1.0 (2600/2600), AH1 1.0 (2600/2600) ; snn_tokens {'ref': 24000, 'cand': 24000} ; patch de contexte max 3999 ; fenêtre = train[:200000] True ; cibles contiguës True → seen COMPARABLE.
+
+Note : moyenne fraîche = fc2, fresh_en, fresh_fr, test20k strict SEULEMENT (test_v3 et queries non mesurés par les bras) : l'écart seen − moyenne fraîche n'est PAS comparable à celui du banc v4 (qui inclut test_v3) ; décision non affectée.
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k ; test_v3 non mesuré) : AH1 +96.067 pts [IC95 +95.402 ; +96.718] (fraîche 2.395 %) ; réf +95.885 pts [+95.176 ; +96.558] (fraîche 2.576 %) ; différence AH1 − réf +0.182 [blocs 512 o seed 0 : +0.024 ; +0.343] [positions seed 25 : +0.039 ; +0.326].
+
+Script sha256 4b89488edb11725434566f35d941282caba3a6487fadcd5f76b6e4621df6a19d ; masque sha256 50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178.
+
diff --git a/results/hashing/lever2_sparse/smoke/v42_identity_0958/new/verdict_AH2/verdict_AH2.json b/results/hashing/lever2_sparse/smoke/v42_identity_0958/new/verdict_AH2/verdict_AH2.json
new file mode 100644
index 0000000000000000000000000000000000000000..e1debbb7bdcee96eed426275e43dd2358937c0a9
--- /dev/null
+++ b/results/hashing/lever2_sparse/smoke/v42_identity_0958/new/verdict_AH2/verdict_AH2.json
@@ -0,0 +1,245 @@
+{
+ "cand": "AH2 (smoke)",
+ "ref": "ref (eta_ah=0, budget égal)",
+ "corpus": "broad/old_local_v1",
+ "snn_tokens": 24000,
+ "epochs": 2,
+ "max_positions": 4000,
+ "windows_measured": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_not_measured": [
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen",
+ "aucun gain significatif sur une fenêtre fraîche"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 4000,
+ "n_clean": 2600,
+ "n_invocab_clean_ref": 2600,
+ "n_invocab_clean_cand": 2600,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 98.46153846153847,
+ "acc_cand_pct": 98.46153846153847,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 42,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a58d536c9af78bbf8451905f7c68222576dfc096bfd3b52f300d992b5a9240b4"
+ },
+ "fc2": {
+ "n_positions": 4000,
+ "n_clean": 2544,
+ "n_invocab_clean_ref": 2544,
+ "n_invocab_clean_cand": 2544,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 8.254716981132075,
+ "acc_cand_pct": 7.822327044025157,
+ "delta_pct": -0.432389937106918,
+ "b_ref_only": 21,
+ "c_cand_only": 10,
+ "mcnemar_p": 0.07075554598122835,
+ "boot_ci95_delta_pct": [
+ -0.9094586196631579,
+ 0.038699690402476804
+ ],
+ "boot_p": 0.0808,
+ "n_blocks": 37,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ },
+ "fresh_en": {
+ "n_positions": 4000,
+ "n_clean": 2847,
+ "n_invocab_clean_ref": 2847,
+ "n_invocab_clean_cand": 2847,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 1.2293642430628733,
+ "acc_cand_pct": 1.053740779768177,
+ "delta_pct": -0.17562346329469625,
+ "b_ref_only": 11,
+ "c_cand_only": 6,
+ "mcnemar_p": 0.332305908203125,
+ "boot_ci95_delta_pct": [
+ -0.49191848208011235,
+ 0.10463899546564348
+ ],
+ "boot_p": 0.2912,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ },
+ "fresh_fr": {
+ "n_positions": 4000,
+ "n_clean": 1557,
+ "n_invocab_clean_ref": 1557,
+ "n_invocab_clean_cand": 1557,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 30,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ },
+ "test20k": {
+ "n_positions": 4000,
+ "n_clean": 2801,
+ "n_invocab_clean_ref": 2801,
+ "n_invocab_clean_cand": 2801,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.8211353088182792,
+ "acc_cand_pct": 0.7854337736522671,
+ "delta_pct": -0.035701535166012155,
+ "b_ref_only": 6,
+ "c_cand_only": 5,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -0.28198801550934083,
+ 0.2164521692670375
+ ],
+ "boot_p": 0.8708,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 17883
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 2.576304133253307,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 95.88523432828516,
+ "ci95": [
+ 95.17631636781792,
+ 96.55817642997651
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 2.4153753993614004,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 96.04616306217707,
+ "ci95": [
+ 95.35077178999046,
+ 96.71769863177818
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": 0.16092873389190743,
+ "ci95": [
+ 0.008778902411852845,
+ 0.3162619288237518
+ ],
+ "ci95_boot_positions_seed25": [
+ 0.020879195458747193,
+ 0.3051967816879966
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "note": "moyenne fraîche = fc2, fresh_en, fresh_fr, test20k strict SEULEMENT (test_v3 et queries non mesurés par les bras) : l'écart seen − moyenne fraîche n'est PAS comparable à celui du banc v4 (qui inclut test_v3) ; décision non affectée ; neither_code exclu",
+ "comparable_to_bench_v4": false
+ },
+ "seen_trained_audit": {
+ "window_is_train_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 24000,
+ "cand": 24000
+ },
+ "max_ctx_patch_index": 3999,
+ "max_byte_evaluated": 21049,
+ "invocab_both_n": 2600,
+ "trained_invocab_n_ref": 2600,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 2600,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "script_sha256": "4b89488edb11725434566f35d941282caba3a6487fadcd5f76b6e4621df6a19d",
+ "inputs_sha256": {
+ "ref__seen.npz": "a508542b6c6d1f4aafcb3c94fed843be7b4d5f4d136aeefca81cdee31d62eac8",
+ "ref__fc2.npz": "73ac8b9f777a42e223852450ef3c795122651893358407d53632f277f41f6003",
+ "ref__fresh_en.npz": "e2563d51b3677e4521e579c7e95afde18924ba8a7cee05c24f8ced0976b7817e",
+ "ref__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "ref__test20k.npz": "3c304dcbb48c6907b519fd42cf95bd817f52343dc588d478aa4273292d99fd4d",
+ "AH2__seen.npz": "fd8e860815ed298dc6da1df1b51f1554f3c93e19f5750e3099822323cbbab8d8",
+ "AH2__fc2.npz": "14c0935cca6715734237030cf92accc5886c4f4afb5aa0da9fd5437ad16ec8da",
+ "AH2__fresh_en.npz": "e83a5ddb3bc7652a0021a3ca1d150f0614bf7a0aa23196fb221cf79df47e776e",
+ "AH2__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "AH2__test20k.npz": "ba2acd5e2b0ace7a90efe48079e814bbab7275b0b85fa80e2eb1c9ab786470c8"
+ },
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178",
+ "mask_path": "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+}
\ No newline at end of file
diff --git a/results/hashing/lever2_sparse/smoke/v42_identity_0958/new/verdict_AH2/verdict_AH2.md b/results/hashing/lever2_sparse/smoke/v42_identity_0958/new/verdict_AH2/verdict_AH2.md
new file mode 100644
index 0000000000000000000000000000000000000000..55f8e57069aca3c121e571d6fb76e7ec68cccb84
--- /dev/null
+++ b/results/hashing/lever2_sparse/smoke/v42_identity_0958/new/verdict_AH2/verdict_AH2.md
@@ -0,0 +1,26 @@
+# Verdict levier 2 — AH2 (smoke) contre ref (eta_ah = 0, budget égal), old_local_v1 court
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), 4000 positions par fenêtre, appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | n apparié | AH2 % | réf % | Δ pts | b (réf seule) / c (AH2 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 2600 | 98.462 | 98.462 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fc2 | 2544 | 7.822 | 8.255 | -0.432 | 21/10 | 0.0708 | [-0.909 ; +0.039] | n.s. |
+| fresh_en | 2847 | 1.054 | 1.229 | -0.176 | 11/6 | 0.332 | [-0.492 ; +0.105] | n.s. |
+| fresh_fr | 1557 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test20k strict (old_local_v1/test.bin, union old ∪ broad) | 2801 | 0.785 | 0.821 | -0.036 | 6/5 | 1 | [-0.282 ; +0.216] | n.s. |
+| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+
+test20k strict : 0 positions exclues sur 4000 (0 par old_local_v1, 0 par broad_local_v1), octets évalués jusqu'à 17883.
+
+Audit seen (trained_frac, positions in-vocab des deux bras dont le patch de contexte est dans ids[:snn_tokens]) : réf 1.0 (2600/2600), AH2 1.0 (2600/2600) ; snn_tokens {'ref': 24000, 'cand': 24000} ; patch de contexte max 3999 ; fenêtre = train[:200000] True ; cibles contiguës True → seen COMPARABLE.
+
+Note : moyenne fraîche = fc2, fresh_en, fresh_fr, test20k strict SEULEMENT (test_v3 et queries non mesurés par les bras) : l'écart seen − moyenne fraîche n'est PAS comparable à celui du banc v4 (qui inclut test_v3) ; décision non affectée.
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k ; test_v3 non mesuré) : AH2 +96.046 pts [IC95 +95.351 ; +96.718] (fraîche 2.415 %) ; réf +95.885 pts [+95.176 ; +96.558] (fraîche 2.576 %) ; différence AH2 − réf +0.161 [blocs 512 o seed 0 : +0.009 ; +0.316] [positions seed 25 : +0.021 ; +0.305].
+
+Script sha256 4b89488edb11725434566f35d941282caba3a6487fadcd5f76b6e4621df6a19d ; masque sha256 50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178.
+
diff --git a/results/hashing/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_AH1/verdict_AH1.json b/results/hashing/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_AH1/verdict_AH1.json
new file mode 100644
index 0000000000000000000000000000000000000000..774e8c1da20766ba1d32198f04344cad28ef0734
--- /dev/null
+++ b/results/hashing/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_AH1/verdict_AH1.json
@@ -0,0 +1,231 @@
+{
+ "cand": "AH1 (smoke)",
+ "ref": "ref (eta_ah=0, budget égal)",
+ "corpus": "broad/old_local_v1",
+ "snn_tokens": 24000,
+ "epochs": 2,
+ "max_positions": 4000,
+ "windows_measured": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_not_measured": [
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen",
+ "aucun gain significatif sur une fenêtre fraîche",
+ "perte(s) significative(s) : fc2"
+ ],
+ "losses": [
+ "fc2"
+ ],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 4000,
+ "n_clean": 2600,
+ "n_invocab_clean_ref": 2600,
+ "n_invocab_clean_cand": 2600,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 98.46153846153847,
+ "acc_cand_pct": 98.46153846153847,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 42,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a58d536c9af78bbf8451905f7c68222576dfc096bfd3b52f300d992b5a9240b4"
+ },
+ "fc2": {
+ "n_positions": 4000,
+ "n_clean": 2544,
+ "n_invocab_clean_ref": 2544,
+ "n_invocab_clean_cand": 2544,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 8.254716981132075,
+ "acc_cand_pct": 7.70440251572327,
+ "delta_pct": -0.550314465408805,
+ "b_ref_only": 24,
+ "c_cand_only": 10,
+ "mcnemar_p": 0.024306510109454393,
+ "boot_ci95_delta_pct": [
+ -1.1080551822495261,
+ -0.03875856449594405
+ ],
+ "boot_p": 0.0444,
+ "n_blocks": 37,
+ "sig_gain": false,
+ "sig_loss": true,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ },
+ "fresh_en": {
+ "n_positions": 4000,
+ "n_clean": 2847,
+ "n_invocab_clean_ref": 2847,
+ "n_invocab_clean_cand": 2847,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 1.2293642430628733,
+ "acc_cand_pct": 1.1239901650860555,
+ "delta_pct": -0.10537407797681775,
+ "b_ref_only": 11,
+ "c_cand_only": 8,
+ "mcnemar_p": 0.6476058959960938,
+ "boot_ci95_delta_pct": [
+ -0.416815013513543,
+ 0.17800087275434376
+ ],
+ "boot_p": 0.572,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ },
+ "fresh_fr": {
+ "n_positions": 4000,
+ "n_clean": 1557,
+ "n_invocab_clean_ref": 1557,
+ "n_invocab_clean_cand": 1557,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 30,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ },
+ "test20k": {
+ "n_positions": 4000,
+ "n_clean": 2801,
+ "n_invocab_clean_ref": 2801,
+ "n_invocab_clean_cand": 2801,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.8211353088182792,
+ "acc_cand_pct": 0.7497322384862549,
+ "delta_pct": -0.07140307033202431,
+ "b_ref_only": 4,
+ "c_cand_only": 2,
+ "mcnemar_p": 0.6875,
+ "boot_ci95_delta_pct": [
+ -0.24673951357067336,
+ 0.10556039405894535
+ ],
+ "boot_p": 0.5462,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 17883
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 2.576304133253307,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 95.88523432828516,
+ "ci95": [
+ 95.17631636781792,
+ 96.55817642997651
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 2.394531229823895,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 96.06700723171457,
+ "ci95": [
+ 95.40164839357195,
+ 96.71787864908593
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": 0.18177290342940466,
+ "ci95": [
+ 0.024249240736329017,
+ 0.34262003170707644
+ ],
+ "ci95_boot_positions_seed25": [
+ 0.03944741090992139,
+ 0.326473583105809
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "note": "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+ },
+ "script_sha256": "2e876e512489fd43832399899d72d31d19b06f1a2cbf7785fed987e110f1d89d",
+ "inputs_sha256": {
+ "ref__seen.npz": "a508542b6c6d1f4aafcb3c94fed843be7b4d5f4d136aeefca81cdee31d62eac8",
+ "ref__fc2.npz": "73ac8b9f777a42e223852450ef3c795122651893358407d53632f277f41f6003",
+ "ref__fresh_en.npz": "e2563d51b3677e4521e579c7e95afde18924ba8a7cee05c24f8ced0976b7817e",
+ "ref__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "ref__test20k.npz": "3c304dcbb48c6907b519fd42cf95bd817f52343dc588d478aa4273292d99fd4d",
+ "AH1__seen.npz": "a8f2e55db3debd594f07eb4df826bd41bcfcfd54cf685b69946a7ccdb94f9108",
+ "AH1__fc2.npz": "50ee8648bba55b661a87f850078a6fbac7f3edde95ba0621081c046fad4e89b3",
+ "AH1__fresh_en.npz": "8ae4cbd7ccb335eb702b77e14193fc29962daea196e28d7436471a833f1dab3d",
+ "AH1__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "AH1__test20k.npz": "6a64e0ea7498e0e83e1521cf1d273751fcfad5e2f0207490dc1c271a564e8faf"
+ },
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178",
+ "mask_path": "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+}
\ No newline at end of file
diff --git a/results/hashing/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_AH1/verdict_AH1.md b/results/hashing/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_AH1/verdict_AH1.md
new file mode 100644
index 0000000000000000000000000000000000000000..42eadac9314633f2dfe8af9f48798f6f5d0e28a9
--- /dev/null
+++ b/results/hashing/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_AH1/verdict_AH1.md
@@ -0,0 +1,22 @@
+# Verdict levier 2 — AH1 (smoke) contre ref (eta_ah = 0, budget égal), old_local_v1 court
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche; perte(s) significative(s) : fc2
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), 4000 positions par fenêtre, appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | n apparié | AH1 % | réf % | Δ pts | b (réf seule) / c (AH1 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 2600 | 98.462 | 98.462 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fc2 | 2544 | 7.704 | 8.255 | -0.550 | 24/10 | 0.0243 | [-1.108 ; -0.039] | PERTE |
+| fresh_en | 2847 | 1.124 | 1.229 | -0.105 | 11/8 | 0.648 | [-0.417 ; +0.178] | n.s. |
+| fresh_fr | 1557 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test20k strict (old_local_v1/test.bin, union old ∪ broad) | 2801 | 0.750 | 0.821 | -0.071 | 4/2 | 0.688 | [-0.247 ; +0.106] | n.s. |
+| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+
+test20k strict : 0 positions exclues sur 4000 (0 par old_local_v1, 0 par broad_local_v1), octets évalués jusqu'à 17883.
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k ; test_v3 non mesuré) : AH1 +96.067 pts [IC95 +95.402 ; +96.718] (fraîche 2.395 %) ; réf +95.885 pts [+95.176 ; +96.558] (fraîche 2.576 %) ; différence AH1 − réf +0.182 [blocs 512 o seed 0 : +0.024 ; +0.343] [positions seed 25 : +0.039 ; +0.326].
+
+Script sha256 2e876e512489fd43832399899d72d31d19b06f1a2cbf7785fed987e110f1d89d ; masque sha256 50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178.
+
diff --git a/results/hashing/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_AH2/verdict_AH2.json b/results/hashing/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_AH2/verdict_AH2.json
new file mode 100644
index 0000000000000000000000000000000000000000..1ae5b400321301a78ed99c643529d30a32ab91c3
--- /dev/null
+++ b/results/hashing/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_AH2/verdict_AH2.json
@@ -0,0 +1,228 @@
+{
+ "cand": "AH2 (smoke)",
+ "ref": "ref (eta_ah=0, budget égal)",
+ "corpus": "broad/old_local_v1",
+ "snn_tokens": 24000,
+ "epochs": 2,
+ "max_positions": 4000,
+ "windows_measured": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_not_measured": [
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen",
+ "aucun gain significatif sur une fenêtre fraîche"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 4000,
+ "n_clean": 2600,
+ "n_invocab_clean_ref": 2600,
+ "n_invocab_clean_cand": 2600,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 98.46153846153847,
+ "acc_cand_pct": 98.46153846153847,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 42,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a58d536c9af78bbf8451905f7c68222576dfc096bfd3b52f300d992b5a9240b4"
+ },
+ "fc2": {
+ "n_positions": 4000,
+ "n_clean": 2544,
+ "n_invocab_clean_ref": 2544,
+ "n_invocab_clean_cand": 2544,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 8.254716981132075,
+ "acc_cand_pct": 7.822327044025157,
+ "delta_pct": -0.432389937106918,
+ "b_ref_only": 21,
+ "c_cand_only": 10,
+ "mcnemar_p": 0.07075554598122835,
+ "boot_ci95_delta_pct": [
+ -0.9094586196631579,
+ 0.038699690402476804
+ ],
+ "boot_p": 0.0808,
+ "n_blocks": 37,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ },
+ "fresh_en": {
+ "n_positions": 4000,
+ "n_clean": 2847,
+ "n_invocab_clean_ref": 2847,
+ "n_invocab_clean_cand": 2847,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 1.2293642430628733,
+ "acc_cand_pct": 1.053740779768177,
+ "delta_pct": -0.17562346329469625,
+ "b_ref_only": 11,
+ "c_cand_only": 6,
+ "mcnemar_p": 0.332305908203125,
+ "boot_ci95_delta_pct": [
+ -0.49191848208011235,
+ 0.10463899546564348
+ ],
+ "boot_p": 0.2912,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ },
+ "fresh_fr": {
+ "n_positions": 4000,
+ "n_clean": 1557,
+ "n_invocab_clean_ref": 1557,
+ "n_invocab_clean_cand": 1557,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 30,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ },
+ "test20k": {
+ "n_positions": 4000,
+ "n_clean": 2801,
+ "n_invocab_clean_ref": 2801,
+ "n_invocab_clean_cand": 2801,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)",
+ "acc_ref_pct": 0.8211353088182792,
+ "acc_cand_pct": 0.7854337736522671,
+ "delta_pct": -0.035701535166012155,
+ "b_ref_only": 6,
+ "c_cand_only": 5,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -0.28198801550934083,
+ 0.2164521692670375
+ ],
+ "boot_p": 0.8708,
+ "n_blocks": 35,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 17883
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 2.576304133253307,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 95.88523432828516,
+ "ci95": [
+ 95.17631636781792,
+ 96.55817642997651
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 2.4153753993614004,
+ "seen_pct": 98.46153846153847,
+ "gap_pct": 96.04616306217707,
+ "ci95": [
+ 95.35077178999046,
+ 96.71769863177818
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": 0.16092873389190743,
+ "ci95": [
+ 0.008778902411852845,
+ 0.3162619288237518
+ ],
+ "ci95_boot_positions_seed25": [
+ 0.020879195458747193,
+ 0.3051967816879966
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "note": "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+ },
+ "script_sha256": "2e876e512489fd43832399899d72d31d19b06f1a2cbf7785fed987e110f1d89d",
+ "inputs_sha256": {
+ "ref__seen.npz": "a508542b6c6d1f4aafcb3c94fed843be7b4d5f4d136aeefca81cdee31d62eac8",
+ "ref__fc2.npz": "73ac8b9f777a42e223852450ef3c795122651893358407d53632f277f41f6003",
+ "ref__fresh_en.npz": "e2563d51b3677e4521e579c7e95afde18924ba8a7cee05c24f8ced0976b7817e",
+ "ref__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "ref__test20k.npz": "3c304dcbb48c6907b519fd42cf95bd817f52343dc588d478aa4273292d99fd4d",
+ "AH2__seen.npz": "fd8e860815ed298dc6da1df1b51f1554f3c93e19f5750e3099822323cbbab8d8",
+ "AH2__fc2.npz": "14c0935cca6715734237030cf92accc5886c4f4afb5aa0da9fd5437ad16ec8da",
+ "AH2__fresh_en.npz": "e83a5ddb3bc7652a0021a3ca1d150f0614bf7a0aa23196fb221cf79df47e776e",
+ "AH2__fresh_fr.npz": "0d522e81f9cb286271fae25357459dc0e626edfc39f1d32d469feb840c74f99c",
+ "AH2__test20k.npz": "ba2acd5e2b0ace7a90efe48079e814bbab7275b0b85fa80e2eb1c9ab786470c8"
+ },
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178",
+ "mask_path": "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+}
\ No newline at end of file
diff --git a/results/hashing/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_AH2/verdict_AH2.md b/results/hashing/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_AH2/verdict_AH2.md
new file mode 100644
index 0000000000000000000000000000000000000000..b43aa730671a332873edc6167e8fab3c16f1adab
--- /dev/null
+++ b/results/hashing/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_AH2/verdict_AH2.md
@@ -0,0 +1,22 @@
+# Verdict levier 2 — AH2 (smoke) contre ref (eta_ah = 0, budget égal), old_local_v1 court
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), 4000 positions par fenêtre, appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | n apparié | AH2 % | réf % | Δ pts | b (réf seule) / c (AH2 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 2600 | 98.462 | 98.462 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fc2 | 2544 | 7.822 | 8.255 | -0.432 | 21/10 | 0.0708 | [-0.909 ; +0.039] | n.s. |
+| fresh_en | 2847 | 1.054 | 1.229 | -0.176 | 11/6 | 0.332 | [-0.492 ; +0.105] | n.s. |
+| fresh_fr | 1557 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test20k strict (old_local_v1/test.bin, union old ∪ broad) | 2801 | 0.785 | 0.821 | -0.036 | 6/5 | 1 | [-0.282 ; +0.216] | n.s. |
+| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |
+
+test20k strict : 0 positions exclues sur 4000 (0 par old_local_v1, 0 par broad_local_v1), octets évalués jusqu'à 17883.
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k ; test_v3 non mesuré) : AH2 +96.046 pts [IC95 +95.351 ; +96.718] (fraîche 2.415 %) ; réf +95.885 pts [+95.176 ; +96.558] (fraîche 2.576 %) ; différence AH2 − réf +0.161 [blocs 512 o seed 0 : +0.009 ; +0.316] [positions seed 25 : +0.021 ; +0.305].
+
+Script sha256 2e876e512489fd43832399899d72d31d19b06f1a2cbf7785fed987e110f1d89d ; masque sha256 50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178.
+
diff --git a/results/hashing/lever2_sparse/smoke/v42_identity_0958/vSP_new.py b/results/hashing/lever2_sparse/smoke/v42_identity_0958/vSP_new.py
new file mode 100644
index 0000000000000000000000000000000000000000..a74032ed6088b8c106f44c6e5b1bab424416b116
--- /dev/null
+++ b/results/hashing/lever2_sparse/smoke/v42_identity_0958/vSP_new.py
@@ -0,0 +1,134 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict levier 2 SPARSITÉ (SP1/SP2, argument 1) — copie de lever2/verdict_AH1/verdict_AH1.py, SEULS changements :
+bras candidat lu dans lever2_sparse/short_old, sortie dans lever2_sparse/verdict_, libellés. Témoin, masque et protocole identiques.
+(ex-docstring AH1) verdict levier 2 AH1 (eta_ah=1e-3) contre le témoin à budget égal ref (eta_ah=0), méthode banc v4.1
+(copie adaptée de m7_v41/strict/verdict_m7_v41_strict.py ; lecture seule des hits short_old/{ref,AH1}__*.npz, aucun modèle chargé).
+Fenêtres MESURÉES par run_l2.py (4000 positions chacune) : seen (= old_local_v1/train[:200000]), fc2, fresh_en, fresh_fr, test20k
+(= old_local_v1/test.bin, sha ce0526c6…, PAS broad_local_v1/test.bin ; masque strict propre recalculé : verdict_AH1/mask_oldtest_strict.npz,
+union old_local_v1 ∪ broad_local_v1). queries et test_v3 : NON évalués par les bras → absents (non mesurables). neither_code exclu.
+hit = fused_hit & invocab. Appariement par position si tgt_start et tgt_len identiques (vérifié). McNemar exact bilatéral = DÉCISION (p<0,05).
+Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un générateur seed 0, fenêtres dans l'ordre WIN, apparié ; stat = acc invocab.
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k strict ; test_v3 non mesuré). Bootstrap secondaire par positions, seed 25.
+Correctif v4.2 (Hashing 24 oct. ~09 h 39, Toronto ; original = verdict_SP.py.bak_0950) : positions gardées ssi in-vocab dans les DEUX bras (et propres) ;
+McNemar, taux (APPARIÉS, même dénominateur) et bootstrap sur ce seul ensemble. Tokenisation identique exigée (assert) ⇒ unités v4.2 = patches.
+Si invocab est identique entre bras (cas AH1/AH2), résultat identique à v4.1.
+Critère utilisateur : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche ET aucune perte significative sur une fenêtre valide ; sinon REJETÉ."""
+import sys, os, json, math, hashlib, numpy as np
+D = "/workspace/spira_shared/hashing_gen/lever2/short_old"; RT, CT = "ref", sys.argv[1]; assert CT in ("AH1", "AH2")
+DC = "/workspace/spira_shared/hashing_gen/lever2/short_old"; OP = f"/workspace/spira_shared/hashing_gen/lever2_sparse/smoke/v42_identity_0958/new/verdict_{CT}"
+MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+DESC = {'AH1': 'AH1 (smoke)', 'AH2': 'AH2 (smoke)', 'SP1': 'SP1 (k-WTA k=51 sur les spikes, N=512, rho=0.1)', 'SP2': 'SP2 (seuil adaptatif theta += 1e-3*(s-0.1), theta0=0, figé en éval)'}[CT]
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k"]; GAPW = FRESH
+NOT_MEASURED = ["queries", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+os.makedirs(OP, exist_ok=True); MS = np.load(MASKP)
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{DC}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_union": int((bo | bb_).sum()),
+ "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ ia1, ib1 = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k; one_side = int((ia1 ^ ib1).sum())
+ k = k & A["invocab"].astype(bool) & B["invocab"].astype(bool) # v4.2 : in-vocab dans les DEUX bras
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); p = binp(b, c)
+ ia, ib = k.copy(), k.copy()
+ acc_a, acc_b = 100 * (ha & k).sum() / ia.sum(), 100 * (hb & k).sum() / ib.sum() # taux APPARIÉS (même dénominateur)
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], k[k], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], k[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, k)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "n_invocab_clean_ref": int(ia.sum()), "n_invocab_clean_cand": int(ib.sum()), "invocab_identical": inv_same, "n_invocab_one_side_only_dropped": one_side, "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)", "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"])}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+# --- 09 h 58 (Toronto), réserve Checker 09 h 45 : audit trained_frac du seen (fenêtre = old_local_v1/train[:200000]) ---
+# SNN entraîné sur ids[:snn_tokens] (model.prepare : neuron_rows(ids[:n_snn]), cols_of(ids[:n_snn+1])). Position i du seen : contexte = patch i,
+# cible = patch i+1, SI les cibles sont contiguës depuis le patch 1 (vérifié : tgt_start[0] = fin du patch 0, tgt_start[i+1] = tgt_start[i]+tgt_len[i])
+# ET si la segmentation de train[:200000] coïncide avec celle de train.bin sur ce préfixe (hypothèse EPT gauche→droite ; derniers octets évalués << 200000).
+# Entraînée ssi patch de contexte i < snn_tokens. trained_frac < 0,99 => seen NON COMPARABLE et ADOPTÉ impossible.
+TRAIN_OLD = "/workspace/spira_shared/broad/old_local_v1/train.bin"
+def _snn_tokens(path, arm):
+ v = {json.loads(l).get("snn_tokens") for l in open(path) if l.strip() and json.loads(l).get("arm") == arm and json.loads(l).get("window") == "seen"}
+ return v.pop() if len(v) == 1 else None
+_A = np.load(f"{D}/{RT}__seen.npz"); _st, _ln = _A["tgt_start"].astype(np.int64), _A["tgt_len"].astype(np.int64)
+_contig = bool(np.all(_st[1:] == _st[:-1] + _ln[:-1]) and _st[0] > 0 and _st[0] <= int(_ln.max()))
+_wsha = hashlib.sha256(open(TRAIN_OLD, "rb").read(200_000)).hexdigest(); _wok = _wsha == R["seen"]["window_sha256"]
+_ksnn = {"ref": _snn_tokens(f"{D}/results.jsonl", RT), "cand": _snn_tokens(f"{DC}/results.jsonl", CT)}
+_k, _ha, _hb, _iv = KEEP["seen"]; _ivb = _k & _iv & np.load(f"{DC}/{CT}__seen.npz")["invocab"].astype(bool); _ctx = np.arange(len(_st))
+SEEN_AUDIT = {"window_is_train_prefix_200000": _wok, "targets_contiguous_from_patch1": _contig, "snn_tokens": _ksnn,
+ "max_ctx_patch_index": int(_ctx.max()), "max_byte_evaluated": int((_st + _ln).max()), "invocab_both_n": int(_ivb.sum())}
+for side in ("ref", "cand"):
+ n_tr = int((_ivb & (_ctx < _ksnn[side])).sum()) if (_wok and _contig and _ksnn[side]) else None
+ SEEN_AUDIT[f"trained_invocab_n_{side}"] = n_tr; SEEN_AUDIT[f"trained_frac_{side}"] = (n_tr / max(1, int(_ivb.sum()))) if n_tr is not None else None
+SEEN_OK = all(SEEN_AUDIT[f"trained_frac_{x}"] is not None and SEEN_AUDIT[f"trained_frac_{x}"] >= 0.99 for x in ("ref", "cand"))
+SEEN_AUDIT["seen_comparable"] = SEEN_OK; print("seen_audit", json.dumps(SEEN_AUDIT), flush=True)
+FRESH_MEAN_NOTE = ("moyenne fraîche = fc2, fresh_en, fresh_fr, test20k strict SEULEMENT (test_v3 et queries non mesurés par les bras) : "
+ "l'écart seen − moyenne fraîche n'est PAS comparable à celui du banc v4 (qui inclut test_v3) ; décision non affectée")
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+R2 = np.random.default_rng(25); BP = {}
+for w in WIN:
+ k, ha_, hb_, iv_ = KEEP[w]; m_ = k & iv_; r_ = ha_[m_].astype(np.float64); c_ = hb_[m_].astype(np.float64); n_ = len(r_); ar = np.empty(NB); ac = np.empty(NB)
+ for t in range(NB):
+ i = R2.integers(0, n_, n_); ar[t] = r_[i].mean(); ac[t] = c_[i].mean()
+ BP[w] = (100 * ar, 100 * ac)
+dgp = (BP["seen"][1] - np.mean([BP[w][1] for w in GAPW], axis=0)) - (BP["seen"][0] - np.mean([BP[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"]["ci95_boot_positions_seed25"] = [float(x) for x in np.percentile(dgp, [2.5, 97.5])]
+gap["windows"] = GAPW; gap["note"] = FRESH_MEAN_NOTE + " ; neither_code exclu"; gap["comparable_to_bench_v4"] = False
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "ADOPTÉ" if (SEEN_OK and R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not SEEN_OK: why.append("seen NON COMPARABLE (audit trained_frac < 0,99 ou non vérifiable)")
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+out = {"cand": DESC, "ref": "ref (eta_ah=0, budget égal)", "corpus": "broad/old_local_v1", "snn_tokens": 24000, "epochs": 2, "max_positions": 4000,
+ "windows_measured": WIN, "windows_not_measured": NOT_MEASURED, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap, "seen_trained_audit": SEEN_AUDIT,
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D if a == RT else DC}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN},
+ "mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest(), "mask_path": MASKP}
+json.dump(out, open(f"{OP}/verdict_{CT}.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict levier 2 — {DESC} contre ref (eta_ah = 0, budget égal), old_local_v1 court\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), 4000 positions par fenêtre, appariement par position (tokenisation identique vérifiée).", "",
+ f"| fenêtre | n apparié | {CT} % | réf % | Δ pts | b (réf seule) / c ({CT} seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ nm = "test20k strict (old_local_v1/test.bin, union old ∪ broad)" if w == "test20k" else w
+ md.append(f"| {nm} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "",
+ f"test20k strict : {EX['excluded_union']} positions exclues sur 4000 ({EX['excluded_by_old_local_v1']} par old_local_v1, {EX['excluded_by_broad_local_v1']} par broad_local_v1), octets évalués jusqu'à {EX['max_byte_evaluated']}.", "",
+ f"Audit seen (trained_frac, positions in-vocab des deux bras dont le patch de contexte est dans ids[:snn_tokens]) : réf {SEEN_AUDIT['trained_frac_ref']} ({SEEN_AUDIT['trained_invocab_n_ref']}/{SEEN_AUDIT['invocab_both_n']}), {CT} {SEEN_AUDIT['trained_frac_cand']} ({SEEN_AUDIT['trained_invocab_n_cand']}/{SEEN_AUDIT['invocab_both_n']}) ; snn_tokens {SEEN_AUDIT['snn_tokens']} ; patch de contexte max {SEEN_AUDIT['max_ctx_patch_index']} ; fenêtre = train[:200000] {SEEN_AUDIT['window_is_train_prefix_200000']} ; cibles contiguës {SEEN_AUDIT['targets_contiguous_from_patch1']} → seen {'COMPARABLE' if SEEN_OK else 'NON COMPARABLE'}.", "",
+ f"Note : {FRESH_MEAN_NOTE}.", "",
+ f"Écart seen − moyenne fraîche ({', '.join(GAPW)} ; test_v3 non mesuré) : {CT} {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence {CT} − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [blocs 512 o seed 0 : {gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}] [positions seed 25 : {gap['cand_minus_ref']['ci95_boot_positions_seed25'][0]:+.3f} ; {gap['cand_minus_ref']['ci95_boot_positions_seed25'][1]:+.3f}].", "",
+ f"Script sha256 {out['script_sha256']} ; masque sha256 {out['mask_sha256']}.", ""]
+open(f"{OP}/verdict_{CT}.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/lever2_sparse/smoke/v42_identity_0958/vSP_pushed.py b/results/hashing/lever2_sparse/smoke/v42_identity_0958/vSP_pushed.py
new file mode 100644
index 0000000000000000000000000000000000000000..f2bebcbae9db9ceac8f4e25f5f3f9ab47af16943
--- /dev/null
+++ b/results/hashing/lever2_sparse/smoke/v42_identity_0958/vSP_pushed.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict levier 2 SPARSITÉ (SP1/SP2, argument 1) — copie de lever2/verdict_AH1/verdict_AH1.py, SEULS changements :
+bras candidat lu dans lever2_sparse/short_old, sortie dans lever2_sparse/verdict_, libellés. Témoin, masque et protocole identiques.
+(ex-docstring AH1) verdict levier 2 AH1 (eta_ah=1e-3) contre le témoin à budget égal ref (eta_ah=0), méthode banc v4.1
+(copie adaptée de m7_v41/strict/verdict_m7_v41_strict.py ; lecture seule des hits short_old/{ref,AH1}__*.npz, aucun modèle chargé).
+Fenêtres MESURÉES par run_l2.py (4000 positions chacune) : seen (= old_local_v1/train[:200000]), fc2, fresh_en, fresh_fr, test20k
+(= old_local_v1/test.bin, sha ce0526c6…, PAS broad_local_v1/test.bin ; masque strict propre recalculé : verdict_AH1/mask_oldtest_strict.npz,
+union old_local_v1 ∪ broad_local_v1). queries et test_v3 : NON évalués par les bras → absents (non mesurables). neither_code exclu.
+hit = fused_hit & invocab. Appariement par position si tgt_start et tgt_len identiques (vérifié). McNemar exact bilatéral = DÉCISION (p<0,05).
+Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un générateur seed 0, fenêtres dans l'ordre WIN, apparié ; stat = acc invocab.
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k strict ; test_v3 non mesuré). Bootstrap secondaire par positions, seed 25.
+Correctif v4.2 (Hashing 24 oct. ~09 h 39, Toronto ; original = verdict_SP.py.bak_0950) : positions gardées ssi in-vocab dans les DEUX bras (et propres) ;
+McNemar, taux (APPARIÉS, même dénominateur) et bootstrap sur ce seul ensemble. Tokenisation identique exigée (assert) ⇒ unités v4.2 = patches.
+Si invocab est identique entre bras (cas AH1/AH2), résultat identique à v4.1.
+Critère utilisateur : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche ET aucune perte significative sur une fenêtre valide ; sinon REJETÉ."""
+import sys, os, json, math, hashlib, numpy as np
+D = "/workspace/spira_shared/hashing_gen/lever2/short_old"; RT, CT = "ref", sys.argv[1]; assert CT in ("AH1", "AH2")
+DC = "/workspace/spira_shared/hashing_gen/lever2/short_old"; OP = f"/workspace/spira_shared/hashing_gen/lever2_sparse/smoke/v42_identity_0958/pushed/verdict_{CT}"
+MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+DESC = {'AH1': 'AH1 (smoke)', 'AH2': 'AH2 (smoke)', 'SP1': 'SP1 (k-WTA k=51 sur les spikes, N=512, rho=0.1)', 'SP2': 'SP2 (seuil adaptatif theta += 1e-3*(s-0.1), theta0=0, figé en éval)'}[CT]
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k"]; GAPW = FRESH
+NOT_MEASURED = ["queries", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+os.makedirs(OP, exist_ok=True); MS = np.load(MASKP)
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{DC}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_union": int((bo | bb_).sum()),
+ "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ ia1, ib1 = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k; one_side = int((ia1 ^ ib1).sum())
+ k = k & A["invocab"].astype(bool) & B["invocab"].astype(bool) # v4.2 : in-vocab dans les DEUX bras
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); p = binp(b, c)
+ ia, ib = k.copy(), k.copy()
+ acc_a, acc_b = 100 * (ha & k).sum() / ia.sum(), 100 * (hb & k).sum() / ib.sum() # taux APPARIÉS (même dénominateur)
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], k[k], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], k[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, k)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "n_invocab_clean_ref": int(ia.sum()), "n_invocab_clean_cand": int(ib.sum()), "invocab_identical": inv_same, "n_invocab_one_side_only_dropped": one_side, "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)", "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"])}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+R2 = np.random.default_rng(25); BP = {}
+for w in WIN:
+ k, ha_, hb_, iv_ = KEEP[w]; m_ = k & iv_; r_ = ha_[m_].astype(np.float64); c_ = hb_[m_].astype(np.float64); n_ = len(r_); ar = np.empty(NB); ac = np.empty(NB)
+ for t in range(NB):
+ i = R2.integers(0, n_, n_); ar[t] = r_[i].mean(); ac[t] = c_[i].mean()
+ BP[w] = (100 * ar, 100 * ac)
+dgp = (BP["seen"][1] - np.mean([BP[w][1] for w in GAPW], axis=0)) - (BP["seen"][0] - np.mean([BP[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"]["ci95_boot_positions_seed25"] = [float(x) for x in np.percentile(dgp, [2.5, 97.5])]
+gap["windows"] = GAPW; gap["note"] = "test_v3 non mesuré par les bras (absent de la moyenne) ; queries non mesuré ; neither_code exclu"
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+out = {"cand": DESC, "ref": "ref (eta_ah=0, budget égal)", "corpus": "broad/old_local_v1", "snn_tokens": 24000, "epochs": 2, "max_positions": 4000,
+ "windows_measured": WIN, "windows_not_measured": NOT_MEASURED, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap,
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D if a == RT else DC}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN},
+ "mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest(), "mask_path": MASKP}
+json.dump(out, open(f"{OP}/verdict_{CT}.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict levier 2 — {DESC} contre ref (eta_ah = 0, budget égal), old_local_v1 court\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), 4000 positions par fenêtre, appariement par position (tokenisation identique vérifiée).", "",
+ f"| fenêtre | n apparié | {CT} % | réf % | Δ pts | b (réf seule) / c ({CT} seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ nm = "test20k strict (old_local_v1/test.bin, union old ∪ broad)" if w == "test20k" else w
+ md.append(f"| {nm} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "",
+ f"test20k strict : {EX['excluded_union']} positions exclues sur 4000 ({EX['excluded_by_old_local_v1']} par old_local_v1, {EX['excluded_by_broad_local_v1']} par broad_local_v1), octets évalués jusqu'à {EX['max_byte_evaluated']}.", "",
+ f"Écart seen − moyenne fraîche ({', '.join(GAPW)} ; test_v3 non mesuré) : {CT} {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence {CT} − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [blocs 512 o seed 0 : {gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}] [positions seed 25 : {gap['cand_minus_ref']['ci95_boot_positions_seed25'][0]:+.3f} ; {gap['cand_minus_ref']['ci95_boot_positions_seed25'][1]:+.3f}].", "",
+ f"Script sha256 {out['script_sha256']} ; masque sha256 {out['mask_sha256']}.", ""]
+open(f"{OP}/verdict_{CT}.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m7_sem/AMENDMENT_1_M7sem.md b/results/hashing/m7_sem/AMENDMENT_1_M7sem.md
new file mode 100644
index 0000000000000000000000000000000000000000..e957a6552c11e9208d6debc084485bacc7cf3146
--- /dev/null
+++ b/results/hashing/m7_sem/AMENDMENT_1_M7sem.md
@@ -0,0 +1,12 @@
+# Amendement 1 à PREDECL_M7sem (322912a0…) — 2026-10-24 20 h 26 (Toronto) — AVANT toute mesure (s6 jamais lancé sur le corpus complet)
+- Cause : s2_vocab.py s'est arrêté lui-même à 20 h 24 (garde interne, RSS 368 236 kB > 290 Mo) dès la 1re tranche de 4 M patches. Rien d'autre touché.
+- Changement RESSOURCES SEULEMENT : taille de tranche STEP 4 000 000 → 1 000 000 (s2, s3, s5) et 2 000 000 → 1 000 000 (s4). Comptes exacts : résultat
+ indépendant de la tranche. Re-vérifié après changement : t_equiv 3 Mo ALL_EQUAL (proj eef19441…), t_split 6 Mo ALL_EQUAL.
+- Règle, paramètres, s1 et s6 : inchangés. s1 r1 (ids 8a870fe8…) conservé ; chaîne de reprise code/chain_full_v2.sh.
+Nouveaux sha256 :
+2af71400a1e88228dd48750ea9cfedb5aed3a9a385ac1d365f20cfe909aafc0f code/s2_vocab.py
+e0484a4acf6afa1c061e63c6cb36b9db2a71a066c8714f1f47efb59d7f0fdf0c code/s3_cols.py
+727b8c0d90e04da88d72b9b902e7cddda4d9956ad647a1825765d0d653dde632 code/s4_cooc.py
+cd27b0cbddfa181872795dfaec6b469f89f418fc884b9a1f16908c9925c7ef22 code/s5_proj.py
+49aed35b75d51cdd27d804dab824a22201e7bbbe002a5d177fe755b914a2b4d1 code/chain_full_v2.sh
+— SPIRA Hashing
diff --git a/results/hashing/m7_sem/AMENDMENT_2_M7sem.md b/results/hashing/m7_sem/AMENDMENT_2_M7sem.md
new file mode 100644
index 0000000000000000000000000000000000000000..e55e12da49a47826bb5000080f62094db7e4133c
--- /dev/null
+++ b/results/hashing/m7_sem/AMENDMENT_2_M7sem.md
@@ -0,0 +1,9 @@
+# Amendement 2 à PREDECL_M7sem — 2026-10-24 20 h 28 (Toronto) — AVANT toute mesure
+- Cause : s2_vocab.py s'est arrêté lui-même à 20 h 27 (garde, RSS 371 460 kB) au comptage du seau A02 (130 860 440 o = 16,4 M ids : seaux très inégaux,
+ un patch fréquent par seau ; dispersion terminée : T = 157 653 771, nA = 78 969 726, nB = 78 684 045).
+- Changement RESSOURCES SEULEMENT : comptage de chaque seau par sous-tranches de 2 M ids, fusion exacte (unique + bincount), assert somme == taille.
+ Test unitaire (logs/unit_count_file.log) : multi-tranches == np.unique. t6m : vocab_A identique (50d990e7…, déjà prouvé == référence par t_split).
+- Règle, paramètres, s1, s3–s6 inchangés. Nouveaux sha256 :
+4f3113ea27ff0cd51d9fa0f4c899dbcf24518bfa5e8ac0454231e3ca4ba80ffe code/s2_vocab.py
+4f1dbd6824483d2622f324d7adc3b182250293a36a278c3458f8fb934cb6f517 code/chain_full_v2.sh
+— SPIRA Hashing
diff --git a/results/hashing/m7_sem/AMENDMENT_3_M7sem.md b/results/hashing/m7_sem/AMENDMENT_3_M7sem.md
new file mode 100644
index 0000000000000000000000000000000000000000..d99ab99805c4e13edcccbd0238a0f537c9434db2
--- /dev/null
+++ b/results/hashing/m7_sem/AMENDMENT_3_M7sem.md
@@ -0,0 +1,25 @@
+# AMENDEMENT 3 — M7sem (ressources seulement, aucun paramètre ni règle modifié)
+Rédigé 2026-10-24 20 h 39 (heure de Toronto), AVANT toute sortie de mesure sur le corpus complet.
+
+**Cause :** s6_analysis.py (gelé, sha 5d0bf51055b37128ad9e125b90d9e1ce0d31f7fc67ac43b8893b9f0793773a60) s'est arrêté par sa propre garde
+(rss_kb=408688 > 290 Mo) à 20:35:14 Toronto, juste après « eligible E=16331 », pendant le calcul des voisins cosinus
+(blocs de 512 lignes × 16331 colonnes densifiés). Aucune statistique n'avait été calculée ni écrite (pas de fichier de sortie).
+
+**Changement (code/s6_analysis_a3.py, sha 7327bcd741cf0cab7558e52f79c8e8224f8c620dd84e10df95babd712f6bdd18) :**
+1. voisins cosinus : blocs de 64 lignes au lieu de 512 (calcul ligne à ligne indépendant) ; libération de X, XT après usage ;
+2. paires aléatoires : tableaux numpy préalloués au lieu de listes Python (mêmes tirages, même ordre) ; libération de excl ;
+3. overlap : dédoublonnage et comparaison par tranches de 20 000 paires (opération ligne à ligne) ;
+4. boot / perm_p : MÊMES tirages RNG (mêmes formes d'appel), moyennes calculées par sous-blocs de 25 lignes.
+Paramètres, graines, seuils, métrique, témoins et règle OUI/NON/NON MESURABLE : inchangés.
+
+**Contrôles d'équivalence (avant mesure complète) :**
+- ancien vs nouveau s6 sur work/t6m (préfixe test, EXCLU de tout verdict) : JSON identiques hors peak_rss/min_memavail (logs/A3EQ_t6m_*_EXCLU.json) ;
+- test unitaire code/t_a3_unit.py (sha 98b0b772b4bd1ec72d7e7bc613c08bef7f9eb621159a7647defe83605054ba5e) à grande taille (130 001 paires, 3001 ancres) : overlap, boot, perm identiques bit à bit (logs/t_a3_unit.log) ;
+- work/t3m : ancien ET nouveau s6 échouent de la même façon (IndexError percentile sur tableau vide : trop peu de paires sur 3 Mo) — défaut préexistant de cas dégénéré, sans effet sur le corpus complet ; signalé.
+
+## 3b — ajout 2026-10-24 20 h 42 (Toronto), toujours AVANT toute sortie de mesure complète
+Le premier essai de s6_analysis_a3.py sur work/full s'est arrêté par sa garde à 20:39:37 (rss_kb=299508) après « pairs close=57678 random=288390 »,
+avant toute statistique (aucun fichier de sortie ; les seuls nombres vus sont E=16331 et ces deux comptes de paires).
+Changements supplémentaires : tirages bootstrap / signes générés par sous-blocs de 25 lignes (flux RNG identique, vérifié à n=16331, 4001, 57 avec B=N=10 000),
+libération de bctx/bval/zb + malloc_trim après les voisins. Nouveau sha s6_analysis_a3.py : ef3273c8ffc8a42de9ca061d9d6501af68e77e699f9f4ef58129d83d25fd0d52 ;
+t_a3_unit.py : a1351625335d20e9a22878d06d97701683068797ed81a022c79a902870051d97 (logs/t_a3b_unit.log : tout identique) ; work/t6m ancien vs nouveau : JSON identiques (logs/A3bEQ_t6m_new_EXCLU.json).
diff --git a/results/hashing/m7_sem/AUDIT_RESPONSE_v2.md b/results/hashing/m7_sem/AUDIT_RESPONSE_v2.md
new file mode 100644
index 0000000000000000000000000000000000000000..d21217349b618116c12e56fd8e710b1c88911331
--- /dev/null
+++ b/results/hashing/m7_sem/AUDIT_RESPONSE_v2.md
@@ -0,0 +1,30 @@
+# Réponse point par point à l'audit Checker FAIL (AUDIT_M7r_plan.md fe684750…) — SPIRA Hashing, 24 oct. 2026, 21 h 47 (Toronto)
+Plan v2 : spira_m7_retrain_plan_v2.md, sha256 32b2e467f0ae2991ddf9e16ef95f06c99ca83d6a16581acd219515b97558e6e5.
+Le v1 (47c087cc…) est conservé intact. Rien n'est lancé ni gelé, et aucun calcul n'a été fait hors lecture de code.
+
+Statuts :
+- CORRIGÉ : corrigé dans le texte du plan ;
+- EN ATTENTE : proposition écrite, rien de figé avant le oui de Philippe-Antoine ;
+- DÉCISION UTILISATEUR : Hashing ne tranche pas.
+
+| # | demande de l'audit | statut | ce qui est fait (v2) |
+|---|---|---|---|
+| 1 | règle de doublons de input_neurons, la même pour pF et rh | CORRIGÉ | §2.1. Le code mesuré somme les doublons (`W_in[idx].sum`) ; repli -1 → base[0]. Une seule règle pour pF, rh et cm : pas de dédoublonnage, convention cm inchangée, ce qui préserve C2 et l'équivalence bit à bit. P(doublon) rh = 0,0653. Distinct-count journalisé ; garde : même nombre de replis. L'alternative dédoublonnée est décrite (elle demanderait un nouveau cm). |
+| 2 | graine et fonction de hachage de rh, sha des tables S | CORRIGÉ (sha : à figer dans le PREDECL) | §2.2. **Défaut trouvé** : input_neurons(pid, 4096, 24) partage ses sels avec base12, d'où une corrélation (mod 1024). Remplacé par splitmix64 (hashing.py f26903e1…) avec RH_SEED = 0x52485F4D37520001 ; formule figée. Les sha S_pF et S_rh ne sont PAS calculés : il faut les ids des colonnes du modèle, et ce calcul revient au test de couverture (point 10). Méthode de sha déclarée. |
+| 3 | seuil de couverture numérique, recompte Checker | **EN ATTENTE** | §4.1 : 0,50 de coverage_tokens_snn proposé comme nombre ; recompte indépendant par Checker ; seul le seuil conditionne la décision. Lié à D4. |
+| 4 | broad_local_v1/test, neither_code et freshcode m7 jamais évalués, tous dans `excluded` | CORRIGÉ | §3.3 : aucun npz d'éval, ni dans la règle ni en descriptif ; les trois sont nommés dans `excluded` avec leur raison. |
+| 5 | drapeau GO propre à M7r pour test_v3 | CORRIGÉ | §3.3 : lit m7_sem/retrain/GO_CHECKER_PASS seulement ; test unitaire §5.4. |
+| 6 | queries hors règle et hors Holm ; broad_gutenberg_v1 | CORRIGÉ | §3.3 : queries n'entre ni dans les gains, ni dans les pertes, ni dans Holm. broad_gutenberg_v1 n'est pas utilisée ; aucune fenêtre ajoutée après le gel. |
+| 7 | ajouts à la règle B à faire approuver | **DÉCISION UTILISATEUR (D1)** | §3.1 : règle B citée mot pour mot. §3.2 : McNemar exact bilatéral ; b = réf. juste / cand. faux, c = réf. faux / cand. juste. §3.4 : versions B-pure et B+ écrites. Note factuelle : « IC95 > 0 » figure déjà dans le texte de la règle B du 13 h 00. |
+| 8 | bornes de scale en dur, sans surcharge | **DÉCISION UTILISATEUR (D2)** | Philippe-Antoine les a dites provisoires : 3 options présentées, la question n'est pas retirée unilatéralement. Aucune révision après avoir vu les scales. |
+| 9 | plafond RSS de 3,5 Go appliqué | CORRIGÉ | §6.2 : garde sur la RSS de groupe dans le lanceur M7r (SIGTERM à son propre groupe, rc 3). Le pic du smoke doit être ≤ 3,0 Go. |
+| 10 | test léger pendant 925745 | **DÉCISION UTILISATEUR (D3)** | Inchangé : seulement avec un oui écrit, sinon après 925745. |
+| 11 | checkpoints intra-époque | **EN ATTENTE (D5)** | §6.3 : proposé tous les 50 000 ticks, identique pour pF et rh, preuve bit à bit (§5.2). Garde « consciente du ballon » proposée, non adoptée. |
+| 12 | PREDECL gelé avec tous les sha avant tout lourd, puis audit | CORRIGÉ (engagement) | §7 : liste complète des sha ; gel avant les tests 5.2 et 5.3 ; audit Checker, puis drapeau. |
+| 13 | exclusions explicites | CORRIGÉ | §4.3 : pas de variante de décodage ; SP1, SP2, AH1 et AH2 non réutilisés ; le masque AH1 sert seulement de masque de propreté. |
+| 14 | sha de config, countmin.py et eval_ref_v3.py pour C2 | CORRIGÉ | §3.6 : sha actuels == PREDECL M8 v1b == journal pF/rh ; champs de config comparés. Risque résiduel déclaré : results.jsonl ne journalise pas les sha de code. |
+| 15 | recompte de fuite en 32 o (descriptif) | CORRIGÉ (non lancé, D7) | §4.2 : optionnel, après 925745, n'a aucun effet sur la règle. |
+| — | McNemar exact bilatéral et définition de b et c | CORRIGÉ | §3.2. |
+
+Questions pour le ré-audit : plan v2 §12.
+— SPIRA Hashing
diff --git a/results/hashing/m7_sem/AUDIT_RESPONSE_v2.md.sha256 b/results/hashing/m7_sem/AUDIT_RESPONSE_v2.md.sha256
new file mode 100644
index 0000000000000000000000000000000000000000..b8a5018be6fb99a7961918391a4bdc27b52da115
--- /dev/null
+++ b/results/hashing/m7_sem/AUDIT_RESPONSE_v2.md.sha256
@@ -0,0 +1 @@
+ba0e781e76e2098dc30982a51bcb89caea697a1ae3ff8ffe282e637ff4fec949 AUDIT_RESPONSE_v2.md
diff --git a/results/hashing/m7_sem/PREDECL_M7sem.md b/results/hashing/m7_sem/PREDECL_M7sem.md
new file mode 100644
index 0000000000000000000000000000000000000000..79ce134ae752179c5ad6e766426b1add161262b6
--- /dev/null
+++ b/results/hashing/m7_sem/PREDECL_M7sem.md
@@ -0,0 +1,63 @@
+# PREDECL M7sem — les patches sémantiquement proches partagent-ils des neurones d'entrée Count-Min ? — SPIRA Hashing — 2026-10-24 20 h 20 (Toronto)
+
+Gelé AVANT toute mesure sur le corpus complet. Scripts gelés : voir SHA256SUMS_predecl (même horodatage). Toute modification après gel = nouvelle pré-déclaration.
+
+## 0. Hypothèse de base (mandat 7)
+La projection Count-Min figée (co-occurrences ±2 → top-16 PPMI → 24 MinHash sur un bloc de 4096 neurones) fait partager des neurones d'entrée
+aux patches sémantiquement proches, nettement plus que le hasard et qu'un hachage aléatoire de mêmes d_in/k_in.
+
+## 1. Corpus élargi : corpus_diverse_v1b
+- hashing_gen/corpus_v1b/train.bin, 520 785 883 o, sha256 ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3 (manifest cb6398ca…, STATUS DONE).
+- Raison : c'est le corpus que la chaîne M8-cm en cours (m8_v1b, bras cm PID 666012, PREDECL M8 v1b « M8 sur corpus_diverse_v1b ») définit
+ comme corpus élargi ; diversifié (broad_local_v1 + Gutenberg v2 + multi_lang_v1) ; recompte 64 o du manifest : 0 position sur les fenêtres nommées
+ (fc2, fresh_en, fresh_fr, test20k, test_v3). code_scale_v1 (527,7 Mo) est presque uniquement du code (moins « diverse ») ; corpus_v3 (93 Mo)
+ et code_prose_v1 (361 Mo) sont plus petits. Le bras cm M8 v1b utilise un ÉCHANTILLON de 35 Mo (v1b_sample.bin) ; ici on compte le corpus ENTIER.
+- Réserve : le recompte Checker indépendant de v1b était « EN ATTENTE » dans le plan M8 v1b ; ici aucune fenêtre d'éval n'est utilisée.
+
+## 2. Projection (aucune variante nouvelle) — config du bras cm M8 v1b (countmin.py caab5040…, identique semhash/ et m8_v1b/code/)
+- EPT du repo (6923c519, lecture seule) : fit data[:2 000 000], calibrate data[2 000 000:2 400 000] cible 4,5 ; segmentation du flux entier ; id = FNV-1a 64.
+- Vocabulaire top-V=16 384 (lexsort((uniq,-cnt)), comme SPIRA.build) ; co-occurrences ±2, PPMI float64, top-16 ; 24 MinHash (minhash_rows, salt 0xC0FFEE)
+ sur [1024, 5120) ; 12 neurones v3 sur [0,1024) (6 hash entier + 6 trigrammes, k_tri=6) ; d_in = 5120, k_in = 36 ; sans contexte → repli base[0].
+- Zéro backprop. Seul aléa : aucun (hash fixes). Implémentation bas-mémoire (code/s1..s5) prouvée bit-identique au code de référence appelé tel quel
+ (EPT.segment, fnv1a64, countmin.cooc_ppmi_topk, minhash_rows, SPIRA._structured_row) sur un préfixe de 3 Mo (t_equiv : ALL_EQUAL) et, pour le découpage A/B,
+ sur un préfixe de 6 Mo avec blocs de 2 Mio (t_split : ALL_EQUAL) ; invariance à la taille de tranche de segmentation vérifiée (256 Kio vs 2 Mio).
+- Comptes EXACTS (pas d'approximation Count-Min sketch des comptes) : seaux de hachage sur disque + tableaux denses uint32 par partition de mots.
+
+## 3. Découpage held-out (non-circularité)
+- Partie A = patches dont l'octet de début est dans un bloc de 8 Mio d'indice pair ; B = impair. Une paire de co-occurrence n'est comptée dans A (resp. B)
+ que si ses deux positions sont dans A (resp. B). B est disjoint de A en octets.
+- **Projection testée = proj_A** : vocabulaire, co-occurrences et MinHash calculés sur A SEUL. B ne sert qu'à définir la proximité.
+- proj_F (corpus entier A∪B) = la projection figée livrée pour le réentraînement ; sur les paires de test elle est CIRCULAIRE → descriptif seulement.
+
+## 4. « Sémantiquement proche » (défini sur B, jamais sur les comptes de proj_A)
+- Éligibles E : colonnes de vocab_A avec contexte dans A (has_ctx), ≥ 50 occurrences dans B, ≥ 5 contextes PPMI>0 dans B.
+- Vecteur de B = top-256 contextes PPMI>0 (±2, comptés sur B uniquement), normé L2. Proximité = cosinus.
+- Paires proches C : pour chaque ancre i ∈ E, ses 5 plus proches voisins dans E (cosinus décroissant, départage par indice), gardés si cosinus ≥ 0,20.
+- Paires aléatoires appariées : pour chaque paire proche (i, j), 5 j' tirés dans E dans le même bin de fréquence que j (20 bins de quantiles de log
+ compte dans A), j' ∉ {i} ∪ 50 plus proches voisins de i. RNG numpy default_rng(20261024).
+- Témoin nul (hash aléatoire, mêmes d/k) : bloc CM remplacé par 1024 + input_neurons(id, 4096, 24) (hash pur du repo), mêmes paires proches.
+
+## 5. Métrique et tests
+- Chevauchement ov(i,j) = |S_i ∩ S_j| / k (ensembles, doublons retirés), **primaire sur le bloc CM (k = 24)** ; secondaire sur la ligne complète (k = 36 / 5120,
+ témoin input_neurons(id, 5120, 36)) — la ligne complète inclut les trigrammes v3 (partage lexical), d'où le choix du bloc CM comme primaire.
+- Δ_rand = moyenne sur ancres de [moy. ov(paires proches de i) − moy. ov(paires aléatoires appariées de i)] ;
+ Δ_hash = moyenne sur ancres de [moy. ov_projA(proches) − moy. ov_hash(proches)].
+- IC95 : bootstrap percentile par ancre (grappes), B = 10 000, seed 0. p : permutation par inversion de signe sur les différences par ancre, 10 000, seed 1.
+- δ (effet minimal) = 1/24 = 0,04167 : en moyenne au moins UN neurone CM partagé de plus par paire proche (sur 24). Sous ce seuil la plupart des paires
+ proches ne partagent aucun neurone supplémentaire, ce qui n'aide pas le cortex (hasard : 24²/4096 ≈ 0,14 neurone, soit 0,006).
+
+## 6. Règle de décision (figée)
+- **OUI** ssi (IC95 bas de Δ_rand > 0 ET Δ_rand ≥ δ) ET (IC95 bas de Δ_hash > 0 ET Δ_hash ≥ δ), sur le bloc CM24 de proj_A.
+- **NON** sinon.
+- **NON MESURABLE** si |E| < 1000, ancres < 1000 ou paires proches < 2000 ; OU si le test de déterminisme (2 constructions complètes indépendantes,
+ sha256 de proj_A et proj_F) échoue ; OU si un des tests d'équivalence échoue.
+- Secondaire (non décisionnel) : ligne complète 36 ; AUC proches vs aléatoires (+IC bootstrap) — comparable à l'ancien M7 (AUC held-out 0,619, chiffre
+ non revérifiable, fichiers perdus) ; dose-réponse par bins de cosinus ; proxys objectifs sans comptes : variantes de casse (" they"/" They") et
+ d'espace initial ("bag"/" bag") dans vocab_A, vs aléatoire apparié en fréquence (A) et vs hash ; descriptif circulaire proj_F.
+
+## 7. Ressources et transparence
+- 1 processus léger à la fois, nice 10, OMP_NUM_THREADS=1, PYTHONHASHSEED=0, garde interne : arrêt de SOI-MÊME si RSS > 290 Mo ou MemAvailable < 4 Go.
+- Fumée faite AVANT ce gel, pour déboguer le code seulement : s6 sur un préfixe de 6 Mo (blocs de 2 Mio) → NON MESURABLE (E = 1835, 758 paires) ;
+ sortie dans logs/SMOKE_t6m_analysis_EXCLU.json, exclue de tout verdict. Paramètres non modifiés après la fumée (seul correctif : tirage aléatoire des
+ proxys excluant les 2 membres de la paire).
+— SPIRA Hashing
diff --git a/results/hashing/m7_sem/SHA256SUMS_predecl b/results/hashing/m7_sem/SHA256SUMS_predecl
new file mode 100644
index 0000000000000000000000000000000000000000..42e026a1f95158fdc7f15aef218d56c0ec696ac7
--- /dev/null
+++ b/results/hashing/m7_sem/SHA256SUMS_predecl
@@ -0,0 +1,21 @@
+322912a0508ca3eb13929b6a6f3a671be5bdface2d997bd00613f5a8fd284a10 PREDECL_M7sem.md
+ee0673148572f8acc863685fafc6df0410093dcb97ea576fb87f589ce58c63b4 code/common.py
+4a44de5996245b693d61dab1c32150f8818bd6c1b7e510f68fa026a510adcff7 code/s1_segment.py
+c37a9263041d665e7cc81a9f91d46d7c570b8fef8c9bc1c2c8381f79d3609e4b code/s2_vocab.py
+247bc251abcd118016d14f2c8b0969095e18c1ac597e055d4f886a79ab8507c2 code/s3_cols.py
+9c7a223f2471eae607d7f72c96a67a6024ae4b788e6a52126fa930ae17f332f5 code/s4_cooc.py
+720f8821a9a785b4f48a702cf256d2ca9c1aadc153532dd0f98e91e61598e2ae code/s5_proj.py
+5d0bf51055b37128ad9e125b90d9e1ce0d31f7fc67ac43b8893b9f0793773a60 code/s6_analysis.py
+075eb1435c087c82612d1e58eca03dae8665bb275eaa43a2b2aa053578dcb738 code/t_equiv.py
+7b2c33c394c2e44f75050037ef9c5b52e4c2a13a42ac2523bcf61c0f39016f3b code/t_split.py
+4bc12ca27fb51df292bba74ad11c255eb82f580971a96e624d733af43a7dc55b code/run.sh
+c869d1a0c2d1933895590f07bb15c676c029f4c4b27e256cad91ed94cd1b0971 code/chain_full.sh
+cd12e8727a3f5c79547625d759ca4389533081e274f0c9e5adf040c3d4a0b01e AMENDMENT_1_M7sem.md
+7dc7e28a12e26d91c812a7b711d1085902bd8fac3b58fa7736d645e2f8e5e9f5 AMENDMENT_2_M7sem.md
+ce58ebd6ee33e4e16b997017c4d474fb095aedf070900219819403bc9b7fba1d AMENDMENT_3_M7sem.md
+7327bcd741cf0cab7558e52f79c8e8224f8c620dd84e10df95babd712f6bdd18 code/s6_analysis_a3.py
+98b0b772b4bd1ec72d7e7bc613c08bef7f9eb621159a7647defe83605054ba5e code/t_a3_unit.py
+24897e841509620ad80e48b71d7783a2be76f8ff09c52e690ce41a0f967ecb4f code/chain_full_v3.sh
+139992e02ee35d0f6ac0be9239139efe15ddb234a6229c1ed39af9cfd87904f9 AMENDMENT_3_M7sem.md
+ef3273c8ffc8a42de9ca061d9d6501af68e77e699f9f4ef58129d83d25fd0d52 code/s6_analysis_a3.py
+a1351625335d20e9a22878d06d97701683068797ed81a022c79a902870051d97 code/t_a3_unit.py
diff --git a/results/hashing/m7_sem/SHA256SUMS_verdict b/results/hashing/m7_sem/SHA256SUMS_verdict
new file mode 100644
index 0000000000000000000000000000000000000000..b29ec8f0e068908cc74d0645d9669225fef27f5a
--- /dev/null
+++ b/results/hashing/m7_sem/SHA256SUMS_verdict
@@ -0,0 +1,4 @@
+e99416cfbc6681a1b86c2fb6f0d0187e203652b02e1c3ea08e439abeb6d702dc verdict_M7sem.md
+85da7cc7466e0e18df7414a7a108144923895a0a8ce8a9128441423a234f3e10 verdict_M7sem.json
+0c2c6b563bb6a60f3821528b42c9b5fbeeca26246579c89b83ba3249341a1ca5 out/analysis_M7sem.json
+65580aaf66b0cb57b5d443586a3a4e878ac53a5e04c1886cccd70cacc465d3c4 code/make_verdict.py
diff --git a/results/hashing/m7_sem/code/chain_full.sh b/results/hashing/m7_sem/code/chain_full.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ea3b0b7e0cb68abeddca346ea32b0a6a7b111c07
--- /dev/null
+++ b/results/hashing/m7_sem/code/chain_full.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# M7sem — chaîne séquentielle (1 processus léger à la fois) : sha corpus, construction r1, analyse, construction r2 (déterminisme), comparaison.
+cd /workspace/spira_shared/hashing_gen/m7_sem; L=logs/chain_full.log
+step(){ echo "$(TZ=America/Toronto date '+%F %T') START $*" >> $L; code/run.sh "$@" > logs/$(echo "$*" | tr ' /' '__').log 2>&1; rc=$?; echo "$(TZ=America/Toronto date '+%F %T') EXIT $rc $*" >> $L; [ $rc -eq 0 ] || { echo FAILED >> $L; exit $rc; }; }
+echo "$(TZ=America/Toronto date '+%F %T') corpus $(nice -n 10 sha256sum /workspace/spira_shared/hashing_gen/corpus_v1b/train.bin)" >> $L
+for R in full full_r2; do
+ P=work/$R
+ step s1_segment.py $P; step s2_vocab.py $P; step s3_cols.py $P; step s4_cooc.py $P; step s5_proj.py $P
+ [ $R = full ] && step s6_analysis.py $P out/analysis_M7sem.json
+done
+echo "$(TZ=America/Toronto date '+%F %T') ALL_DONE" >> $L
diff --git a/results/hashing/m7_sem/code/chain_full_v2.sh b/results/hashing/m7_sem/code/chain_full_v2.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ab3e2b63002077331d34a03265eb17704875beb2
--- /dev/null
+++ b/results/hashing/m7_sem/code/chain_full_v2.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# M7sem — reprise après arrêt-garde de s2 (20 h 24, RSS 368 Mo > 290, tranches 4 M) : s1 r1 déjà fait (ids 8a870fe8…). Séquentiel.
+cd /workspace/spira_shared/hashing_gen/m7_sem; L=logs/chain_full.log
+step(){ echo "$(TZ=America/Toronto date '+%F %T') START $*" >> $L; code/run.sh "$@" > logs/$(echo "$*" | tr ' /' '__').log 2>&1; rc=$?; echo "$(TZ=America/Toronto date '+%F %T') EXIT $rc $*" >> $L; [ $rc -eq 0 ] || { echo FAILED >> $L; exit $rc; }; }
+echo "$(TZ=America/Toronto date '+%F %T') RESUME v3 (STEP 1M + count_file par sous-tranches)" >> $L
+P=work/full; step s2_vocab.py $P; step s3_cols.py $P; step s4_cooc.py $P; step s5_proj.py $P; step s6_analysis.py $P out/analysis_M7sem.json
+P=work/full_r2; step s1_segment.py $P; step s2_vocab.py $P; step s3_cols.py $P; step s4_cooc.py $P; step s5_proj.py $P
+echo "$(TZ=America/Toronto date '+%F %T') ALL_DONE" >> $L
diff --git a/results/hashing/m7_sem/code/chain_full_v3.sh b/results/hashing/m7_sem/code/chain_full_v3.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ac1873dc015765285cffb5865c5049b1e6be2937
--- /dev/null
+++ b/results/hashing/m7_sem/code/chain_full_v3.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# M7sem — reprise après arrêt-garde de s6 (20:35:14, RSS 409 Mo) : s1–s5 r1 faits. Amendement 3 : s6_analysis_a3.py. Séquentiel.
+cd /workspace/spira_shared/hashing_gen/m7_sem; L=logs/chain_full.log
+step(){ echo "$(TZ=America/Toronto date '+%F %T') START $*" >> $L; code/run.sh "$@" > logs/$(echo "$*" | tr ' /' '__').log 2>&1; rc=$?; echo "$(TZ=America/Toronto date '+%F %T') EXIT $rc $*" >> $L; [ $rc -eq 0 ] || { echo FAILED >> $L; exit $rc; }; }
+echo "$(TZ=America/Toronto date '+%F %T') RESUME v4 (amendement 3, s6_analysis_a3)" >> $L
+P=work/full; step s6_analysis_a3.py $P out/analysis_M7sem.json
+P=work/full_r2; step s1_segment.py $P; step s2_vocab.py $P; step s3_cols.py $P; step s4_cooc.py $P; step s5_proj.py $P
+echo "$(TZ=America/Toronto date '+%F %T') ALL_DONE" >> $L
diff --git a/results/hashing/m7_sem/code/common.py b/results/hashing/m7_sem/code/common.py
new file mode 100644
index 0000000000000000000000000000000000000000..b1d0ec022853bb7b3e847933660a3dd049da8aca
--- /dev/null
+++ b/results/hashing/m7_sem/code/common.py
@@ -0,0 +1,45 @@
+"""M7sem — utilitaires communs (SPIRA Hashing, 2026-10-24). Lecture seule sur /workspace/SPIRA et semhash/."""
+import os, sys, time, json, hashlib, threading, resource
+import numpy as np
+sys.path.insert(0, "/workspace/SPIRA/python")
+ROOT = "/workspace/spira_shared/hashing_gen/m7_sem"
+WORK = f"{ROOT}/work"; OUT = f"{ROOT}/out"; LOGS = f"{ROOT}/logs"
+CORPUS = "/workspace/spira_shared/hashing_gen/corpus_v1b/train.bin"
+CORPUS_SHA = "ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3"
+V = 16384 # vocab (config M8 v1b / repo)
+WINDOW, TOPK = 2, 16 # countmin : ±2, top-16 PPMI
+CM_D, CM_W, BASE_D, BASE_K = 24, 4096, 1024, 12 # d_in total 5120, k_in total 36
+SPLIT_BLOCK = int(os.environ.get("M7_SPLIT_BLOCK_TEST", 8 << 20)) # 8 Mio : bloc pair -> A, impair -> B (par octet de début de patch) ; surcharge env pour tests seulement
+RSS_CAP_KB = 290 * 1024; MEMAVAIL_MIN_KB = 4 * 1024 * 1024
+T0 = time.perf_counter()
+def log(s):
+ print(f"{time.strftime('%H:%M:%S')} [{time.perf_counter()-T0:7.0f}s] rss={rss_kb()//1024}M {s}", flush=True)
+def rss_kb():
+ for l in open("/proc/self/status"):
+ if l.startswith("VmRSS"): return int(l.split()[1])
+def memavail_kb():
+ for l in open("/proc/meminfo"):
+ if l.startswith("MemAvailable"): return int(l.split()[1])
+PEAK = {"rss_kb": 0, "min_memavail_kb": 1 << 62}
+def _guard():
+ while True:
+ r = rss_kb(); m = memavail_kb()
+ PEAK["rss_kb"] = max(PEAK["rss_kb"], r); PEAK["min_memavail_kb"] = min(PEAK["min_memavail_kb"], m)
+ if r > RSS_CAP_KB or m < MEMAVAIL_MIN_KB:
+ print(f"GUARD ABORT self: rss_kb={r} memavail_kb={m}", flush=True); os._exit(97)
+ time.sleep(0.5)
+def start_guard():
+ assert os.environ.get("OMP_NUM_THREADS") == "1" and os.environ.get("PYTHONHASHSEED") == "0", "env OMP/PYTHONHASHSEED"
+ threading.Thread(target=_guard, daemon=True).start()
+def peak_mb():
+ return round(max(PEAK["rss_kb"], resource.getrusage(resource.RUSAGE_SELF).ru_maxrss) / 1024, 1)
+def sha_file(p, bs=8 << 20):
+ h = hashlib.sha256()
+ with open(p, "rb") as f:
+ while True:
+ b = f.read(bs)
+ if not b: break
+ h.update(b)
+ return h.hexdigest()
+def sha_arr(a):
+ return hashlib.sha256(np.ascontiguousarray(a).tobytes()).hexdigest()
diff --git a/results/hashing/m7_sem/code/make_verdict.py b/results/hashing/m7_sem/code/make_verdict.py
new file mode 100644
index 0000000000000000000000000000000000000000..fcbccf214f576f736836d4f1ca0fcc315e23c5de
--- /dev/null
+++ b/results/hashing/m7_sem/code/make_verdict.py
@@ -0,0 +1,39 @@
+"""M7sem — assemble verdict_M7sem.json (aucun calcul nouveau : lit out/analysis_M7sem.json, logs, sha)."""
+import json, hashlib, glob, os, re
+R = "/workspace/spira_shared/hashing_gen/m7_sem"; os.chdir(R)
+def sha(p):
+ h = hashlib.sha256()
+ with open(p, "rb") as f:
+ for b in iter(lambda: f.read(1 << 20), b""): h.update(b)
+ return h.hexdigest()
+a = json.load(open("out/analysis_M7sem.json")); seg = json.load(open("work/full.seg.json")); voc = json.load(open("work/full.vocab.json"))
+cols = json.load(open("work/full.cols.json")); co = json.load(open("work/full.cooc.json")); pj = json.load(open("work/full.proj.json"))
+det = [l.split() for l in open("logs/determinism_r1_r2.txt")]
+peaks = {}
+for f in sorted(glob.glob("logs/*work_full*.log")):
+ m = re.findall(r'"peak_rss_mb": ([0-9.]+)', open(f).read())
+ if m: peaks[os.path.basename(f)] = float(m[-1])
+peaks["s6_analysis_a3 (out json)"] = a["peak_rss_mb"]
+v = {"mandat": "M7sem — SPIRA Hashing", "verdict": a["verdict_rule_output"]["verdict"], "verdict_why": a["verdict_rule_output"]["why"],
+ "rule": {"PREDECL_M7sem.md": sha("PREDECL_M7sem.md"), "amendments": {f: sha(f) for f in sorted(glob.glob("AMENDMENT_*_M7sem.md"))},
+ "amendments_nature": "ressources seulement (tailles de tranches / libération mémoire) ; paramètres, graines, règle inchangés ; équivalence vérifiée"},
+ "corpus": {"path": "hashing_gen/corpus_v1b/train.bin", "sha256": "ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3",
+ "bytes_counted": seg["bytes"], "fraction_counted": 1.0, "n_patches": seg["n_patches"], "avg_patch_len": seg["avg_len"],
+ "budget_bits": seg["budget_bits"], "nA_patches": voc["nA"], "nB_patches": voc["nB"]},
+ "projection": {"frozen_deliverable_proj_F_npz_sha256": [d[2] for d in det if d[0] == "proj_F.npz"][0], "proj_F_rows_sha256": pj["F"]["proj_sha256"],
+ "tested_proj_A_npz_sha256": [d[2] for d in det if d[0] == "proj_A.npz"][0], "proj_A_rows_sha256": pj["A"]["proj_sha256"],
+ "meta": pj, "d_in": 5120, "k_in": 36, "cm_block": [1024, 5120], "cm_k": 24},
+ "determinism_two_full_builds": {"all_equal": all(d[1] == "EQ" for d in det), "files": {d[0]: {"eq": d[1] == "EQ", "sha256": d[2]} for d in det}},
+ "equivalence_tests_final_code": {f: re.findall(r'"ALL_EQUAL": (true|false)', open(f).read())[-1:] for f in ("logs/final_t3m_t_equiv.log", "logs/final_t6m_t_split.log")},
+ "unit_tests": {"logs/unit_count_file.log": open("logs/unit_count_file.log").read().strip(), "logs/t_a3b_unit.log": json.loads(open("logs/t_a3b_unit.log").read())},
+ "coverage": {"vocab_A_token_coverage_on_A": cols["coverage_A_on_A"], "vocab_A_token_coverage_on_B": cols["coverage_A_on_B"], "vocab_F_coverage": cols["coverage_F"],
+ **a["coverage"]},
+ "cooc": {"tot": co["tot"], "distinct_pairs_nnz": co["distinct_pairs_nnz"]},
+ "analysis": a, "peak_rss_mb_per_step": peaks, "peak_rss_mb_max_completed": max(peaks.values()),
+ "guard_self_aborts": ["s2 20:24 RSS 368 Mo (amend. 1)", "s2 20:27 RSS 371 Mo (amend. 2)", "s6 20:35:14 RSS 409 Mo (amend. 3)", "s6_a3 20:39:37 RSS 299,5 Mo (amend. 3b)"],
+ "inputs_sha256": {"/workspace/SPIRA/python/spira/ept.py": sha("/workspace/SPIRA/python/spira/ept.py"), "/workspace/SPIRA/python/spira/hashing.py": sha("/workspace/SPIRA/python/spira/hashing.py"),
+ "/workspace/SPIRA/python/spira/model.py": sha("/workspace/SPIRA/python/spira/model.py"), "/workspace/spira_shared/semhash/countmin.py": sha("/workspace/spira_shared/semhash/countmin.py"),
+ "repo_HEAD": "6923c5191049ee488d9418c7002f108abd9e8ea1"},
+ "scripts_sha256": {f: sha(f) for f in sorted(f for f in glob.glob("code/*") if os.path.isfile(f))},
+ "outputs_sha256": {f: sha(f) for f in ["out/analysis_M7sem.json"] + sorted(glob.glob("work/full.*.json")) + sorted(glob.glob("work/full.*.np*"))}}
+json.dump(v, open("verdict_M7sem.json", "w"), indent=1, ensure_ascii=False); print(v["verdict"], v["peak_rss_mb_max_completed"], v["determinism_two_full_builds"]["all_equal"], v["equivalence_tests_final_code"])
diff --git a/results/hashing/m7_sem/code/run.sh b/results/hashing/m7_sem/code/run.sh
new file mode 100644
index 0000000000000000000000000000000000000000..219892c015cc772b0b1c19dfcdc5e11167c71ba7
--- /dev/null
+++ b/results/hashing/m7_sem/code/run.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# usage: run.sh script.py args... (nice 10, 1 thread, PYTHONHASHSEED=0 ; garde RSS 290 Mo / MemAvailable 4 Go dans common.py)
+cd /workspace/spira_shared/hashing_gen/m7_sem
+export OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0 TZ=America/Toronto
+s=$1; shift
+exec nice -n 10 /usr/bin/python3 -u code/$s "$@"
diff --git a/results/hashing/m7_sem/code/s1_segment.py b/results/hashing/m7_sem/code/s1_segment.py
new file mode 100644
index 0000000000000000000000000000000000000000..1dbe8b56c2b7bcf28676ed697818cdf02f93c55b
--- /dev/null
+++ b/results/hashing/m7_sem/code/s1_segment.py
@@ -0,0 +1,69 @@
+"""M7sem étape 1 — segmentation EPT en flux (== SPIRA.build : EPT.fit(data[:2M]), calibrate(data[2M:2.4M], 4.5), segment(data)),
+bas-mémoire : tranches d'octets CH, même arithmétique que spira/ept.py (float32 -log2p, cumul float64 séquentiel repris à cum[start],
+recherche gloutonne identique) — dérivé de checker/scale/lowmem_bg1c.py (boundaries_chunked, fnv_ids ; lecture seule), mais les bornes
+sont écrites sur disque par tranche (pas de tableau plein en mémoire). Sorties : PREFIX.ids.u64 (FNV-1a 64 par patch), PREFIX.lens.u8.
+usage : s1_segment.py PREFIX [--limit NBYTES] [--ch BYTES]"""
+import sys, json, argparse, time
+import numpy as np
+from common import *
+from spira.ept import EPT
+ap = argparse.ArgumentParser(); ap.add_argument("prefix"); ap.add_argument("--limit", type=int, default=0); ap.add_argument("--ch", type=int, default=2 << 20)
+a = ap.parse_args(); start_guard()
+import os
+F = open(CORPUS, "rb"); n = os.path.getsize(CORPUS)
+if a.limit: n = min(n, a.limit)
+assert n < 2**32 - 64
+def rd(lo, hi): # lecture par tranche (pas de mmap : le RSS reste borné)
+ F.seek(lo); return np.frombuffer(F.read(hi - lo), dtype=np.uint8)
+class _U8:
+ def __getitem__(self, sl): return rd(sl.start or 0, sl.stop)
+u8 = _U8()
+ept = EPT(budget_bits=16.0, min_len=2, max_len=32, alpha=0.5) # SPIRA.__init__ (cfg défaut)
+ept.fit(bytes(u8[:2_000_000]))
+calib = bytes(u8[2_000_000:2_400_000])
+if calib: ept.calibrate(calib, target_len=4.5)
+log(f"EPT budget_bits={ept.budget_bits!r} n={n}")
+FNV_OFF, FNV_PRIME = np.uint64(0xCBF29CE484222325), np.uint64(0x100000001B3)
+def fnv(st, ln):
+ lo = int(st[0]); buf = rd(lo, int(st[-1] + ln[-1])); st = st - lo
+ h = np.full(len(st), FNV_OFF, dtype=np.uint64)
+ for j in range(int(ln.max()) if len(ln) else 0):
+ mk = ln > j
+ h[mk] = (h[mk] ^ buf[st[mk] + j].astype(np.uint64)) * FNV_PRIME
+ return h
+lp = ept.log2p.ravel(); min_len, max_len, budget = ept.min_len, ept.max_len, ept.budget_bits
+fi = open(a.prefix + ".ids.u64", "wb"); fl = open(a.prefix + ".lens.u8", "wb")
+start, cstart, npat, t1 = 0, 0.0, 0, time.perf_counter()
+searchsorted = np.searchsorted
+while start < n:
+ base = start; hi = min(n, base + a.ch + max_len + 1)
+ if base == 0:
+ bb = rd(0, hi); s = np.empty(hi, dtype=np.float32); s[0] = 8.0
+ if hi > 1: s[1:] = -lp[bb[0:hi - 1].astype(np.int32) * 256 + bb[1:hi]]
+ else:
+ bb = rd(base - 1, hi); s = -lp[bb[:-1].astype(np.int32) * 256 + bb[1:]]
+ del bb
+ cum = np.empty(hi - base + 1, dtype=np.float64); cum[0] = cstart; cum[1:] = s; del s
+ np.cumsum(cum, out=cum)
+ cl = cum.tolist() # floats Python == float64 exacts ; accès rapide
+ lim = n if hi == n else hi - max_len - 1
+ ends = []; app = ends.append; st0 = start
+ while start < n and start <= lim:
+ target = cl[start - base] + budget
+ b = int(searchsorted(cum, target, side="left")) + base
+ if b < start + min_len: b = start + min_len
+ elif b > start + max_len: b = start + max_len
+ if b > n: b = n
+ app(b); start = b
+ cstart = cl[start - base] if start < n else 0.0
+ del cum, cl
+ e = np.asarray(ends, dtype=np.int64); stt = np.concatenate([[st0], e[:-1]]); ln = e - stt
+ assert ln.min() >= 1 and ln.max() <= max_len
+ fnv(stt, ln).tofile(fi); ln.astype(np.uint8).tofile(fl); npat += len(e)
+ if (start // a.ch) % 16 == 0:
+ log(f"seg {start}/{n} ({100*start/n:.1f}%) patches={npat} {start/1e6/(time.perf_counter()-t1):.2f} MB/s")
+fi.close(); fl.close()
+meta = {"corpus": CORPUS, "limit": a.limit, "bytes": n, "n_patches": npat, "avg_len": n / npat, "budget_bits": ept.budget_bits,
+ "log2p_sha256": sha_arr(ept.log2p), "ch": a.ch, "ids_sha256": sha_file(a.prefix + ".ids.u64"), "lens_sha256": sha_file(a.prefix + ".lens.u8"),
+ "seg_s": round(time.perf_counter() - t1, 1), "peak_rss_mb": peak_mb(), "min_memavail_kb": PEAK["min_memavail_kb"]}
+json.dump(meta, open(a.prefix + ".seg.json", "w"), indent=1); log("DONE " + json.dumps(meta))
diff --git a/results/hashing/m7_sem/code/s2_vocab.py b/results/hashing/m7_sem/code/s2_vocab.py
new file mode 100644
index 0000000000000000000000000000000000000000..488c00c10d6e12ce207644f697320fbb70c747a4
--- /dev/null
+++ b/results/hashing/m7_sem/code/s2_vocab.py
@@ -0,0 +1,63 @@
+"""M7sem étape 2 — comptes EXACTS des patches par partie (A = blocs de 8 Mio pairs, B = impairs, par octet de début de patch),
+par seaux de hachage sur disque (64 seaux selon les 6 bits hauts de l'id), puis vocabulaire top-V (== SPIRA.build :
+order = np.lexsort((uniq, -cnt))[:V] ; vocab = sort(uniq[order])) pour A seul (projection de test) et pour A∪B (projection figée).
+usage : s2_vocab.py PREFIX"""
+import sys, os, json
+import numpy as np
+from common import *
+P = sys.argv[1]; start_guard(); NB = 64; STEP = 1_000_000
+ids_f = np.memmap(P + ".ids.u64", dtype=np.uint64, mode="r"); T = len(ids_f); del ids_f
+def chunks():
+ fi = open(P + ".ids.u64", "rb"); fl = open(P + ".lens.u8", "rb"); off = 0
+ while True:
+ ids = np.frombuffer(fi.read(8 * STEP), dtype=np.uint64)
+ if len(ids) == 0: break
+ ln = np.frombuffer(fl.read(len(ids)), dtype=np.uint8).astype(np.int64)
+ st = off + np.concatenate([[0], np.cumsum(ln)[:-1]]); off += int(ln.sum())
+ yield ids, (st // SPLIT_BLOCK) & 1
+bdir = P + ".buckets"; os.makedirs(bdir, exist_ok=True)
+fh = {(p, b): open(f"{bdir}/{p}{b:02d}.u64", "wb") for p in "AB" for b in range(NB)}
+nA = nB = 0
+for ids, part in chunks():
+ bk = (ids >> np.uint64(58)).astype(np.int64)
+ for pi, pn in ((0, "A"), (1, "B")):
+ sel = part == pi; x = ids[sel]; xb = bk[sel]
+ if pi == 0: nA += len(x)
+ else: nB += len(x)
+ o = np.argsort(xb, kind="stable"); x = x[o]; xb = xb[o]
+ cuts = np.searchsorted(xb, np.arange(NB + 1))
+ for b in range(NB):
+ x[cuts[b]:cuts[b + 1]].tofile(fh[(pn, b)])
+for f in fh.values(): f.close()
+log(f"scatter done T={T} nA={nA} nB={nB}")
+cand = {"A": [], "F": []}; dist = {"A": 0, "B": 0, "F": 0}
+def count_file(path, step=2_000_000): # comptes exacts par sous-tranches (seaux très inégaux : patches fréquents)
+ K = np.zeros(0, np.uint64); C = np.zeros(0, np.int64); f = open(path, "rb")
+ while True:
+ x = np.frombuffer(f.read(8 * step), dtype=np.uint64)
+ if len(x) == 0: break
+ k2, c2 = np.unique(x, return_counts=True); del x
+ u, inv = np.unique(np.concatenate([K, k2]), return_inverse=True)
+ C = np.bincount(inv, weights=np.concatenate([C, c2]).astype(np.float64), minlength=len(u)).astype(np.int64); K = u
+ assert C.sum() == os.path.getsize(path) // 8
+ return K, C
+def topv(u, c):
+ o = np.lexsort((u, -c))[:V]; return u[o], c[o]
+for b in range(NB):
+ ua, ca = count_file(f"{bdir}/A{b:02d}.u64"); ub, cb = count_file(f"{bdir}/B{b:02d}.u64")
+ uf = np.union1d(ua, ub); cf = np.zeros(len(uf), np.int64)
+ cf[np.searchsorted(uf, ua)] += ca; cf[np.searchsorted(uf, ub)] += cb
+ dist["A"] += len(ua); dist["B"] += len(ub); dist["F"] += len(uf)
+ cand["A"].append(topv(ua, ca)); cand["F"].append(topv(uf, cf))
+ del ua, ca, ub, cb, uf, cf
+ os.remove(f"{bdir}/A{b:02d}.u64"); os.remove(f"{bdir}/B{b:02d}.u64")
+os.rmdir(bdir)
+res = {"T": T, "nA": nA, "nB": nB, "distinct": dist, "split_block": SPLIT_BLOCK}
+for k in ("A", "F"):
+ u = np.concatenate([x[0] for x in cand[k]]); c = np.concatenate([x[1] for x in cand[k]])
+ assert len(np.unique(u)) == len(u)
+ o = np.lexsort((u, -c))[:V]; voc = np.sort(u[o]).astype(np.uint64)
+ np.save(f"{P}.vocab_{k}.npy", voc); res[f"vocab_{k}_sha256"] = sha_arr(voc); res[f"vocab_{k}_n"] = len(voc)
+ res[f"vocab_{k}_min_count"] = int(c[o].min()); res[f"vocab_{k}_count_sum"] = int(c[o].sum())
+res["peak_rss_mb"] = peak_mb(); res["min_memavail_kb"] = PEAK["min_memavail_kb"]
+json.dump(res, open(P + ".vocab.json", "w"), indent=1); log("DONE " + json.dumps(res))
diff --git a/results/hashing/m7_sem/code/s3_cols.py b/results/hashing/m7_sem/code/s3_cols.py
new file mode 100644
index 0000000000000000000000000000000000000000..e8fdd601efea168df903a96cd1a285c36fe26078
--- /dev/null
+++ b/results/hashing/m7_sem/code/s3_cols.py
@@ -0,0 +1,29 @@
+"""M7sem étape 3 — colonnes de vocabulaire (== SPIRA.cols_of : searchsorted, UNK = V) pour vocab_A et vocab_F.
+PREFIX.colsA.u16 : col_A | (partie << 15) ; PREFIX.colsF.u16 : col_F. Comptes par colonne et par partie.
+usage : s3_cols.py PREFIX"""
+import sys, json
+import numpy as np
+from common import *
+P = sys.argv[1]; start_guard(); STEP = 1_000_000
+vA = np.load(P + ".vocab_A.npy"); vF = np.load(P + ".vocab_F.npy")
+def cols_of(voc, ids):
+ pos = np.searchsorted(voc, ids); pc = np.minimum(pos, V - 1)
+ ok = (pos < V) & (voc[pc] == ids); return np.where(ok, pc, V).astype(np.int64)
+fi = open(P + ".ids.u64", "rb"); fl = open(P + ".lens.u8", "rb"); off = 0
+oa = open(P + ".colsA.u16", "wb"); of = open(P + ".colsF.u16", "wb")
+cnt = {"A_A": np.zeros(V + 1, np.int64), "A_B": np.zeros(V + 1, np.int64), "F": np.zeros(V + 1, np.int64)}
+while True:
+ ids = np.frombuffer(fi.read(8 * STEP), dtype=np.uint64)
+ if len(ids) == 0: break
+ ln = np.frombuffer(fl.read(len(ids)), dtype=np.uint8).astype(np.int64)
+ st = off + np.concatenate([[0], np.cumsum(ln)[:-1]]); off += int(ln.sum()); part = (st // SPLIT_BLOCK) & 1
+ ca = cols_of(vA, ids); cf = cols_of(vF, ids)
+ cnt["A_A"] += np.bincount(ca[part == 0], minlength=V + 1); cnt["A_B"] += np.bincount(ca[part == 1], minlength=V + 1)
+ cnt["F"] += np.bincount(cf, minlength=V + 1)
+ (ca | (part << 15)).astype(np.uint16).tofile(oa); cf.astype(np.uint16).tofile(of)
+oa.close(); of.close()
+np.savez(P + ".colcounts.npz", **cnt)
+res = {"bytes": off, "colsA_sha256": sha_file(P + ".colsA.u16"), "colsF_sha256": sha_file(P + ".colsF.u16"),
+ "coverage_A_on_A": 1 - cnt["A_A"][V] / cnt["A_A"].sum(), "coverage_A_on_B": 1 - cnt["A_B"][V] / cnt["A_B"].sum(),
+ "coverage_F": 1 - cnt["F"][V] / cnt["F"].sum(), "peak_rss_mb": peak_mb(), "min_memavail_kb": PEAK["min_memavail_kb"]}
+json.dump(res, open(P + ".cols.json", "w"), indent=1); log("DONE " + json.dumps(res))
diff --git a/results/hashing/m7_sem/code/s4_cooc.py b/results/hashing/m7_sem/code/s4_cooc.py
new file mode 100644
index 0000000000000000000000000000000000000000..abc3a81f077c00cb12fd0d03d4547c572167a170
--- /dev/null
+++ b/results/hashing/m7_sem/code/s4_cooc.py
@@ -0,0 +1,69 @@
+"""M7sem étape 4 — co-occurrences ±W EXACTES (mêmes clés que countmin.cooc_ppmi_topk : a*V+b et b*V+a pour chaque paire (t, t+o),
+o=1..W, deux colonnes in-vocab), comptées en tableaux denses uint32 par partition de mots (NPW mots × V), plusieurs passes sur disque.
+A : paires dont les 2 positions sont dans A (vocab_A) ; B : 2 positions dans B (vocab_A, pour les voisins held-out) ; F : tout le flux (vocab_F).
+PPMI = max(log(c*tot/(rw[w]*rc[ctx])), 0) en float64, élément par élément (== countmin) ; top-16 par mot (tri lexsort((ctx,-pp,w)))
+pour A et F ; pour B : top-KB (256) contextes PPMI>0 avec valeurs (représentation des voisins).
+usage : s4_cooc.py PREFIX [--npw 512]"""
+import sys, os, json, argparse
+import numpy as np
+from common import *
+ap = argparse.ArgumentParser(); ap.add_argument("prefix"); ap.add_argument("--npw", type=int, default=512); ap.add_argument("--kb", type=int, default=256)
+a = ap.parse_args(); P = a.prefix; start_guard(); STEP = 1_000_000; W = WINDOW; NPW = a.npw; KB = a.kb
+T = os.path.getsize(P + ".colsA.u16") // 2; assert T == os.path.getsize(P + ".colsF.u16") // 2
+def segs(path):
+ f = open(path, "rb")
+ for s0 in range(0, T, STEP):
+ f.seek(2 * s0); seg = np.frombuffer(f.read(2 * (min(T, s0 + STEP + W) - s0)), dtype=np.uint16).astype(np.int64)
+ for o in range(1, W + 1):
+ L = min(s0 + STEP, T - o) - s0
+ if L > 0: yield seg[:L], seg[o:o + L]
+def valid_pairs(kind, x, y):
+ if kind == "F":
+ ok = (x < V) & (y < V); return x[ok], y[ok]
+ pi = 0 if kind == "A" else 1
+ px, py = x >> 15, y >> 15; x, y = x & 0x7FFF, y & 0x7FFF
+ ok = (x < V) & (y < V) & (px == pi) & (py == pi); return x[ok], y[ok]
+# ---- pré-passe : tot, rw (= rc par symétrie des clés)
+rw = {k: np.zeros(V, np.float64) for k in "ABF"}; tot = {}
+for k, path in (("A", P + ".colsA.u16"), ("B", P + ".colsA.u16"), ("F", P + ".colsF.u16")):
+ npairs = 0
+ for x, y in segs(path):
+ x, y = valid_pairs(k, x, y); npairs += len(x)
+ rw[k] += np.bincount(x, minlength=V) + np.bincount(y, minlength=V)
+ tot[k] = np.float64(2 * npairs); assert rw[k].sum() == tot[k]
+ log(f"prepass {k}: pairs={npairs} tot={tot[k]}")
+top = {k: np.full((V, TOPK), -1, np.int64) for k in "AF"}
+bctx = np.full((V, KB), -1, np.int16); bval = np.zeros((V, KB), np.float32)
+nnz = {k: 0 for k in "ABF"}
+for p0 in range(0, V, NPW):
+ p1 = min(V, p0 + NPW)
+ for group, path in (("AB", P + ".colsA.u16"), ("F", P + ".colsF.u16")):
+ kinds = [k for k in group if tot[k] > 0]
+ if not kinds: continue
+ dense = {k: np.zeros((p1 - p0) * V, np.uint32) for k in kinds}
+ for x0, y0 in segs(path):
+ for k in kinds:
+ x, y = valid_pairs(k, x0, y0)
+ m1 = (x >= p0) & (x < p1); m2 = (y >= p0) & (y < p1)
+ idx = np.concatenate([(x[m1] - p0) * V + y[m1], (y[m2] - p0) * V + x[m2]])
+ u, c = np.unique(idx, return_counts=True); dense[k][u] += c.astype(np.uint32)
+ for k in kinds:
+ d = dense.pop(k); nzi = np.flatnonzero(d); nnz[k] += len(nzi)
+ w = p0 + nzi // V; ctx = nzi % V; c = d[nzi].astype(np.float64); del d
+ pmi = np.log(c * tot[k] / (rw[k][w] * rw[k][ctx])); pp = np.maximum(pmi, 0.0); del pmi, c
+ order = np.lexsort((ctx, -pp, w)); w, ctx, pp = w[order], ctx[order], pp[order]; del order
+ vv = np.arange(p0, p1); s_ = np.searchsorted(w, vv); e_ = np.searchsorted(w, vv, side="right")
+ for i, v in enumerate(vv):
+ if k == "B":
+ s, e = s_[i], min(e_[i], s_[i] + KB); ok = pp[s:e] > 0
+ sel = ctx[s:e][ok]; bctx[v, :len(sel)] = sel; bval[v, :len(sel)] = pp[s:e][ok]
+ else:
+ s, e = s_[i], min(e_[i], s_[i] + TOPK); sel = ctx[s:e][pp[s:e] > 0]; top[k][v, :len(sel)] = sel
+ del w, ctx, pp
+ log(f"partition {p0}-{p1} done nnz={nnz}")
+res = {"T": T, "tot": {k: float(v) for k, v in tot.items()}, "distinct_pairs_nnz": nnz, "npw": NPW, "kb": KB}
+for k in "AF":
+ np.save(f"{P}.top{k}.npy", top[k]); res[f"top{k}_sha256"] = sha_arr(top[k]); res[f"top{k}_rows_with_ctx"] = int((top[k][:, 0] >= 0).sum())
+np.savez(P + ".ppmiB.npz", ctx=bctx, val=bval, rwB=rw["B"], rwA=rw["A"]); res["ppmiB_ctx_sha256"] = sha_arr(bctx); res["ppmiB_val_sha256"] = sha_arr(bval)
+res["peak_rss_mb"] = peak_mb(); res["min_memavail_kb"] = PEAK["min_memavail_kb"]
+json.dump(res, open(P + ".cooc.json", "w"), indent=1); log("DONE " + json.dumps(res))
diff --git a/results/hashing/m7_sem/code/s5_proj.py b/results/hashing/m7_sem/code/s5_proj.py
new file mode 100644
index 0000000000000000000000000000000000000000..8dd8cb04d0b10472c30d6e19e2af6ddf5270c77a
--- /dev/null
+++ b/results/hashing/m7_sem/code/s5_proj.py
@@ -0,0 +1,47 @@
+"""M7sem étape 5 — projection Count-Min figée (config du bras cm M8 v1b : countmin.py, CMSPIRA._structured_row) :
+ligne = 12 neurones v3 sur [0,1024) (6 hash du patch entier + 6 trigrammes, SPIRA._structured_row, k_tri=6)
+ + 24 neurones MinHash (countmin.minhash_rows, top-16 PPMI) sur [1024, 5120) ; sans contexte -> repli base[0] (comme CMSPIRA).
+d_in = 5120, k_in = 36. Octets du patch : 1re ET dernière occurrence dans le flux (vérifiées égales ; le registre du repo garde la dernière).
+usage : s5_proj.py PREFIX"""
+import sys, json, dataclasses
+import numpy as np
+from common import *
+sys.path.insert(0, "/workspace/spira_shared/semhash")
+from countmin import minhash_rows # lecture seule, sha vérifié dans le verdict
+from spira.model import SPIRA, SPIRAConfig
+P = sys.argv[1]; start_guard(); STEP = 1_000_000
+voc = {k: np.load(f"{P}.vocab_{k}.npy") for k in "AF"}
+first = {k: np.full(V, -1, np.int64) for k in "AF"}; last = {k: np.full(V, -1, np.int64) for k in "AF"}
+flen = {k: np.zeros(V, np.int64) for k in "AF"}; llen = {k: np.zeros(V, np.int64) for k in "AF"}
+fi = open(P + ".ids.u64", "rb"); fl = open(P + ".lens.u8", "rb"); off = 0
+while True:
+ ids = np.frombuffer(fi.read(8 * STEP), dtype=np.uint64)
+ if len(ids) == 0: break
+ ln = np.frombuffer(fl.read(len(ids)), dtype=np.uint8).astype(np.int64)
+ st = off + np.concatenate([[0], np.cumsum(ln)[:-1]]); off += int(ln.sum())
+ for k in "AF":
+ pos = np.searchsorted(voc[k], ids); pc = np.minimum(pos, V - 1); ok = (pos < V) & (voc[k][pc] == ids)
+ c = pc[ok]; s = st[ok]; l = ln[ok]
+ u, i0 = np.unique(c, return_index=True); new = first[k][u] < 0
+ first[k][u[new]] = s[i0[new]]; flen[k][u[new]] = l[i0[new]]
+ u2, i1 = np.unique(c[::-1], return_index=True); last[k][u2] = s[::-1][i1]; llen[k][u2] = l[::-1][i1]
+F = open(CORPUS, "rb")
+def rd(o, n): F.seek(int(o)); return F.read(int(n))
+cfgb = SPIRAConfig(vocab_size=V, d_in=BASE_D, k_in=BASE_K)
+class _Dummy: cfg = cfgb
+res = {}
+for k in "AF":
+ assert (first[k] >= 0).all()
+ pb = [rd(first[k][v], flen[k][v]) for v in range(V)]
+ assert all(pb[v] == rd(last[k][v], llen[k][v]) for v in range(V)), "octets 1re != dernière occurrence (collision FNV ?)"
+ base = np.stack([SPIRA._structured_row(_Dummy, int(voc[k][v]), pb[v]) for v in range(V)]).astype(np.int32)
+ top = np.load(f"{P}.top{k}.npy"); sem = minhash_rows(top, CM_D, CM_W, BASE_D)
+ has = sem[:, 0] >= 0
+ proj = np.concatenate([base, np.where(sem < 0, base[:, :1], sem)], axis=1).astype(np.int32)
+ assert proj.shape == (V, BASE_K + CM_D) and proj.min() >= 0 and proj.max() < BASE_D + CM_W
+ np.savez(f"{P}.proj_{k}.npz", vocab_ids=voc[k], base=base, sem=sem, proj=proj, top=top, has_ctx=has,
+ patch_bytes=np.array([b.hex() for b in pb]))
+ res[k] = {"proj_sha256": sha_arr(proj), "sem_sha256": sha_arr(sem), "base_sha256": sha_arr(base), "vocab_sha256": sha_arr(voc[k]),
+ "n_with_ctx": int(has.sum()), "d_in": BASE_D + CM_W, "k_in": BASE_K + CM_D}
+res["peak_rss_mb"] = peak_mb(); res["min_memavail_kb"] = PEAK["min_memavail_kb"]
+json.dump(res, open(P + ".proj.json", "w"), indent=1); log("DONE " + json.dumps(res))
diff --git a/results/hashing/m7_sem/code/s6_analysis.py b/results/hashing/m7_sem/code/s6_analysis.py
new file mode 100644
index 0000000000000000000000000000000000000000..34bd17e76d26de36aa6ab1d9ba5366d71885ea5c
--- /dev/null
+++ b/results/hashing/m7_sem/code/s6_analysis.py
@@ -0,0 +1,175 @@
+"""M7sem étape 6 — mesure pré-déclarée (PREDECL_M7sem.md). Aucune lecture des comptes de B dans la projection testée (proj_A).
+usage : s6_analysis.py PREFIX OUTJSON"""
+import sys, json, re
+import numpy as np
+from common import *
+from spira.hashing import input_neurons
+import scipy.sparse as sp
+P, OUTJ = sys.argv[1], sys.argv[2]; start_guard()
+# ---- paramètres PRÉ-DÉCLARÉS (ne pas modifier après gel)
+MIN_B_COUNT, MIN_B_NNZ, K_NEI, MIN_COS, EXCL_TOP, R_RAND, NBINS = 50, 5, 5, 0.20, 50, 5, 20
+DELTA = 1.0 / CM_D; B_BOOT, SEED_BOOT, SEED_PAIRS, N_PERM, SEED_PERM = 10_000, 0, 20261024, 10_000, 1
+MIN_ANCHORS, MIN_PAIRS = 1000, 2000
+zA = np.load(P + ".proj_A.npz"); zF = np.load(P + ".proj_F.npz"); zb = np.load(P + ".ppmiB.npz"); cc = np.load(P + ".colcounts.npz")
+vocA = zA["vocab_ids"]; semA = zA["sem"]; projA = zA["proj"]; hasA = zA["has_ctx"]
+cntA, cntB = cc["A_A"][:V], cc["A_B"][:V]
+bctx, bval = zb["ctx"].astype(np.int64), zb["val"]; bnnz = (bctx >= 0).sum(1)
+E = np.flatnonzero(hasA & (cntB >= MIN_B_COUNT) & (bnnz >= MIN_B_NNZ)); nE = len(E)
+log(f"eligible E={nE} (has_ctx_A={int(hasA.sum())}, B>= {MIN_B_COUNT}: {int((cntB>=MIN_B_COUNT).sum())})")
+# ---- vecteurs PPMI de B (top-256), normés L2
+rows = np.repeat(np.arange(nE), bnnz[E]); m = bctx[E] >= 0
+X = sp.csr_matrix((bval[E][m].astype(np.float32), (rows, bctx[E][m])), shape=(nE, V))
+nr = np.sqrt(np.asarray(X.multiply(X).sum(1)).ravel()); X = sp.diags(1 / nr) @ X; XT = X.T.tocsr()
+nei = np.full((nE, EXCL_TOP), -1, np.int64); neic = np.zeros((nE, EXCL_TOP), np.float32)
+for r0 in range(0, nE, 512):
+ S = (X[r0:r0 + 512] @ XT).toarray().astype(np.float32)
+ S[np.arange(S.shape[0]), np.arange(r0, r0 + S.shape[0])] = -np.inf
+ part = np.argpartition(-S, EXCL_TOP, axis=1)[:, :EXCL_TOP]
+ ps = np.take_along_axis(S, part, 1); o = np.lexsort((part, -ps), axis=1)
+ nei[r0:r0 + 512] = np.take_along_axis(part, o, 1); neic[r0:r0 + 512] = np.take_along_axis(ps, o, 1); del S
+log("cosine neighbours done")
+# ---- paires proches (indices dans E), ancres
+ci, cj, ccos = [], [], []
+for i in range(nE):
+ for t in range(K_NEI):
+ if neic[i, t] >= MIN_COS: ci.append(i); cj.append(nei[i, t]); ccos.append(neic[i, t])
+ci, cj, ccos = np.array(ci), np.array(cj), np.array(ccos)
+# ---- appariement en fréquence (cntA, bins de quantiles sur E)
+lf = np.log(cntA[E].astype(np.float64)); edges = np.quantile(lf, np.linspace(0, 1, NBINS + 1)[1:-1]); fb = np.searchsorted(edges, lf, side="right")
+bins = [np.flatnonzero(fb == b) for b in range(NBINS)]
+rng = np.random.default_rng(SEED_PAIRS); excl = [set(nei[i].tolist()) | {i} for i in range(nE)]
+ri, rj, rk = [], [], [] # paire aléatoire appariée : (ancre, j', indice de la paire proche)
+for p in range(len(ci)):
+ i, j = ci[p], cj[p]; pool = bins[fb[j]]; got = 0
+ while got < R_RAND:
+ x = int(pool[rng.integers(len(pool))])
+ if x in excl[i]: continue
+ ri.append(i); rj.append(x); rk.append(p); got += 1
+ri, rj, rk = np.array(ri), np.array(rj), np.array(rk)
+log(f"pairs close={len(ci)} random={len(ri)}")
+# ---- ensembles de neurones et chevauchement |Si ∩ Sj| / k
+def dedup(R, neg0):
+ R = np.sort(R, 1).astype(np.int64); dup = np.zeros_like(R, bool); dup[:, 1:] = R[:, 1:] == R[:, :-1]
+ return np.where(dup, -(neg0 + np.arange(R.shape[1]))[None, :], R)
+def overlap(R, a, b, k):
+ Ra, Rb = dedup(R[a], 1), dedup(R[b], 1000); out = np.empty(len(a))
+ for s in range(0, len(a), 50_000):
+ out[s:s + 50_000] = (Ra[s:s + 50_000, :, None] == Rb[s:s + 50_000, None, :]).sum((1, 2)) / k
+ return out
+pidE = vocA[E]
+CM = semA[E] # bloc CM (24 sur [1024,5120)) de la projection A
+HCM = np.array([[BASE_D + x for x in input_neurons(int(p), CM_W, CM_D)] for p in pidE]) # témoin hash aléatoire, même d/k
+FULL = projA[E] # ligne complète 36 / 5120
+HFULL = np.array([input_neurons(int(p), BASE_D + CM_W, BASE_K + CM_D) for p in pidE])
+def anchor_mean(vals, anc):
+ s = np.bincount(anc, weights=vals, minlength=nE); n = np.bincount(anc, minlength=nE); return s, n
+A_ids = np.unique(ci); nA_ = len(A_ids)
+def stats_for(Rproj, Rhash, k):
+ oc = overlap(Rproj, ci, cj, k); orr = overlap(Rproj, ri, rj, k); oh = overlap(Rhash, ci, cj, k); ohr = overlap(Rhash, ri, rj, k)
+ sc, nc = anchor_mean(oc, ci); sr, nr_ = anchor_mean(orr, ri); sh, _ = anchor_mean(oh, ci)
+ mc = sc[A_ids] / nc[A_ids]; mr = sr[A_ids] / nr_[A_ids]; mh = sh[A_ids] / nc[A_ids]
+ return oc, orr, oh, ohr, mc, mr, mh
+def boot(x, seed=SEED_BOOT, B=B_BOOT):
+ r = np.random.default_rng(seed); n = len(x); out = np.empty(B)
+ for b0 in range(0, B, 500):
+ idx = r.integers(0, n, size=(min(500, B - b0), n)); out[b0:b0 + idx.shape[0]] = x[idx].mean(1)
+ return [float(np.percentile(out, 2.5)), float(np.percentile(out, 97.5))]
+def perm_p(d, seed=SEED_PERM, N=N_PERM):
+ r = np.random.default_rng(seed); obs = abs(d.mean()); cnt = 0
+ for b0 in range(0, N, 500):
+ s = r.choice([-1.0, 1.0], size=(min(500, N - b0), len(d))); cnt += int((np.abs((s * d).mean(1)) >= obs - 1e-15).sum())
+ return (cnt + 1) / (N + 1)
+def auc_boot(oc, orr, k, seed=SEED_BOOT, B=B_BOOT):
+ vals = np.round(oc * k).astype(int); valr = np.round(orr * k).astype(int)
+ Hc = np.zeros((nE, k + 1)); np.add.at(Hc, (ci, vals), 1); Hr = np.zeros((nE, k + 1)); np.add.at(Hr, (ri, valr), 1)
+ Hc, Hr = Hc[A_ids], Hr[A_ids]
+ def auc(hc, hr):
+ cr = np.cumsum(hr, -1) - hr; return ((hc * (cr + 0.5 * hr)).sum(-1)) / (hc.sum(-1) * hr.sum(-1))
+ pt = float(auc(Hc.sum(0), Hr.sum(0))); r = np.random.default_rng(seed); out = np.empty(B)
+ for b in range(B):
+ w = np.bincount(r.integers(0, nA_, nA_), minlength=nA_).astype(float); out[b] = auc(w @ Hc, w @ Hr)
+ return pt, [float(np.percentile(out, 2.5)), float(np.percentile(out, 97.5))]
+res = {"params": {"MIN_B_COUNT": MIN_B_COUNT, "MIN_B_NNZ": MIN_B_NNZ, "K_NEI": K_NEI, "MIN_COS": MIN_COS, "EXCL_TOP": EXCL_TOP, "R_RAND": R_RAND,
+ "NBINS": NBINS, "DELTA": DELTA, "B_BOOT": B_BOOT, "SEED_BOOT": SEED_BOOT, "SEED_PAIRS": SEED_PAIRS, "N_PERM": N_PERM, "SEED_PERM": SEED_PERM},
+ "n_vocab_A": V, "n_has_ctx_A": int(hasA.sum()), "n_eligible": nE, "n_anchors": int(nA_), "n_close_pairs": int(len(ci)), "n_random_pairs": int(len(ri)),
+ "close_cos": {"mean": float(ccos.mean()) if len(ccos) else None, "p10": float(np.percentile(ccos, 10)) if len(ccos) else None, "p50": float(np.median(ccos)) if len(ccos) else None},
+ "coverage": {"tokens_B_in_E_frac": float(cntB[E].sum() / cc["A_B"].sum()), "tokens_A_in_E_frac": float(cntA[E].sum() / cc["A_A"].sum())}}
+for name, Rp, Rh, k in (("CM24_primary", CM, HCM, CM_D), ("FULL36_secondary", FULL, HFULL, BASE_K + CM_D)):
+ oc, orr, oh, ohr, mc, mr, mh = stats_for(Rp, Rh, k); dr = mc - mr; dh = mc - mh
+ auc_pt, auc_ci = auc_boot(oc, orr, k)
+ res[name] = {"k": k, "mean_overlap_close": float(oc.mean()), "mean_overlap_random_matched": float(orr.mean()),
+ "mean_overlap_close_randomhash": float(oh.mean()), "mean_overlap_random_randomhash": float(ohr.mean()),
+ "anchor_mean_close": float(mc.mean()), "anchor_mean_random": float(mr.mean()), "anchor_mean_close_hash": float(mh.mean()),
+ "delta_vs_random": float(dr.mean()), "delta_vs_random_ci95": boot(dr), "delta_vs_random_perm_p": perm_p(dr),
+ "delta_vs_hash": float(dh.mean()), "delta_vs_hash_ci95": boot(dh), "delta_vs_hash_perm_p": perm_p(dh),
+ "mean_shared_neurons_close": float(oc.mean() * k), "mean_shared_neurons_random": float(orr.mean() * k),
+ "frac_close_pairs_share_ge1": float((oc > 0).mean()), "frac_random_pairs_share_ge1": float((orr > 0).mean()),
+ "auc_close_vs_random": auc_pt, "auc_ci95": auc_ci}
+ if name == "CM24_primary":
+ bins_c = [0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1.01]; res["dose_response_CM24"] = [
+ {"cos": [bins_c[b], bins_c[b + 1]], "n": int(((ccos >= bins_c[b]) & (ccos < bins_c[b + 1])).sum()),
+ "mean_overlap": float(oc[(ccos >= bins_c[b]) & (ccos < bins_c[b + 1])].mean()) if ((ccos >= bins_c[b]) & (ccos < bins_c[b + 1])).any() else None}
+ for b in range(len(bins_c) - 1)]
+ log(f"{name}: {json.dumps(res[name])}")
+# ---- proxy objectif (secondaire) : variantes de casse et d'espace initial, dans vocab_A avec contexte A
+pb = [bytes.fromhex(h) for h in zA["patch_bytes"]]; key = {b: v for v, b in enumerate(pb)}
+def proxy_pairs(kind):
+ out = []
+ for v, b in enumerate(pb):
+ if not hasA[v]: continue
+ if kind == "case":
+ if b[:1].isalpha() and b[:1].islower():
+ w = key.get(b[:1].upper() + b[1:])
+ elif b[:2] in (b" a", b" b") or (len(b) > 1 and b[:1] == b" " and b[1:2].isalpha() and b[1:2].islower()):
+ w = key.get(b[:1] + b[1:2].upper() + b[2:])
+ else: w = None
+ else:
+ w = key.get(b" " + b) if not b.startswith(b" ") else None
+ if w is not None and hasA[w] and w != v: out.append((v, w))
+ return out
+hasidx = np.flatnonzero(hasA); lfa = np.log(np.maximum(cntA, 1).astype(np.float64)); edges2 = np.quantile(lfa[hasidx], np.linspace(0, 1, NBINS + 1)[1:-1])
+fb2 = np.searchsorted(edges2, lfa, side="right"); bins2 = [hasidx[fb2[hasidx] == b] for b in range(NBINS)]
+res["proxies_secondary"] = {}
+for kind in ("case", "space"):
+ pr = proxy_pairs(kind)
+ if len(pr) < 30: res["proxies_secondary"][kind] = {"n_pairs": len(pr), "status": "trop peu de paires"}; continue
+ a = np.array([p[0] for p in pr]); b = np.array([p[1] for p in pr]); r2 = np.random.default_rng(SEED_PAIRS + 1)
+ def draw(x, y):
+ pool = bins2[fb2[y]]; out = []
+ while len(out) < R_RAND:
+ z = int(pool[r2.integers(len(pool))])
+ if z != x and z != y: out.append(z)
+ return out
+ rb = np.array([draw(x, y) for x, y in zip(a, b)])
+ S = semA.astype(np.int64)
+ def ovp(x, y):
+ Ra, Rb = dedup(S[x], 1), dedup(S[y], 1000); return (Ra[:, :, None] == Rb[:, None, :]).sum((1, 2)) / CM_D
+ oc = ovp(a, b); orr = np.stack([ovp(a, rb[:, t]) for t in range(R_RAND)], 1).mean(1)
+ Hh = {int(v): [BASE_D + x for x in input_neurons(int(vocA[v]), CM_W, CM_D)] for v in np.unique(np.concatenate([a, b]))}
+ Sh = np.zeros((V, CM_D), np.int64)
+ for v, row in Hh.items(): Sh[v] = row
+ Ra, Rb = dedup(Sh[a], 1), dedup(Sh[b], 1000); oh = (Ra[:, :, None] == Rb[:, None, :]).sum((1, 2)) / CM_D
+ d1, d2 = oc - orr, oc - oh
+ res["proxies_secondary"][kind] = {"n_pairs": len(pr), "examples": [[pb[x].decode("latin-1"), pb[y].decode("latin-1")] for x, y in pr[:8]],
+ "mean_overlap_close": float(oc.mean()), "mean_overlap_random_matched": float(orr.mean()), "mean_overlap_randomhash": float(oh.mean()),
+ "delta_vs_random": float(d1.mean()), "delta_vs_random_ci95": boot(d1), "delta_vs_hash": float(d2.mean()), "delta_vs_hash_ci95": boot(d2)}
+ log(f"proxy {kind}: {json.dumps(res['proxies_secondary'][kind])}")
+# ---- descriptif CIRCULAIRE (non décisionnel) : projection F (inclut B) sur les mêmes patches, si mêmes ids
+posF = np.searchsorted(zF["vocab_ids"], pidE); okF = (posF < V) & (zF["vocab_ids"][np.minimum(posF, V - 1)] == pidE) & zF["has_ctx"][np.minimum(posF, V - 1)]
+if okF.all():
+ oc = overlap(zF["sem"][posF], ci, cj, CM_D); orr = overlap(zF["sem"][posF], ri, rj, CM_D)
+ res["circular_descriptive_projF"] = {"mean_overlap_close": float(oc.mean()), "mean_overlap_random": float(orr.mean())}
+else:
+ res["circular_descriptive_projF"] = {"status": f"{int((~okF).sum())} patches de E absents/sans contexte dans vocab_F ; non calculé"}
+# ---- décision (règle pré-déclarée)
+pm = res.get("CM24_primary")
+if nE < MIN_ANCHORS or len(ci) < MIN_PAIRS or nA_ < MIN_ANCHORS:
+ verdict, why = "NON MESURABLE", f"données insuffisantes (E={nE}, ancres={nA_}, paires={len(ci)})"
+else:
+ c1 = pm["delta_vs_random_ci95"][0] > 0 and pm["delta_vs_random"] >= DELTA
+ c2 = pm["delta_vs_hash_ci95"][0] > 0 and pm["delta_vs_hash"] >= DELTA
+ verdict = "OUI" if (c1 and c2) else "NON"
+ why = f"vs aléatoire apparié: {'OK' if c1 else 'ÉCHEC'} ; vs hash aléatoire: {'OK' if c2 else 'ÉCHEC'} (δ={DELTA:.5f})"
+res["verdict_rule_output"] = {"verdict": verdict, "why": why}
+res["peak_rss_mb"] = peak_mb(); res["min_memavail_kb"] = PEAK["min_memavail_kb"]
+json.dump(res, open(OUTJ, "w"), indent=1, ensure_ascii=False); log(f"VERDICT {verdict} — {why}")
diff --git a/results/hashing/m7_sem/code/s6_analysis_a3.py b/results/hashing/m7_sem/code/s6_analysis_a3.py
new file mode 100644
index 0000000000000000000000000000000000000000..1e5616eae9b9e493b440426b3e9227685e610fb6
--- /dev/null
+++ b/results/hashing/m7_sem/code/s6_analysis_a3.py
@@ -0,0 +1,183 @@
+"""M7sem étape 6 — mesure pré-déclarée (PREDECL_M7sem.md). Aucune lecture des comptes de B dans la projection testée (proj_A).
+usage : s6_analysis.py PREFIX OUTJSON"""
+import sys, json, re
+import numpy as np
+from common import *
+from spira.hashing import input_neurons
+import scipy.sparse as sp
+P, OUTJ = sys.argv[1], sys.argv[2]; start_guard()
+# ---- paramètres PRÉ-DÉCLARÉS (ne pas modifier après gel)
+MIN_B_COUNT, MIN_B_NNZ, K_NEI, MIN_COS, EXCL_TOP, R_RAND, NBINS = 50, 5, 5, 0.20, 50, 5, 20
+DELTA = 1.0 / CM_D; B_BOOT, SEED_BOOT, SEED_PAIRS, N_PERM, SEED_PERM = 10_000, 0, 20261024, 10_000, 1
+MIN_ANCHORS, MIN_PAIRS = 1000, 2000
+zA = np.load(P + ".proj_A.npz"); zF = np.load(P + ".proj_F.npz"); zb = np.load(P + ".ppmiB.npz"); cc = np.load(P + ".colcounts.npz")
+vocA = zA["vocab_ids"]; semA = zA["sem"]; projA = zA["proj"]; hasA = zA["has_ctx"]
+cntA, cntB = cc["A_A"][:V], cc["A_B"][:V]
+bctx, bval = zb["ctx"].astype(np.int64), zb["val"]; bnnz = (bctx >= 0).sum(1)
+E = np.flatnonzero(hasA & (cntB >= MIN_B_COUNT) & (bnnz >= MIN_B_NNZ)); nE = len(E)
+log(f"eligible E={nE} (has_ctx_A={int(hasA.sum())}, B>= {MIN_B_COUNT}: {int((cntB>=MIN_B_COUNT).sum())})")
+# ---- vecteurs PPMI de B (top-256), normés L2
+rows = np.repeat(np.arange(nE), bnnz[E]); m = bctx[E] >= 0
+X = sp.csr_matrix((bval[E][m].astype(np.float32), (rows, bctx[E][m])), shape=(nE, V))
+nr = np.sqrt(np.asarray(X.multiply(X).sum(1)).ravel()); X = sp.diags(1 / nr) @ X; XT = X.T.tocsr()
+nei = np.full((nE, EXCL_TOP), -1, np.int64); neic = np.zeros((nE, EXCL_TOP), np.float32)
+RB = 64 # AMENDEMENT 3 : 512 -> 64 lignes par bloc (ressources seulement ; calcul ligne à ligne indépendant)
+for r0 in range(0, nE, RB):
+ S = (X[r0:r0 + RB] @ XT).toarray().astype(np.float32)
+ S[np.arange(S.shape[0]), np.arange(r0, r0 + S.shape[0])] = -np.inf
+ part = np.argpartition(-S, EXCL_TOP, axis=1)[:, :EXCL_TOP]
+ ps = np.take_along_axis(S, part, 1); o = np.lexsort((part, -ps), axis=1)
+ nei[r0:r0 + RB] = np.take_along_axis(part, o, 1); neic[r0:r0 + RB] = np.take_along_axis(ps, o, 1); del S
+del X, XT, rows, m, bctx, bval, zb
+import ctypes; ctypes.CDLL("libc.so.6").malloc_trim(0) # AMENDEMENT 3b : rendre la mémoire libérée
+log("cosine neighbours done")
+# ---- paires proches (indices dans E), ancres
+ci, cj, ccos = [], [], []
+for i in range(nE):
+ for t in range(K_NEI):
+ if neic[i, t] >= MIN_COS: ci.append(i); cj.append(nei[i, t]); ccos.append(neic[i, t])
+ci, cj, ccos = np.array(ci), np.array(cj), np.array(ccos)
+# ---- appariement en fréquence (cntA, bins de quantiles sur E)
+lf = np.log(cntA[E].astype(np.float64)); edges = np.quantile(lf, np.linspace(0, 1, NBINS + 1)[1:-1]); fb = np.searchsorted(edges, lf, side="right")
+bins = [np.flatnonzero(fb == b) for b in range(NBINS)]
+rng = np.random.default_rng(SEED_PAIRS); excl = [set(nei[i].tolist()) | {i} for i in range(nE)]
+NR = len(ci) * R_RAND; ri = np.empty(NR, np.int64); rj = np.empty(NR, np.int64); rk = np.empty(NR, np.int64); q = 0 # AMENDEMENT 3 : tableaux préalloués (même ordre, mêmes tirages)
+for p in range(len(ci)):
+ i, j = ci[p], cj[p]; pool = bins[fb[j]]; got = 0
+ while got < R_RAND:
+ x = int(pool[rng.integers(len(pool))])
+ if x in excl[i]: continue
+ ri[q] = i; rj[q] = x; rk[q] = p; q += 1; got += 1
+assert q == NR; del excl
+log(f"pairs close={len(ci)} random={len(ri)}")
+# ---- ensembles de neurones et chevauchement |Si ∩ Sj| / k
+def dedup(R, neg0):
+ R = np.sort(R, 1).astype(np.int64); dup = np.zeros_like(R, bool); dup[:, 1:] = R[:, 1:] == R[:, :-1]
+ return np.where(dup, -(neg0 + np.arange(R.shape[1]))[None, :], R)
+def overlap(R, a, b, k): # AMENDEMENT 3 : dédoublonnage par tranches de 20 000 (opération ligne à ligne, résultat identique)
+ out = np.empty(len(a))
+ for s in range(0, len(a), 20_000):
+ Ra, Rb = dedup(R[a[s:s + 20_000]], 1), dedup(R[b[s:s + 20_000]], 1000)
+ out[s:s + 20_000] = (Ra[:, :, None] == Rb[:, None, :]).sum((1, 2)) / k
+ return out
+pidE = vocA[E]
+CM = semA[E] # bloc CM (24 sur [1024,5120)) de la projection A
+HCM = np.array([[BASE_D + x for x in input_neurons(int(p), CM_W, CM_D)] for p in pidE]) # témoin hash aléatoire, même d/k
+FULL = projA[E] # ligne complète 36 / 5120
+HFULL = np.array([input_neurons(int(p), BASE_D + CM_W, BASE_K + CM_D) for p in pidE])
+def anchor_mean(vals, anc):
+ s = np.bincount(anc, weights=vals, minlength=nE); n = np.bincount(anc, minlength=nE); return s, n
+A_ids = np.unique(ci); nA_ = len(A_ids)
+def stats_for(Rproj, Rhash, k):
+ oc = overlap(Rproj, ci, cj, k); orr = overlap(Rproj, ri, rj, k); oh = overlap(Rhash, ci, cj, k); ohr = overlap(Rhash, ri, rj, k)
+ sc, nc = anchor_mean(oc, ci); sr, nr_ = anchor_mean(orr, ri); sh, _ = anchor_mean(oh, ci)
+ mc = sc[A_ids] / nc[A_ids]; mr = sr[A_ids] / nr_[A_ids]; mh = sh[A_ids] / nc[A_ids]
+ return oc, orr, oh, ohr, mc, mr, mh
+def boot(x, seed=SEED_BOOT, B=B_BOOT):
+ r = np.random.default_rng(seed); n = len(x); out = np.empty(B)
+ for b0 in range(0, B, 500):
+ nb = min(500, B - b0) # AMENDEMENT 3b : tirages par sous-blocs de 25 lignes (flux RNG identique, vérifié t_a3_unit.py)
+ for t in range(0, nb, 25):
+ idx = r.integers(0, n, size=(min(25, nb - t), n)); out[b0 + t:b0 + t + idx.shape[0]] = x[idx].mean(1)
+ return [float(np.percentile(out, 2.5)), float(np.percentile(out, 97.5))]
+def perm_p(d, seed=SEED_PERM, N=N_PERM):
+ r = np.random.default_rng(seed); obs = abs(d.mean()); cnt = 0
+ for b0 in range(0, N, 500):
+ nb = min(500, N - b0) # AMENDEMENT 3b : tirages par sous-blocs de 25 lignes (flux RNG identique, vérifié t_a3_unit.py)
+ for t in range(0, nb, 25):
+ s = r.choice([-1.0, 1.0], size=(min(25, nb - t), len(d))); cnt += int((np.abs((s * d).mean(1)) >= obs - 1e-15).sum())
+ return (cnt + 1) / (N + 1)
+def auc_boot(oc, orr, k, seed=SEED_BOOT, B=B_BOOT):
+ vals = np.round(oc * k).astype(int); valr = np.round(orr * k).astype(int)
+ Hc = np.zeros((nE, k + 1)); np.add.at(Hc, (ci, vals), 1); Hr = np.zeros((nE, k + 1)); np.add.at(Hr, (ri, valr), 1)
+ Hc, Hr = Hc[A_ids], Hr[A_ids]
+ def auc(hc, hr):
+ cr = np.cumsum(hr, -1) - hr; return ((hc * (cr + 0.5 * hr)).sum(-1)) / (hc.sum(-1) * hr.sum(-1))
+ pt = float(auc(Hc.sum(0), Hr.sum(0))); r = np.random.default_rng(seed); out = np.empty(B)
+ for b in range(B):
+ w = np.bincount(r.integers(0, nA_, nA_), minlength=nA_).astype(float); out[b] = auc(w @ Hc, w @ Hr)
+ return pt, [float(np.percentile(out, 2.5)), float(np.percentile(out, 97.5))]
+res = {"params": {"MIN_B_COUNT": MIN_B_COUNT, "MIN_B_NNZ": MIN_B_NNZ, "K_NEI": K_NEI, "MIN_COS": MIN_COS, "EXCL_TOP": EXCL_TOP, "R_RAND": R_RAND,
+ "NBINS": NBINS, "DELTA": DELTA, "B_BOOT": B_BOOT, "SEED_BOOT": SEED_BOOT, "SEED_PAIRS": SEED_PAIRS, "N_PERM": N_PERM, "SEED_PERM": SEED_PERM},
+ "n_vocab_A": V, "n_has_ctx_A": int(hasA.sum()), "n_eligible": nE, "n_anchors": int(nA_), "n_close_pairs": int(len(ci)), "n_random_pairs": int(len(ri)),
+ "close_cos": {"mean": float(ccos.mean()) if len(ccos) else None, "p10": float(np.percentile(ccos, 10)) if len(ccos) else None, "p50": float(np.median(ccos)) if len(ccos) else None},
+ "coverage": {"tokens_B_in_E_frac": float(cntB[E].sum() / cc["A_B"].sum()), "tokens_A_in_E_frac": float(cntA[E].sum() / cc["A_A"].sum())}}
+for name, Rp, Rh, k in (("CM24_primary", CM, HCM, CM_D), ("FULL36_secondary", FULL, HFULL, BASE_K + CM_D)):
+ oc, orr, oh, ohr, mc, mr, mh = stats_for(Rp, Rh, k); dr = mc - mr; dh = mc - mh
+ auc_pt, auc_ci = auc_boot(oc, orr, k)
+ res[name] = {"k": k, "mean_overlap_close": float(oc.mean()), "mean_overlap_random_matched": float(orr.mean()),
+ "mean_overlap_close_randomhash": float(oh.mean()), "mean_overlap_random_randomhash": float(ohr.mean()),
+ "anchor_mean_close": float(mc.mean()), "anchor_mean_random": float(mr.mean()), "anchor_mean_close_hash": float(mh.mean()),
+ "delta_vs_random": float(dr.mean()), "delta_vs_random_ci95": boot(dr), "delta_vs_random_perm_p": perm_p(dr),
+ "delta_vs_hash": float(dh.mean()), "delta_vs_hash_ci95": boot(dh), "delta_vs_hash_perm_p": perm_p(dh),
+ "mean_shared_neurons_close": float(oc.mean() * k), "mean_shared_neurons_random": float(orr.mean() * k),
+ "frac_close_pairs_share_ge1": float((oc > 0).mean()), "frac_random_pairs_share_ge1": float((orr > 0).mean()),
+ "auc_close_vs_random": auc_pt, "auc_ci95": auc_ci}
+ if name == "CM24_primary":
+ bins_c = [0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1.01]; res["dose_response_CM24"] = [
+ {"cos": [bins_c[b], bins_c[b + 1]], "n": int(((ccos >= bins_c[b]) & (ccos < bins_c[b + 1])).sum()),
+ "mean_overlap": float(oc[(ccos >= bins_c[b]) & (ccos < bins_c[b + 1])].mean()) if ((ccos >= bins_c[b]) & (ccos < bins_c[b + 1])).any() else None}
+ for b in range(len(bins_c) - 1)]
+ log(f"{name}: {json.dumps(res[name])}")
+# ---- proxy objectif (secondaire) : variantes de casse et d'espace initial, dans vocab_A avec contexte A
+pb = [bytes.fromhex(h) for h in zA["patch_bytes"]]; key = {b: v for v, b in enumerate(pb)}
+def proxy_pairs(kind):
+ out = []
+ for v, b in enumerate(pb):
+ if not hasA[v]: continue
+ if kind == "case":
+ if b[:1].isalpha() and b[:1].islower():
+ w = key.get(b[:1].upper() + b[1:])
+ elif b[:2] in (b" a", b" b") or (len(b) > 1 and b[:1] == b" " and b[1:2].isalpha() and b[1:2].islower()):
+ w = key.get(b[:1] + b[1:2].upper() + b[2:])
+ else: w = None
+ else:
+ w = key.get(b" " + b) if not b.startswith(b" ") else None
+ if w is not None and hasA[w] and w != v: out.append((v, w))
+ return out
+hasidx = np.flatnonzero(hasA); lfa = np.log(np.maximum(cntA, 1).astype(np.float64)); edges2 = np.quantile(lfa[hasidx], np.linspace(0, 1, NBINS + 1)[1:-1])
+fb2 = np.searchsorted(edges2, lfa, side="right"); bins2 = [hasidx[fb2[hasidx] == b] for b in range(NBINS)]
+res["proxies_secondary"] = {}
+for kind in ("case", "space"):
+ pr = proxy_pairs(kind)
+ if len(pr) < 30: res["proxies_secondary"][kind] = {"n_pairs": len(pr), "status": "trop peu de paires"}; continue
+ a = np.array([p[0] for p in pr]); b = np.array([p[1] for p in pr]); r2 = np.random.default_rng(SEED_PAIRS + 1)
+ def draw(x, y):
+ pool = bins2[fb2[y]]; out = []
+ while len(out) < R_RAND:
+ z = int(pool[r2.integers(len(pool))])
+ if z != x and z != y: out.append(z)
+ return out
+ rb = np.array([draw(x, y) for x, y in zip(a, b)])
+ S = semA.astype(np.int64)
+ def ovp(x, y):
+ Ra, Rb = dedup(S[x], 1), dedup(S[y], 1000); return (Ra[:, :, None] == Rb[:, None, :]).sum((1, 2)) / CM_D
+ oc = ovp(a, b); orr = np.stack([ovp(a, rb[:, t]) for t in range(R_RAND)], 1).mean(1)
+ Hh = {int(v): [BASE_D + x for x in input_neurons(int(vocA[v]), CM_W, CM_D)] for v in np.unique(np.concatenate([a, b]))}
+ Sh = np.zeros((V, CM_D), np.int64)
+ for v, row in Hh.items(): Sh[v] = row
+ Ra, Rb = dedup(Sh[a], 1), dedup(Sh[b], 1000); oh = (Ra[:, :, None] == Rb[:, None, :]).sum((1, 2)) / CM_D
+ d1, d2 = oc - orr, oc - oh
+ res["proxies_secondary"][kind] = {"n_pairs": len(pr), "examples": [[pb[x].decode("latin-1"), pb[y].decode("latin-1")] for x, y in pr[:8]],
+ "mean_overlap_close": float(oc.mean()), "mean_overlap_random_matched": float(orr.mean()), "mean_overlap_randomhash": float(oh.mean()),
+ "delta_vs_random": float(d1.mean()), "delta_vs_random_ci95": boot(d1), "delta_vs_hash": float(d2.mean()), "delta_vs_hash_ci95": boot(d2)}
+ log(f"proxy {kind}: {json.dumps(res['proxies_secondary'][kind])}")
+# ---- descriptif CIRCULAIRE (non décisionnel) : projection F (inclut B) sur les mêmes patches, si mêmes ids
+posF = np.searchsorted(zF["vocab_ids"], pidE); okF = (posF < V) & (zF["vocab_ids"][np.minimum(posF, V - 1)] == pidE) & zF["has_ctx"][np.minimum(posF, V - 1)]
+if okF.all():
+ oc = overlap(zF["sem"][posF], ci, cj, CM_D); orr = overlap(zF["sem"][posF], ri, rj, CM_D)
+ res["circular_descriptive_projF"] = {"mean_overlap_close": float(oc.mean()), "mean_overlap_random": float(orr.mean())}
+else:
+ res["circular_descriptive_projF"] = {"status": f"{int((~okF).sum())} patches de E absents/sans contexte dans vocab_F ; non calculé"}
+# ---- décision (règle pré-déclarée)
+pm = res.get("CM24_primary")
+if nE < MIN_ANCHORS or len(ci) < MIN_PAIRS or nA_ < MIN_ANCHORS:
+ verdict, why = "NON MESURABLE", f"données insuffisantes (E={nE}, ancres={nA_}, paires={len(ci)})"
+else:
+ c1 = pm["delta_vs_random_ci95"][0] > 0 and pm["delta_vs_random"] >= DELTA
+ c2 = pm["delta_vs_hash_ci95"][0] > 0 and pm["delta_vs_hash"] >= DELTA
+ verdict = "OUI" if (c1 and c2) else "NON"
+ why = f"vs aléatoire apparié: {'OK' if c1 else 'ÉCHEC'} ; vs hash aléatoire: {'OK' if c2 else 'ÉCHEC'} (δ={DELTA:.5f})"
+res["verdict_rule_output"] = {"verdict": verdict, "why": why}
+res["peak_rss_mb"] = peak_mb(); res["min_memavail_kb"] = PEAK["min_memavail_kb"]
+json.dump(res, open(OUTJ, "w"), indent=1, ensure_ascii=False); log(f"VERDICT {verdict} — {why}")
diff --git a/results/hashing/m7_sem/code/t_a3_unit.py b/results/hashing/m7_sem/code/t_a3_unit.py
new file mode 100644
index 0000000000000000000000000000000000000000..5cd93355d7ccf127d669ab1b586ad6e7c35eb66d
--- /dev/null
+++ b/results/hashing/m7_sem/code/t_a3_unit.py
@@ -0,0 +1,49 @@
+"""Amendement 3 : test unitaire ancien vs nouveau (overlap, boot, perm_p) à grande taille. Résultat attendu : identique bit à bit."""
+import numpy as np, json
+def dedup(R, neg0):
+ R = np.sort(R, 1).astype(np.int64); dup = np.zeros_like(R, bool); dup[:, 1:] = R[:, 1:] == R[:, :-1]
+ return np.where(dup, -(neg0 + np.arange(R.shape[1]))[None, :], R)
+def ov_old(R, a, b, k):
+ Ra, Rb = dedup(R[a], 1), dedup(R[b], 1000); out = np.empty(len(a))
+ for s in range(0, len(a), 50_000): out[s:s + 50_000] = (Ra[s:s + 50_000, :, None] == Rb[s:s + 50_000, None, :]).sum((1, 2)) / k
+ return out
+def ov_new(R, a, b, k):
+ out = np.empty(len(a))
+ for s in range(0, len(a), 20_000):
+ Ra, Rb = dedup(R[a[s:s + 20_000]], 1), dedup(R[b[s:s + 20_000]], 1000); out[s:s + 20_000] = (Ra[:, :, None] == Rb[:, None, :]).sum((1, 2)) / k
+ return out
+def boot_old(x, seed=0, B=2000):
+ r = np.random.default_rng(seed); n = len(x); out = np.empty(B)
+ for b0 in range(0, B, 500):
+ idx = r.integers(0, n, size=(min(500, B - b0), n)); out[b0:b0 + idx.shape[0]] = x[idx].mean(1)
+ return out
+def boot_new(x, seed=0, B=2000):
+ r = np.random.default_rng(seed); n = len(x); out = np.empty(B)
+ for b0 in range(0, B, 500):
+ nb = min(500, B - b0)
+ for t in range(0, nb, 25):
+ idx = r.integers(0, n, size=(min(25, nb - t), n)); out[b0 + t:b0 + t + idx.shape[0]] = x[idx].mean(1)
+ return out
+def perm_old(d, seed=1, N=2000):
+ r = np.random.default_rng(seed); obs = abs(d.mean()); cnt = 0
+ for b0 in range(0, N, 500):
+ s = r.choice([-1.0, 1.0], size=(min(500, N - b0), len(d))); cnt += int((np.abs((s * d).mean(1)) >= obs - 1e-15).sum())
+ return cnt
+def perm_new(d, seed=1, N=2000):
+ r = np.random.default_rng(seed); obs = abs(d.mean()); cnt = 0
+ for b0 in range(0, N, 500):
+ nb = min(500, N - b0)
+ for t in range(0, nb, 25):
+ s = r.choice([-1.0, 1.0], size=(min(25, nb - t), len(d))); cnt += int((np.abs((s * d).mean(1)) >= obs - 1e-15).sum())
+ return cnt
+g = np.random.default_rng(5); res = {}
+R = g.integers(1024, 1100, size=(3000, 24)); a = g.integers(0, 3000, 130_001); b = g.integers(0, 3000, 130_001)
+res["overlap_equal"] = bool(np.array_equal(ov_old(R, a, b, 24), ov_new(R, a, b, 24)))
+x = g.random(3001) - 0.45
+res["boot_equal"] = bool(np.array_equal(boot_old(x), boot_new(x)))
+res["perm_equal"] = perm_old(x) == perm_new(x); d0 = (g.random(3001) - 0.5) * 1e-3
+res["perm_equal_near_null"] = perm_old(d0) == perm_new(d0)
+for n in (16331, 4001, 57): # tailles réalistes (ancres complètes), B = N = 10 000 comme pré-déclaré
+ y = g.random(n) - 0.5; res[f"boot_equal_n{n}_B10000"] = bool(np.array_equal(boot_old(y, B=10_000), boot_new(y, B=10_000)))
+ res[f"perm_equal_n{n}_N10000"] = perm_old(y, N=10_000) == perm_new(y, N=10_000)
+print(json.dumps(res))
diff --git a/results/hashing/m7_sem/code/t_equiv.py b/results/hashing/m7_sem/code/t_equiv.py
new file mode 100644
index 0000000000000000000000000000000000000000..9daa6e5e5b17bf3430a369fcb11c076cb7289d7c
--- /dev/null
+++ b/results/hashing/m7_sem/code/t_equiv.py
@@ -0,0 +1,32 @@
+"""M7sem — test d'équivalence : pipeline bas-mémoire (s1..s5, préfixe NBYTES) == code de référence appelé tel quel
+(spira/ept.py EPT.fit/calibrate/segment, spira/hashing.fnv1a64, lignes vocab de SPIRA.build, PatchRegistry.build (octets = dernière occ.),
+SPIRA.cols_of (logique), semhash/countmin.cooc_ppmi_topk + minhash_rows, SPIRA._structured_row, repli CMSPIRA).
+usage : t_equiv.py PREFIX NBYTES"""
+import sys, json
+import numpy as np
+from common import *
+sys.path.insert(0, "/workspace/spira_shared/semhash")
+from countmin import cooc_ppmi_topk, minhash_rows
+from spira.ept import EPT
+from spira.hashing import fnv1a64
+from spira.model import SPIRA, SPIRAConfig, PatchRegistry
+P, NB = sys.argv[1], int(sys.argv[2]); start_guard()
+data = open(CORPUS, "rb").read(NB)
+ept = EPT(budget_bits=16.0, min_len=2, max_len=32, alpha=0.5); ept.fit(data[:2_000_000]); ept.calibrate(data[2_000_000:2_400_000], target_len=4.5)
+patches = ept.segment(data); ids = np.fromiter((fnv1a64(p) for p in patches), dtype=np.uint64, count=len(patches))
+uniq, cnt = np.unique(ids, return_counts=True); order = np.lexsort((uniq, -cnt))[:V]; vocab = np.sort(uniq[order]).astype(np.uint64)
+keep = set(vocab.tolist()) | set(uniq[cnt >= 2].tolist()); reg = PatchRegistry.build(ids, patches, keep=keep)
+pos = np.searchsorted(vocab, ids); pc = np.minimum(pos, V - 1); cols = np.where((pos < V) & (vocab[pc] == ids), pc, V).astype(np.int64)
+top = cooc_ppmi_topk(cols, V, WINDOW, TOPK); sem = minhash_rows(top, CM_D, CM_W, BASE_D)
+class _D: cfg = SPIRAConfig(vocab_size=V, d_in=BASE_D, k_in=BASE_K)
+base = np.stack([SPIRA._structured_row(_D, int(v), reg.bytes_of(int(v))) for v in vocab]).astype(np.int32)
+proj = np.concatenate([base, np.where(sem < 0, base[:, :1], sem)], axis=1).astype(np.int32)
+mine_ids = np.fromfile(P + ".ids.u64", dtype=np.uint64); mine_len = np.fromfile(P + ".lens.u8", dtype=np.uint8)
+z = np.load(P + ".proj_F.npz")
+chk = {"ids": bool(np.array_equal(ids, mine_ids)), "lens": bool(np.array_equal(np.array([len(p) for p in patches]), mine_len)),
+ "vocab": bool(np.array_equal(vocab, z["vocab_ids"])), "cols": bool(np.array_equal(cols, np.fromfile(P + ".colsF.u16", dtype=np.uint16).astype(np.int64))),
+ "top": bool(np.array_equal(top, z["top"])), "sem": bool(np.array_equal(sem, z["sem"])), "base": bool(np.array_equal(base, z["base"])),
+ "proj": bool(np.array_equal(proj, z["proj"])), "ref_proj_sha256": sha_arr(proj), "mine_proj_sha256": sha_arr(z["proj"]),
+ "budget_bits": ept.budget_bits, "n_patches": len(ids), "nbytes": NB, "peak_rss_mb": peak_mb()}
+chk["ALL_EQUAL"] = all(v for k, v in chk.items() if isinstance(v, bool))
+json.dump(chk, open(P + ".equiv.json", "w"), indent=1); log("EQUIV " + json.dumps(chk))
diff --git a/results/hashing/m7_sem/code/t_split.py b/results/hashing/m7_sem/code/t_split.py
new file mode 100644
index 0000000000000000000000000000000000000000..d51ee5a6bb33ebe6e34faea77a35f4a270f28af7
--- /dev/null
+++ b/results/hashing/m7_sem/code/t_split.py
@@ -0,0 +1,20 @@
+"""M7sem — test du découpage A/B : topA/sem_A du pipeline == countmin.cooc_ppmi_topk sur colonnes vocab_A où les positions B sont
+masquées en UNK (=> toute paire touchant B exclue), vocab_A recalculé (lignes SPIRA.build) sur les seuls ids de A.
+Vérifie aussi ids (ch différent) contre la référence EPT du repo. usage : t_split.py PREFIX NBYTES"""
+import sys, json
+import numpy as np
+from common import *
+sys.path.insert(0, "/workspace/spira_shared/semhash")
+from countmin import cooc_ppmi_topk, minhash_rows
+P, NB = sys.argv[1], int(sys.argv[2]); start_guard()
+ids = np.fromfile(P + ".ids.u64", dtype=np.uint64); ln = np.fromfile(P + ".lens.u8", dtype=np.uint8).astype(np.int64)
+st = np.concatenate([[0], np.cumsum(ln)[:-1]]); part = (st // SPLIT_BLOCK) & 1
+u, c = np.unique(ids[part == 0], return_counts=True); o = np.lexsort((u, -c))[:V]; vA = np.sort(u[o]).astype(np.uint64); del u, c
+pos = np.searchsorted(vA, ids); pc = np.minimum(pos, V - 1); cols = np.where((pos < V) & (vA[pc] == ids), pc, V).astype(np.int64)
+cols[part == 1] = V
+top = cooc_ppmi_topk(cols, V, WINDOW, TOPK); sem = minhash_rows(top, CM_D, CM_W, BASE_D)
+z = np.load(P + ".proj_A.npz"); seg = json.load(open(P + ".seg.json"))
+chk = {"nA": int((part == 0).sum()), "nB": int((part == 1).sum()), "vocab_A": bool(np.array_equal(vA, z["vocab_ids"])),
+ "topA": bool(np.array_equal(top, z["top"])), "semA": bool(np.array_equal(sem, z["sem"])), "seg_ch": seg["ch"], "ids_sha256": seg["ids_sha256"], "peak_rss_mb": peak_mb()}
+chk["ALL_EQUAL"] = chk["vocab_A"] and chk["topA"] and chk["semA"]
+json.dump(chk, open(P + ".split_equiv.json", "w"), indent=1); log("SPLIT " + json.dumps(chk))
diff --git a/results/hashing/m7_sem/spira_m7_retrain_plan.md b/results/hashing/m7_sem/spira_m7_retrain_plan.md
new file mode 100644
index 0000000000000000000000000000000000000000..cdf8f7db69235b2ff43ff446c6660b60b8ce2564
--- /dev/null
+++ b/results/hashing/m7_sem/spira_m7_retrain_plan.md
@@ -0,0 +1,188 @@
+# BROUILLON de pré-déclaration — réentraînement SPIRA avec la projection figée M7sem (proj_F) — SPIRA Hashing
+Rédigé le 2026-10-24 vers 21 h 15 (Toronto). **BROUILLON, NON GELÉ.** Rien n'est lancé, rien n'est armé, aucun script de bras ni de verdict n'est écrit.
+Le gel demande trois choses : les réponses de Philippe-Antoine aux questions du §10, un PASS d'audit écrit de Checker, puis un PREDECL définitif
+qui portera le sha des scripts.
+
+## 0. Base
+- Hypothèse validée : M7sem **OUI** (verdict_M7sem.json 85da7cc7… ; sha du .md dans SHA256SUMS_verdict). Recompte indépendant Checker du 24 oct.
+ à 21 h 08 (spira_relay.md l. ~10394) : « validé par Checker ». Sur le bloc CM24 : Δ_rand 0,1071 [0,1055 ; 0,1088] et Δ_hash 0,1075 [0,1058 ; 0,1092].
+- Projection livrée : **m7_sem/work/full.proj_F.npz, sha256 942ad88a387cbae4e22685956fdd7d8006da643b4dba659b23fca1d1b87ac94b**.
+ Elle est déterministe : 2 constructions donnent le même sha. Lignes : 6f465916…. Elle contient vocab_ids (16 384 ids FNV-1a 64, sur le vocabulaire
+ du corpus ENTIER), base (12 neurones), sem (24 neurones dans [1024, 5120)), proj (36), top et has_ctx (16 384/16 384).
+- Ce que M7sem démontre : les patches proches au sens distributionnel partagent des neurones d'entrée.
+ Ce que M7sem ne démontre pas : que le modèle prédit mieux. Le présent réentraînement sert à tester ce second point.
+
+## 1. Pipeline de référence repris tel quel (M8 v1b, m8_v1b/PREDECL.md §1–§5, §10)
+- Données : m8_v1b/sample/v1b_sample.bin (35 128 951 o, sha 9ea562e4…370b), échantillon entrelacé de corpus_v1b/train.bin.
+- EPT : fit sur l'échantillon [0, 2 000 000), calibration [2 000 000, 2 400 000), budget mesuré 16,04 bits. Segmentation de tout l'échantillon
+ (7 739 248 patches), vocabulaire top-16 384 et registre (count ≥ 2).
+- SNN : 600 000 ticks par époque, 2 époques (1 tick = 1 token, spiking.py l. 471-539). AM : 1 200 000 patches. Calibration fusion sur [0, 60 000).
+- Config : SPIRAConfig(vocab_size=16384, d_in=1024, snn_tokens=600000, am_tokens=1200000, epochs=2), seed modèle 20261022 (repo 6923c519),
+ maxpos 4000 par fenêtre.
+- Script de bras : m8_v1b/code/train_m8v1b.py (b2b12c8c…9e3c). Classe CMSPIRA de countmin.py (caab5040…). Éval par eval_hits verbatim
+ (checker/eval_ref_v3.py e2c8cd1d…) ; fc2 via windows_v2.py (7d9ed224…).
+- Bras cm M8 v1b : d_in 1024+4096 = 5120, k_in 12+24 = 36, n_state 6656. Le bloc CM vient de cooc_ppmi_topk sur les colonnes du MODÈLE
+ (échantillon de 35 Mo), puis minhash_rows.
+
+## 2. Bras
+| bras | rôle | bloc CM [1024, 5120), 24 neurones | d_in / k_in / n_state | coût |
+|---|---|---|---|---|
+| **pF** | TRAITÉ | ligne `sem` de proj_F, cherchée par **id de patch** (FNV-1a 64 des octets) ; id absent de proj_F ou sans contexte → repli base[0] (comme CMSPIRA) | 5120 / 36 / 6656 | nouveau run |
+| **rh** | CONTRÔLE PRIMAIRE | **mêmes patches couverts que pF**, avec 1024 + input_neurons(id, 4096, 24) (hash aléatoire pur du repo, même témoin nul que M7sem) ; mêmes replis que pF | 5120 / 36 / 6656 | nouveau run |
+| cm | CONTRÔLE SECONDAIRE (bras existant) | M8 v1b cm (co-occurrences sur l'échantillon de 35 Mo), réutilisé tel quel si l'essai 3 (PID 925745) finit en code 0 | 5120 / 36 / 6656 | 0 (déjà en cours) |
+| ctl | descriptif seulement | sans bloc CM | 1024 / 12 / 2560 | 0 (fait, essai 1) |
+
+### Diff prévu (train_m7r.py = copie de train_m8v1b.py, seuls changements listés)
+1. `--arm` accepte en plus `pf` et `rh` ; `cm` et `ctl` restent identiques octet pour octet dans leur chemin.
+2. pf et rh : `m = CMSPIRA.build_cm(data, cfg, …)` comme cm, puis **avant `m.prepare()`** :
+ `m.cm_sem[col] = S[col]` pour col < V, où, pour pid = id de la colonne col du modèle :
+ - pf : S[col] = proj_F.sem[i] si pid = proj_F.vocab_ids[i] et proj_F.has_ctx[i], sinon -1 (repli base[0] par CMSPIRA._structured_row, code inchangé) ;
+ - rh : S[col] = 1024 + input_neurons(pid, 4096, 24) sur le **même ensemble** de colonnes couvertes que pf, sinon -1 ;
+ - ensuite `m._row_cache = {}`.
+ Le calcul cooc_ppmi_topk de l'échantillon reste exécuté puis écrasé, ce qui garde le flux de code identique à cm.
+3. Garde : proj_F.npz est vérifié par sha (942ad88a…) au chargement, sinon rc 2. Le json de sortie journalise coverage_cols (colonnes couvertes / 16 384),
+ coverage_tokens_snn (tokens SNN couverts / 600 000), coverage_tokens_am, sha de cm_sem et sha de la table S.
+4. Contrôle d'égalité : pour les ids communs, base calculée par le modèle == proj_F.base (même SPIRA._structured_row). Sinon arrêt (rc 2).
+5. `meta` inclut le nom du bras et le sha de S (clé de reprise distincte). runs dans m7_sem/retrain/runs/ (ctl et cm sont LUS dans m8_v1b/runs, jamais copiés ni modifiés).
+**Inchangé** : données, EPT, vocabulaire, registre, tokenisation (donc appariement par position possible avec cm et ctl), seeds, budgets, boucle
+d'entraînement (copie de SPIRA.train), points de reprise par époque, AM, calibration, sauvegarde, éval, fenêtres, maxpos.
+
+### Pourquoi rh est le contrôle primaire
+- La question honnête « le hachage sémantique aide-t-il ? » doit fixer la capacité et ne changer que le contenu. À d_in, k_in, n_state et
+ couverture égaux, pF et rh ne diffèrent **que** par le choix des 24 neurones : sémantique (proj_F) ou aléatoire (hash).
+- pF contre ctl confond sémantique et capacité (6656 contre 2560 états, 36 contre 12 neurones actifs). Ce n'est donc pas un test du hachage
+ sémantique. En plus, la fusion.scale de ctl vaut **0,02818, hors de [0,03 ; 0,11]** (results.jsonl M8 v1b), donc toute comparaison contre ctl
+ serait NON MESURABLE par la règle r3B.
+- pF contre cm répond à une autre question : la projection co-occurrence « grande échelle » (corpus entier, 520 Mo, figée) fait-elle mieux que le
+ CM existant, lui aussi construit par co-occurrences mais sur 35 Mo et sur le vocabulaire du modèle ? **Les deux sont des CM à co-occurrences** :
+ cm contre pF ne teste donc pas « sémantique ou non », mais l'échelle et la provenance de la projection. Cette comparaison décide de
+ l'adoption de proj_F à la place du bras cm.
+- pF contre cm a un biais connu : la couverture de pF est partielle (vocabulaires différents, §4), alors que cm couvre ses 16 384 colonnes.
+ rh n'a pas ce biais.
+
+## 3. Règle de décision (copie de r3B, verdict_M8v1b.py b3db0875…7dc7, plus Holm sur 2 comparaisons)
+Script prévu : verdict_M7r.py = verdict_M8v1b.py (b3db0875…) avec RT et CT en paramètres (--ref, --cand) et un bloc Holm final. **Calculs par fenêtre inchangés** :
+- positions in-vocab dans les DEUX bras, taux appariés (même dénominateur), appariement par position (tgt_start/tgt_len identiques, sinon assert) ;
+- McNemar exact bilatéral (binp) ; bootstrap apparié par blocs de 512 o, B = 10 000, seed 0 ;
+- test20k strict (masque mask_oldtest_strict.npz 50fa08f9…, old_local_v1 ∪ broad_local_v1, recul 64 o).
+**Fenêtres de la règle** :
+- seen = échantillon[:200 000], avec audit trained_frac ≥ 0,99 dans les deux bras ;
+- fc2, fresh_en, fresh_fr, test20k strict, test_v3. test_v3 compte seulement si propre : recompte échantillon = 0 ET recompte v1b = 0 ET drapeau GO.
+**Fenêtres propres seulement**, c'est-à-dire avec **0 position confirmée dans les DEUX recomptes** :
+- recompte de l'échantillon : sample/recount64_v1b_sample.json a307ccc7… ;
+- recompte v1b indépendant de Checker : checker/recount/v1b_dedup_1138/recount64_words.json 0107671a…, PASS.
+queries est rapportée à part, hors règle. **neither_code est exclue** (non évaluée). freshcode m7 et broad_local_v1/test sont exclues (contaminées).
+- Par comparaison (C1 = pF contre rh, primaire ; C2 = pF contre cm), selon r3B :
+ - gain significatif sur une fenêtre = McNemar p < 0,05 ET c > b ET IC95 bootstrap > 0 ;
+ - perte significative = McNemar p < 0,05 ET b > c, sur seen ou sur une fenêtre fraîche valide ; une égalité sur seen saturé est admise ;
+ - ADOPTÉ_k ssi au moins un gain significatif sur une fenêtre fraîche valide ET aucune perte significative, seen compris ; sinon REJETÉ_k.
+- **Holm** (famille de 2 comparaisons, α = 0,05) : p_k = plus petit p McNemar parmi les fenêtres fraîches valides où c > b et IC95 > 0.
+ On trie p_(1) ≤ p_(2) : la première comparaison garde son gain si p_(1) ≤ 0,025, la seconde si de plus p_(2) ≤ 0,05 (procédure descendante).
+ Un gain qui ne passe pas Holm est traité comme « pas de gain ». Les pertes restent testées à p < 0,05 **sans** correction, ce qui est plus strict pour l'adoption.
+- **Décision finale** : **proj_F ADOPTÉ** pour le réentraînement ssi C1 et C2 sont ADOPTÉ après Holm. Si C1 est ADOPTÉ mais pas C2 : « hachage
+ sémantique utile, mais proj_F ne bat pas le CM existant » → pas d'adoption, rapporté tel quel. Si C2 est ADOPTÉ mais pas C1 : l'effet n'est
+ pas attribuable à la sémantique → pas d'adoption.
+- **NON MESURABLE** (par comparaison, puis global si C1 l'est) :
+ - budgets inégaux (snn_tokens, am_tokens, epochs, ticks/époque, sha des données) ;
+ - passe SNN incomplète (ticks × 1 ≠ snn_tokens) ;
+ - seen non comparable (trained_frac < 0,99) ;
+ - **fusion.scale d'un bras hors [0,03 ; 0,11]** ou illisible. La plage reste PROVISOIRE et codée en dur ; toute sortie de plage est rapportée avec sa valeur ;
+ - tokenisation différente (assert) ;
+ - sha de proj_F ≠ 942ad88a… ;
+ - couverture pF sous le seuil pré-déclaré du §4 ;
+ - bras cm absent (essai 3 en échec), ce qui rend seulement C2 NON MESURABLE : la décision se lit alors sur C1 seule, sans adoption possible (cf. §10).
+- Descriptifs non décisionnels : pF contre ctl et rh contre cm (tables complètes), écart seen − frais (gapcalc r3B), couverture par fenêtre
+ (positions dont la cible est couverte par proj_F), et précision sur positions couvertes ou non couvertes.
+
+## 4. Points critiques connus (honnêteté)
+1. **Vocabulaires différents.** proj_F vient de l'EPT fit sur corpus_v1b/train.bin[:2 M] (budget 12,905 bits, vocabulaire du
+ corpus entier). Le modèle M8 v1b fit son EPT sur l'échantillon[:2 M] (budget 16,04 bits). Les deux segmentations diffèrent, et seuls les
+ patches dont les octets coïncident sont couverts (correspondance par id FNV-1a des octets). **La couverture n'est pas mesurée** (aucun calcul fait ici).
+ Étape légère pré-lancement (< 300 Mo, segmentation en flux, sans SNN) : colonnes couvertes, tokens SNN et AM couverts, couverture par fenêtre.
+ Seuil proposé, à trancher : NON MESURABLE si coverage_tokens_snn < 0,50.
+ Alternative (option B, §10) : pF et rh avec l'EPT et le vocabulaire de proj_F. La tokenisation serait identique entre eux, mais cm et ctl ne
+ seraient plus réutilisables : pas de C2 sans un nouveau bras cm, soit environ 12 h de plus.
+2. **Fuite d'éval par proj_F** (proj_F est construite sur le corpus ENTIER, A+B, de corpus_v1b/train.bin, 520 785 883 o, ddf67ffb…), vérifiée sur
+ fichiers existants uniquement :
+ - manifest_corpus_diverse_v1b.json (cb6398ca…), bloc overlap64_recount_v1b (recount64.py, confirmé octet par octet) : confirmed_window_positions = 0
+ ET confirmed_train_positions = 0 pour fc2 (b052096b), m7_fresh_en (67ff20b2), m7_fresh_fr (875f0906), m7_test20k (ce0526c6),
+ corpus_v3_test = test_v3 (a6730bbe) et m7_queries (5aab38d6) ;
+ - recompte INDÉPENDANT de Checker (checker/recount/v1b_dedup_1138/recount64_words.json 0107671a…, PASS = true, autre algorithme) :
+ 0 / 0 / 0 sur fc2, fresh_en, fresh_fr, test20k, test_v3 et queries ;
+ - contaminées, donc exclues comme avant : neither_code (224 171 positions), freshcode m7 (163 445) et broad_local_v1/test (32 344 ; témoin seulement) ;
+ - seen = échantillon[:200 000] ⊂ train par construction (c'est le cas pour tous les bras) ;
+ - **Réserve** : le critère est l'absence de 64-grammes communs. Des chaînes communes plus courtes que 64 o restent possibles. C'est le critère
+ de tous les verdicts précédents, mais proj_F, contrairement à cm, a vu tout train.bin (15 fois plus d'octets) : c'est un avantage de données déclaré.
+3. **Avantage de données de pF sur cm et rh** : les co-occurrences de proj_F viennent de 520 Mo contre 35 Mo. C'est voulu, puisque c'est
+ l'objet de C2, mais il faut le déclarer. rh n'utilise aucune donnée.
+4. fusion.scale : ctl réel vaut 0,02818, hors plage ; celle de cm n'est pas encore connue. Risque réel de NON MESURABLE pour pF et rh aussi.
+5. Les essais cm 1 et 2 se sont terminés en code 143 (17 h 29 et 21 h 05). L'essai 3 est le dernier autorisé par la porte (≤ 3). S'il échoue, C2 tombe.
+6. Pas de reprise intra-époque : une interruption fait perdre jusqu'à environ 5,5 h d'époque.
+
+## 5. Tests avant lancement (dans l'ordre ; seul le 1 est léger)
+1. Couverture (léger, < 300 Mo) : segmentation en flux de l'échantillon avec l'EPT du modèle (même fit), puis correspondance avec proj_F.vocab_ids.
+ Sortie : coverage.json avec sha.
+2. Équivalence (lourd, environ 1,3 Go, derrière la porte) : train_m7r.py --arm pf avec S := cm_sem de l'échantillon doit reproduire --arm cm
+ **bit à bit** sur le préfixe smoke/equiv (3 Mo, snn 1500, am 20 000, 2 époques ; empreintes W_rec/W_out/W_outG/AM/historique).
+ Plus un test rh/pf : table S différente ⇒ seules les lignes couvertes diffèrent.
+3. Smoke vtest2 (lourd, budget complet mais petit : snn 3000, am 1,2 M, 1 époque, --no-save) : verdict_M7r.py doit être mesurable et Holm calculé.
+ Non décisionnel.
+4. Audit Checker écrit du script de verdict figé (sha), puis drapeau m7_sem/retrain/GO_CHECKER_PASS posé à la main par Hashing.
+
+## 6. Ressources (mesures M8 v1b, pas d'estimation nouvelle)
+- Bras CM (pF et rh sont identiques à cm en taille) :
+ - smoke cm : 26,0 t/s, RSS SNN plat ≈ 952 Mo, pic ru_maxrss 2 040,6 Mio (≈ 2,14 Go) à la sauvegarde ;
+ - essai 2 réel : 30 t/s, RSS 946 840 kB à 340 000 ticks ;
+ - durée : 1,2 M ticks / 26–30 t/s = 11,1–12,8 h, plus environ 25 min de build/AM/calibration/sauvegarde/éval ⇒ **≈ 11,5–13,3 h par bras** ;
+ - le chargement de proj_F (16 384 × 36 int) est négligeable.
+- ctl (descriptif, déjà fait) : 83 t/s, 14 791 s (4,1 h), pic 1 192,8 Mo.
+- Porte : celle de gate_m8v1b.sh (d8287108…) adaptée par paramètres, logique inchangée :
+ - MemAvailable ≥ max(5,2 Go ; 4,4 GiB + pic du bras (2,5 Go) + marge du bras en cours) ;
+ - ≤ 4 lourds sur la machine (python RSS ≥ 500 Mo) ;
+ - 4 Go toujours libres (chien de garde 4,4 GiB de run_guarded.sh, qui n'agit que sur son propre groupe) ;
+ - nice 10, OMP_NUM_THREADS=1, PYTHONHASHSEED=0, setsid ; TMPDIR dans m7_sem/retrain/tmp ; rien sous /tmp ; aucune commande kill.
+- Disque : ctl.npz mesure 197 927 122 o ; un bras CM (n_state 6656) sera plus gros, taille non mesurée (cm pas encore sauvé). Plus environ 11 ko par npz d'éval.
+
+## 7. Ordre proposé (RIEN ne démarre pendant le cm M8 v1b essai 3, PID 925745)
+1. cm M8 v1b essai 3 (démarré à 21 h 06 ; ETA ≈ dim. 08 h 40–10 h 20 Toronto), puis verdict r3B par la porte 218845.
+2. Chaîne cov b r3 784212 : test A/R/chain sur la tranche de 3 Mo, puis arrêt en WAIT_CHECKER_AUDIT. Durée non estimée ici. Pas de relance
+ automatique (GO_COVB_R3_LAUNCH est manuel).
+3. M8cp1 (waiter 882549, puis gate_m8cp1.sh) : ctl ≈ 4,3–4,8 h et cm ≈ 13,3 h (estimations v1b), soit 13,3 h en parallèle ou environ 18 h en séquentiel.
+4. **M7r** : test 1 (léger) dès maintenant possible si Philippe-Antoine l'autorise (< 300 Mo), sinon après l'étape 1. Tests 2–3 après l'étape 3,
+ puis pF et rh, **en parallèle si la porte le permet** (2 × 2,5 Go + 4,4 GiB ≈ 9,7 Go libres), sinon pF puis rh.
+- ETA indicatives (Toronto, si chaque étape démarre dès la libération et sans échec) :
+ - fin de M8cp1 ≈ dim. 23 h 00 – lun. 05 h 00 ;
+ - pF ∥ rh ≈ lun. 12 h 00–19 h 00 ;
+ - en séquentiel ≈ mar. 00 h 00–08 h 00 ;
+ - verdict environ 10 min après.
+ Si la relance cov b r3 (environ 9 Go de porte) passe avant, tout est décalé d'autant.
+- Remarque : les deux attentes (882549, 784212) visent le PID 666012 (essai 2, terminé) puis la porte 218845. L'essai 3 est donc couvert
+ par l'attente de 218845, qui reste vivante tant que cm tourne. Je n'ai rien modifié.
+
+## 8. Ce qui est réutilisé
+- m8_v1b/runs : ctl.npz et ctl__*.npz, plus cm après l'essai 3 ; results.jsonl est LU, jamais écrit par M7r. Le verdict M7r lit deux dossiers runs
+ (m8_v1b/runs pour cm et ctl, m7_sem/retrain/runs pour pf et rh) et vérifie data_sha, budgets et tokenisation entre dossiers.
+
+## 9. Livrables prévus
+m7_sem/retrain/ : PREDECL_M7r.md (gelé, sha), train_m7r.py, verdict_M7r.py (gelé), gate_m7r.sh, coverage.json, runs/, verdict/verdict_M7r.{md,json}.
+Aucun push HF sans ordre écrit.
+
+## 10. Questions ouvertes
+**Pour Philippe-Antoine**
+1. Comparaison principale : faut-il C1 (pF contre rh, « la sémantique aide-t-elle à capacité égale ») ET C2 (pF contre cm) pour adopter, comme proposé, ou C2 seule ?
+2. Vocabulaires : option A (proposée : EPT et vocabulaire du modèle, proj_F cherchée par id ; cm et ctl réutilisés) ou option B
+ (EPT et vocabulaire de proj_F pour pF et rh ; nouveau bras cm à budget égal, environ 12 h de plus) ? Seuil de couverture : 0,50 des tokens SNN ?
+3. Plage fusion.scale [0,03 ; 0,11] : toujours provisoire. ctl est à 0,02818 (hors plage). La garde doit-elle rester « NON MESURABLE », ou être
+ tranchée avant ce run ?
+4. Priorité contre la relance cov b r3 et M8cp1 : M7r après M8cp1 (proposé), ou avant ? pF ∥ rh autorisés si la porte le permet ?
+5. Autorisez-vous le test léger de couverture (§5.1, < 300 Mo) pendant l'essai 3 du cm ?
+6. Si l'essai 3 du cm échoue : faut-il relancer un bras cm hors limite de 3 essais, ou décider sur C1 seule (sans adoption) ?
+
+**Pour l'audit Checker**
+1. Diff train_m7r.py contre train_m8v1b.py : remplacement de cm_sem avant prepare() ; vérifier qu'aucune ligne n'est mise en cache avant (_row_cache vidé).
+2. Équité rh/pF : même ensemble couvert, même repli ; input_neurons peut-il produire des doublons (dédoublonnage identique pour les deux bras) ?
+3. Holm sur p_k = min p des fenêtres fraîches gagnantes : définition correcte, ou faut-il Holm sur toutes les fenêtres × comparaisons ?
+4. Lecture croisée de deux dossiers runs : contrôles data_sha, budgets et tokenisation suffisants ?
+5. Fuite : le critère « 0 position en 64 o dans les deux recomptes » suffit-il, sachant que proj_F a vu tout train.bin ? Faut-il un recompte plus court (32 o) ?
+6. Recomptage de la couverture (§5.1) par un script Checker indépendant ?
+— SPIRA Hashing (brouillon, non gelé)
diff --git a/results/hashing/m7_sem/spira_m7_retrain_plan.md.sha256 b/results/hashing/m7_sem/spira_m7_retrain_plan.md.sha256
new file mode 100644
index 0000000000000000000000000000000000000000..cb7d20a0adf77670c63f6b03f2f408a0297fae4d
--- /dev/null
+++ b/results/hashing/m7_sem/spira_m7_retrain_plan.md.sha256
@@ -0,0 +1 @@
+47c087ccce89044a461df308dde4f00ea72286ee11134e43089ef8c61663c913 spira_m7_retrain_plan.md
diff --git a/results/hashing/m7_sem/spira_m7_retrain_plan_v2.md b/results/hashing/m7_sem/spira_m7_retrain_plan_v2.md
new file mode 100644
index 0000000000000000000000000000000000000000..a09c1b8b9aa2ad482245668516368cbbe59f7885
--- /dev/null
+++ b/results/hashing/m7_sem/spira_m7_retrain_plan_v2.md
@@ -0,0 +1,271 @@
+# BROUILLON v2 de pré-déclaration — réentraînement SPIRA avec la projection figée M7sem (proj_F) — SPIRA Hashing
+Rédigé le 2026-10-24 vers 21 h 45 (Toronto). Il remplace le brouillon v1 (spira_m7_retrain_plan.md, 47c087cc…, conservé intact).
+Il répond à l'audit Checker FAIL (checker/recount/m7r_plan_audit/AUDIT_M7r_plan.md, fe684750…) et à la demande Relay de 21 h 43.
+Réponses point par point : AUDIT_RESPONSE_v2.md.
+**BROUILLON, NON GELÉ. Rien n'est lancé ni armé, et aucun script de bras ou de verdict n'est écrit.**
+Les points marqués **[EN ATTENTE — oui de Philippe-Antoine]** sont des propositions : rien n'est figé sur ces points.
+
+## 0. Base
+- M7sem **OUI**, validé par Checker le 24 oct. à 21 h 08 (spira_relay.md l. ~10394). verdict_M7sem.json : 85da7cc7….
+ Bloc CM24 : Δ_rand 0,1071 [0,1055 ; 0,1088], Δ_hash 0,1075 [0,1058 ; 0,1092].
+- Projection : **m7_sem/work/full.proj_F.npz, sha256 942ad88a387cbae4e22685956fdd7d8006da643b4dba659b23fca1d1b87ac94b**.
+ Elle est déterministe (2 constructions identiques). Contenu : vocab_ids (16 384 ids FNV-1a 64), base (12), sem (24, dans [1024, 5120)), has_ctx.
+- M7sem montre seulement que des patches proches partagent des neurones. Le réentraînement teste si cela améliore la prédiction.
+
+## 1. Pipeline de référence repris tel quel (M8 v1b, m8_v1b/PREDECL.md §1–§5, §10)
+- **Données.** m8_v1b/sample/v1b_sample.bin : 35 128 951 o, sha 9ea562e4…370b.
+- **EPT.** Fit sur l'échantillon [0, 2 M), calibration sur [2 M, 2,4 M), budget 16,04 bits. 7 739 248 patches, vocabulaire top-16 384, registre count ≥ 2.
+- **Budgets.** SNN : 600 000 ticks/époque × 2 époques. AM : 1 200 000 patches. Calibration fusion sur [0, 60 000).
+- **Config.** SPIRAConfig(vocab_size=16384, d_in=1024, snn_tokens=600000, am_tokens=1200000, epochs=2), seed 20261022, maxpos 4000. Repo HEAD 6923c519.
+- **Code et sha.**
+
+ | fichier | sha256 |
+ |---|---|
+ | train_m8v1b.py | b2b12c8c…9e3c |
+ | countmin.py | caab50405e73eba7981f73a63fb1709139aed55383501c3e830e174cb02b8d3b |
+ | eval_ref_v3.py (verbatim) | e2c8cd1deabc228faed302bebdb81bf8d10405df63e393b4a8ddb6152401c10e |
+ | windows_v2.py | 7d9ed224… |
+ | spira/hashing.py | f26903e19cd92963e84d6271fc296d4998c4b364ce28be712241236391c2ab02 |
+
+- **Bras cm M8 v1b.** d_in 5120, k_in 36, n_state 6656. Ligne = base12 (SPIRA._structured_row, d_in 1024, k 12 = 6 hash entiers + 6 trigrammes) + 24 MinHash.
+
+## 2. Bras
+| bras | rôle | bloc CM [1024, 5120), 24 positions | d_in / k_in / n_state | coût |
+|---|---|---|---|---|
+| **pF** | TRAITÉ | S_pF[col] = proj_F.sem[i], où pid(col) = proj_F.vocab_ids[i] et has_ctx[i] ; sinon -1 | 5120 / 36 / 6656 | nouveau run |
+| **rh** | CONTRÔLE PRIMAIRE | S_rh[col] = hash aléatoire figé (§2.2) sur **exactement** les colonnes où S_pF ≠ -1 ; sinon -1 | 5120 / 36 / 6656 | nouveau run |
+| cm | CONTRÔLE SECONDAIRE (existant) | M8 v1b cm, réutilisé si l'essai 3 (PID 925745) finit en code 0 | 5120 / 36 / 6656 | 0 |
+| ctl | descriptif seulement | sans bloc CM | 1024 / 12 / 2560 | 0 |
+
+### 2.1 Règle unique de doublons et de repli, identique pour pF, rh et cm (point 1 de l'audit)
+- Le code mesuré : SpikingCore.step fait `I = W_in[input_idx].sum(axis=0)`. **Les doublons ne sont pas dédoublonnés : ils sont sommés**
+ (un neurone répété deux fois reçoit deux fois son poids).
+- CMSPIRA._structured_row (countmin.py caab5040…) remplace chaque -1 par base[0]. Une colonne sans ligne sémantique répète donc base[0]
+ 24 fois. C'est la convention du bras cm.
+- **Règle figée pour pF et rh (et inchangée pour cm) : aucun dédoublonnage, doublons sommés, -1 → base[0], code CMSPIRA._structured_row inchangé.**
+ - Raison : c'est la convention exacte de cm, ce qui permet la comparaison C2 et le test d'équivalence bit à bit pF(S := cm_sem) == cm (§5.2).
+ - Dédoublonner pour pF/rh seulement casserait cette identité. Dédoublonner pour les trois demanderait un nouveau bras cm.
+- Pour rh, P(au moins un doublon parmi 24 tirages uniformes dans 4096) = 1 − ∏_{i<24}(1 − i/4096) = 0,0653 (calcul exact). Pour pF (MinHash
+ à 24 sels), le taux n'est pas mesuré.
+- **Contrôle figé.** Le json de sortie journalise, pour chaque bras et sur les colonnes couvertes, la distribution du nombre de neurones
+ distincts du bloc (moyenne, min, histogramme) et le nombre de colonnes en repli.
+- **Garde.** Le nombre de colonnes en repli doit être identique pour pF et rh (même ensemble), sinon rc 2. L'écart de neurones distincts
+ moyens pF − rh est rapporté, sans valeur décisionnelle.
+- **Alternative** (24 neurones distincts garantis, par extension de sel, pour pF ET rh) : possible si Checker ou l'utilisateur l'exige.
+ Elle demanderait alors aussi un bras cm dédoublonné.
+
+### 2.2 rh : fonction de hachage et graine figées (point 2)
+- **Écart trouvé en relisant le code.** La v1 proposait `1024 + input_neurons(pid, 4096, 24)`. Or input_neurons utilise les sels
+ `0x51ED270B733D4C31 + j·0x9E3779B97F4A7C15`, ce sont les MÊMES que la partie « hash entier » de base12 (input_neurons(pid, 1024, 6)).
+ Comme 4096 est un multiple de 1024, on aurait (rh_j − 1024) mod 1024 == base_j pour j < 6 : le bloc rh serait corrélé à base. **Retiré.**
+- **Formule figée** (splitmix64 de spira/hashing.py f26903e1…, M64 = 2^64 − 1, RH_SEED = 0x52485F4D37520001) :
+ S_rh[col, j] = 1024 + ((splitmix64((pid ^ RH_SEED ^ ((j · 0x9E3779B97F4A7C15) & M64)) & M64) >> 32) mod 4096), j = 0..23.
+ Elle s'applique pour col ∈ couvert(pF) ; sinon S_rh[col, j] = -1.
+- **Sha des tables S_pF et S_rh (int32, forme 16 384 × 24, C-order) : À FIGER DANS LE PREDECL.**
+ - Leur calcul demande l'id des colonnes du modèle (vocabulaire de l'échantillon). Aucun fichier existant ne le fournit sans charger un
+ checkpoint M8 v1b ou resegmenter l'échantillon, et ce calcul est en pratique le test de couverture §5.1, soumis au point 10.
+ - Il n'a donc pas été fait. Méthode de calcul figée : sha256 des octets de `S.astype(' « **ADOPTÉ** ssi gain significatif (McNemar exact p < 0,05 ET c > b ET IC95 bootstrap > 0) sur ≥ 1 fenêtre fraîche valide (fc2, fresh_en,
+> fresh_fr, test20k strict, test_v3 si propre), ET aucune perte significative (p < 0,05 ET b > c) sur une fenêtre valide (seen + fraîches
+> valides ; une égalité sur seen saturé est admise). Le gain sur seen n'est plus exigé. Sinon **REJETÉ**. »
+
+### 3.2 Définitions (identiques à verdict_M8v1b.py l. 76–88)
+- Positions retenues : cible in-vocab dans les DEUX bras, sous le masque de fenêtre. Appariement par position (tgt_start et tgt_len
+ identiques, sinon assert).
+- ha = fused_hit ∧ invocab pour le bras de **référence** ; hb = la même chose pour le bras **candidat** (pF).
+- **b = #{réf. juste ∧ cand. faux}** ; **c = #{réf. faux ∧ cand. juste}**.
+- **McNemar exact bilatéral** (pour les gains ET les pertes) : p = min(1, 2 · Σ_{i ≤ min(b, c)} C(b+c, i) / 2^{b+c}), fonction binp de r3B.
+- Bootstrap apparié par blocs de 512 o, B = 10 000, seed 0. test20k strict = masque 50fa08f9….
+- Gain significatif = p < 0,05 ET c > b ET IC95 bootstrap > 0. Perte significative = p < 0,05 ET b > c.
+
+### 3.3 Fenêtres (point 4 et point 6)
+- **Dans la règle :**
+ - seen = échantillon[:200 000], avec trained_frac ≥ 0,99 dans les deux bras ;
+ - fc2, fresh_en, fresh_fr, test20k strict ;
+ - test_v3, seulement si recompte échantillon = 0 ET recompte v1b = 0 ET présence de **m7_sem/retrain/GO_CHECKER_PASS**.
+ verdict_M7r.py lit CE drapeau et jamais m8_v1b/GO_CHECKER_PASS (point 5). Test unitaire : le drapeau M8 v1b seul ⇒ test_v3 exclue.
+- **Propreté** = 0 position en 64 o dans les DEUX recomptes : a307ccc7… (échantillon) et 0107671a… (Checker v1b, PASS).
+- **queries** : rapportée à part, **hors règle** : ni dans les gains, ni dans les pertes, ni dans Holm.
+- **Jamais évaluées par aucun bras, ni dans la règle ni en descriptif :** broad_local_v1/test, neither_code et freshcode m7.
+ - broad_local_v1/test ne sert que de témoin positif de recompte ; aucun npz d'éval n'est produit pour ces trois fenêtres.
+ - La liste `excluded` du json de verdict les nomme **toutes les trois**, avec leur raison (positions contaminées : 32 344 / 224 171 / 163 445).
+- **broad_gutenberg_v1 n'est pas utilisée.** Aucune fenêtre n'est ajoutée après le gel.
+
+### 3.4 Ajouts à la règle B **[DÉCISION UTILISATEUR — §11, D1]**
+Deux versions sont écrites. Le PREDECL gelé ne contiendra que celle que Philippe-Antoine aura choisie par écrit.
+- **Version B-pure.** Règle §3.1 appliquée à une seule comparaison, sans Holm. Il faut alors choisir laquelle : C2 = pF contre cm
+ (comme M8 v1b, candidat contre bras existant) ou C1 = pF contre rh.
+- **Version B+.**
+ - Règle §3.1 appliquée à C1 (pF contre rh) ET à C2 (pF contre cm).
+ - Holm à 2 comparaisons sur les gains, α = 0,05, avec deux définitions possibles du p de chaque comparaison :
+ - (i) p_k = min des p McNemar sur les fenêtres fraîches valides gagnantes. C'est fidèle à l'événement « ≥ 1 fenêtre » de la règle B,
+ mais ce minimum n'est pas lui-même corrigé pour le nombre de fenêtres (≤ 5) ;
+ - (ii) Holm sur l'ensemble fenêtres × comparaisons (≤ 10 tests), plus conservateur.
+ - Pertes : p < 0,05 sans correction, donc plus strict pour l'adoption.
+ - ADOPTÉ ssi C1 ET C2 sont ADOPTÉ.
+- Note factuelle : l'exigence « IC95 bootstrap > 0 » figure déjà dans le texte de la règle B approuvé à 13 h 00 (citation §3.1) ; ce
+ n'est pas un ajout de M7r. Elle est néanmoins soumise à confirmation, comme le demande l'audit.
+
+### 3.5 NON MESURABLE (par comparaison)
+- budgets inégaux (snn_tokens, am_tokens, epochs, ticks/époque, sha des données) ;
+- passe SNN incomplète ;
+- trained_frac < 0,99 ;
+- tokenisation différente ;
+- sha de proj_F, S_pF ou S_rh différent du gel ;
+- couverture sous le seuil (§4.1) ;
+- fusion.scale hors [0,03 ; 0,11] ou illisible (valeur rapportée ; statut des bornes : §11, D2) ;
+- sha de code différent entre runs (§3.6) ;
+- bras cm absent : C2 NON MESURABLE, donc **aucune adoption** dans la version B+.
+
+### 3.6 Lecture croisée de deux dossiers runs (point 14)
+results.jsonl de M8 v1b ne journalise pas les sha de code par run (clés présentes : data_sha256, ckpt_sha256, budgets, cal, n_state…).
+Pour C2, verdict_M7r.py vérifie :
+- data_sha256, budgets, n_state et tokenisation égaux ;
+- sha **actuel** de countmin.py (caab5040…), eval_ref_v3.py (e2c8cd1d…), windows_v2.py (7d9ed224…), train_m8v1b.py (b2b12c8c…) et
+ spira/hashing.py (f26903e1…) == sha déclarés dans m8_v1b/PREDECL.md == sha journalisés par les runs pF/rh ;
+- config : les champs SPIRAConfig de cm (lus depuis cm.npz) == ceux de pF/rh, hors d_in/k_in, qui sont égaux par construction.
+Toute inégalité rend C2 NON MESURABLE. Risque résiduel déclaré : le run cm lui-même ne journalise pas ses sha de code ; l'égalité repose
+sur le PREDECL M8 v1b gelé et sur l'invariance des fichiers.
+
+### 3.7 Descriptifs non décisionnels
+pF contre ctl, rh contre cm, écart seen − frais (gapcalc r3B), précision sur positions couvertes ou non, statistiques de doublons.
+
+## 4. Points critiques
+### 4.1 Couverture (point 3) **[EN ATTENTE — oui de Philippe-Antoine]**
+- Les vocabulaires de proj_F (EPT corpus entier, 12,905 bits) et du modèle (EPT échantillon, 16,04 bits) diffèrent. La couverture n'est pas mesurée.
+- **Seuil numérique proposé : NON MESURABLE si coverage_tokens_snn < 0,50** (fraction des 600 000 ticks SNN dont le patch a une ligne S_pF ≠ -1).
+ Ce n'est pas figé avant le oui écrit.
+- Le test de couverture (§5.1) tourne AVANT le gel ; seul le seuil conditionne la décision.
+- **Recompte indépendant par Checker** (script Checker, dans checker/ ; Hashing n'y touche pas). Un désaccord bloque le gel.
+- Option A ou B : §11, D4.
+
+### 4.2 Fuite d'éval par proj_F (proj_F a vu corpus_v1b/train.bin entier : 520 785 883 o, ddf67ffb…)
+- 0 position en 64 o contre TOUT train.bin pour fc2, fresh_en, fresh_fr, test20k, test_v3 et queries, dans les deux recomptes :
+ manifest_corpus_diverse_v1b.json (cb6398ca…) et Checker recount64_words.json (0107671a…, PASS). Fichiers existants seulement.
+- Fenêtres contaminées, jamais évaluées (§3.3) : neither_code, freshcode m7, broad_local_v1/test.
+- **Recompte en 32 o (point 15), optionnel et descriptif, NON lancé maintenant** : fenêtres fraîches contre train.bin. Le résultat est
+ rapporté sans changer la règle. Il serait lancé seulement avec l'accord de l'utilisateur, après 925745, sous la porte.
+- Avantage de données déclaré : 520 Mo pour proj_F contre 35 Mo pour cm ; aucune donnée pour rh.
+
+### 4.3 Exclusions explicites (point 13)
+- Aucune variante de décodage n'est testée (température, top-k, n-best, re-ranking) : l'éval est eval_hits verbatim.
+- Aucun levier déjà rejeté n'est réutilisé : ni SP1, ni SP2, ni AH1, ni AH2.
+- mask_oldtest_strict.npz (dossier lever2/verdict_AH1/, 50fa08f9…) est **seulement un masque de propreté** pour test20k strict ; ce n'est pas le levier AH1.
+
+### 4.4 Autres risques
+- ctl a scale = 0,02818, hors plage ; la scale de cm n'est pas encore connue ; pF et rh risquent aussi un NON MESURABLE.
+- Les essais cm 1 et 2 ont fini en code 143. L'essai 3 est le dernier autorisé.
+
+## 5. Tests avant lancement
+1. **Couverture** (léger, < 300 Mo, sans SNN) : produit coverage.json, S_pF, S_rh et leurs sha. Pendant 925745 : seulement avec le oui écrit
+ de Philippe-Antoine (§11, D3), avec ≤ 300 Mo par processus et une garde qui ne tue que son propre enfant ; sinon après la fin de 925745.
+2. **Équivalence** (lourd, derrière la porte, après le gel) :
+ - pf avec S := cm_sem de l'échantillon == cm bit à bit, sur le préfixe smoke/equiv (3 Mo, snn 1500, am 20 000, 2 époques ; empreintes
+ W_rec, W_out, W_outG, AM, historique) ;
+ - test rh/pf : seules les lignes couvertes diffèrent ;
+ - avec checkpoints intra-époque (si approuvés), interruption puis reprise == run continu, et checkpoint actif == inactif, bit à bit (§6.3).
+3. **Smoke vtest2** (lourd ; snn 3000, am 1,2 M, 1 époque) : verdict mesurable. **Pic RSS de pF/rh mesuré ici** (point 9).
+4. Test unitaire du drapeau test_v3 (§3.3) et de la liste `excluded`.
+
+## 6. Ressources et gardes
+### 6.1 Mesures M8 v1b
+- **Bras CM** : 26–30 t/s, RSS SNN ≈ 952 Mo, pic ≈ 2,14 Go à la sauvegarde. Durée ≈ 11,5–13,3 h par bras.
+- **ctl** : 4,1 h, pic 1 192,8 Mo (descriptif, déjà fait).
+### 6.2 Porte et plafond (point 9)
+- Porte gate_m8v1b.sh (d8287108…) en paramètres, logique inchangée :
+ - MemAvailable ≥ max(5,2 Go ; 4,4 GiB + 2,5 Go + marge du bras en cours) ;
+ - < 4 lourds avant lancement ;
+ - nice 10, OMP_NUM_THREADS=1, PYTHONHASHSEED=0, setsid, TMPDIR dans m7_sem/retrain/tmp, rien sous /tmp.
+- **Plafond RSS de groupe ≤ 3,5 Go par bras, APPLIQUÉ dans le lanceur M7r** :
+ - mesure de la RSS du groupe toutes les 5 s ;
+ - au-delà de 3,5 Go, SIGTERM à son **propre** groupe seulement, rc 3, journalisé ;
+ - en plus du chien de garde existant (MemAvailable < 4,4 GiB) ;
+ - jamais de kill hors de son propre groupe.
+- Le pic mesuré au smoke doit être ≤ 3,0 Go, sinon pas de run.
+### 6.3 Checkpoints intra-époque (point 11) **[EN ATTENTE — oui de Philippe-Antoine]**
+- Proposition : checkpoint tous les 50 000 ticks (≈ 28–32 min à 26–30 t/s), **identique pour pF et rh**.
+ - État complet : poids, v, s, refr, traces, état RNG, index de tick, offset données.
+ - Écriture atomique (tmp puis rename), 2 derniers gardés.
+- Preuve par le test d'équivalence §5.2 : poids identiques avec ou sans checkpoint, et après reprise.
+- Le pic RSS lors d'un checkpoint est mesuré au smoke et doit respecter §6.2.
+- C2 compare alors pF/rh (avec checkpoints) à cm (sans) ; c'est valide seulement si §5.2 prouve l'identité bit à bit.
+- Recommandation de Checker, non adoptée sans oui : garde « consciente du ballon » (pas de kill sur un seul échantillon dans les 120 s
+ après un fork ou une activité du ballon).
+
+## 7. Gel (point 12)
+- **PREDECL_M7r.md** est gelé (lecture seule, daté) AVANT le premier run lourd (tests 5.2 et 5.3 compris). Il porte les sha de :
+ - train_m7r.py, verdict_M7r.py, gate_m7r.sh, du lanceur ;
+ - proj_F (942ad88a…), S_pF, S_rh, coverage.json et du recompte Checker de couverture ;
+ - du masque test20k (50fa08f9…) et des deux recomptes 64 o (a307ccc7…, 0107671a…) ;
+ - des fichiers de code §1 ;
+ - des seuils : couverture, bornes de scale, α = 0,05, B = 10 000, blocs de 512 o, pas de checkpoint.
+- Ensuite, un audit Checker écrit des scripts figés, puis le drapeau m7_sem/retrain/GO_CHECKER_PASS est posé.
+- Seuls les points tranchés par écrit par Philippe-Antoine (§11) y entrent ; sinon, pas de gel.
+
+## 8. Ordre proposé (rien de lourd pendant cm 925745)
+1. cm M8 v1b essai 3 (ETA ≈ dim. 08 h 40–10 h 20 Toronto), puis verdict r3B par la porte 218845.
+2. cov b r3 test (784212), arrêt en WAIT_CHECKER_AUDIT.
+3. M8cp1 (882549 puis gate_m8cp1.sh ; ≈ 13,3–18 h).
+4. M7r : gel, tests 5.2 et 5.3, puis pF et rh (en parallèle si la porte le permet, sinon pF puis rh).
+- ETA indicatives sans échec :
+ - pF ∥ rh ≈ lun. 12 h 00–19 h 00 ;
+ - séquentiel ≈ mar. 00 h 00–08 h 00.
+- Les attentes 882549 et 784212 visent le PID 666012 (mort), puis la porte 218845, qui couvre l'essai 3. Rien n'a été modifié.
+
+## 9. Réutilisé
+m8_v1b/runs (ctl, et cm après l'essai 3) : lu seulement.
+
+## 10. Livrables prévus
+m7_sem/retrain/ : PREDECL_M7r.md, train_m7r.py, verdict_M7r.py, gate_m7r.sh, coverage.json, runs/, verdict/. Aucun push HF sans ordre écrit.
+
+## 11. Décisions utilisateur requises (Philippe-Antoine, par écrit ; Hashing ne tranche rien)
+- **D1 — Ajouts à la règle B (point 7 de l'audit)**
+ - (a) IC95 bootstrap > 0 dans le gain : garder (déjà dans le texte de la règle B du 13 h 00) ou retirer.
+ - (b) Holm : aucun (B-pure) ; ou Holm à 2 comparaisons avec p_k = min des fenêtres fraîches ; ou Holm fenêtres × comparaisons.
+ - (c) Adoption : C1 ET C2 (B+) ; ou C2 seule ; ou C1 seule.
+ - À défaut d'approbation, retour à la règle B pure sur une seule comparaison, à désigner.
+- **D2 — Bornes fusion.scale [0,03 ; 0,11] (point 8)** : vous les avez dites PROVISOIRES ; Checker demande de les coder en dur, sans surcharge.
+ - Option 1 : figer [0,03 ; 0,11] en dur, NON MESURABLE hors plage.
+ - Option 2 : réviser les bornes maintenant, avant le gel, puis les figer en dur.
+ - Option 3 : les garder provisoires. Dans ce cas, pas de gel possible.
+ - Dans tous les cas, aucune révision après avoir vu les scales de pF/rh. Rappel : ctl est à 0,02818.
+- **D3 — Test léger de couverture pendant cm 925745 (point 10)** : oui écrit (≤ 300 Mo, garde sur son propre enfant) ou non (après 925745).
+- **D4 — Seuil de couverture (point 3)** : 0,50 de coverage_tokens_snn (proposé) ou une autre valeur.
+ Et le choix de l'option : A (vocabulaire du modèle, cm et ctl réutilisés ; proposé) ou B (vocabulaire de proj_F, nouveau bras cm, ≈ 12 h de plus).
+- **D5 — Checkpoints intra-époque (point 11)** : oui ou non à 50 000 ticks, identiques pour pF et rh. Et oui ou non à la garde « consciente du ballon ».
+- **D6 — Questions conservées de la v1**
+ - C1 + C2 contre C2 seule (lié à D1c).
+ - Ordre : M7r après M8cp1 et cov b r3 (proposé) ou avant ; pF ∥ rh autorisé ?
+ - Si l'essai 3 du cm échoue : 4e essai cm hors limite, ou pas d'adoption (C2 NON MESURABLE).
+- **D7 — Recompte de fuite en 32 o (point 15)** : le faire (descriptif, après 925745) ou non.
+
+## 12. Questions pour Checker (ré-audit)
+1. Règle de doublons §2.1 (sommés, sans dédoublonnage, identique pour les trois bras) : acceptable, ou faut-il l'alternative dédoublonnée avec un nouveau cm ?
+2. Formule rh §2.2 (RH_SEED, indépendance par rapport à base12) : correcte ?
+3. Contrôles de lecture croisée §3.6 suffisants, vu l'absence de sha de code par run dans results.jsonl de M8 v1b ?
+4. Recompte indépendant de couverture (§4.1) : Checker le prend-il en charge ?
+— SPIRA Hashing (brouillon v2, non gelé)
diff --git a/results/hashing/m7_sem/spira_m7_retrain_plan_v2.md.sha256 b/results/hashing/m7_sem/spira_m7_retrain_plan_v2.md.sha256
new file mode 100644
index 0000000000000000000000000000000000000000..c542d8afd6652bebf1acc81700c8b75ad0b845d1
--- /dev/null
+++ b/results/hashing/m7_sem/spira_m7_retrain_plan_v2.md.sha256
@@ -0,0 +1 @@
+32b2e467f0ae2991ddf9e16ef95f06c99ca83d6a16581acd219515b97558e6e5 spira_m7_retrain_plan_v2.md
diff --git a/results/hashing/m7_sem/spira_m7_retrain_plan_v3.md b/results/hashing/m7_sem/spira_m7_retrain_plan_v3.md
new file mode 100644
index 0000000000000000000000000000000000000000..88a1bb3776c27f944225e6429f45f922049831d5
--- /dev/null
+++ b/results/hashing/m7_sem/spira_m7_retrain_plan_v3.md
@@ -0,0 +1,314 @@
+# BROUILLON v3 de pré-déclaration — réentraînement SPIRA avec la projection figée M7sem (proj_F) — SPIRA Hashing
+Rédigé le 2026-10-24 vers 21 h 57 (Toronto). Il remplace la v2 (spira_m7_retrain_plan_v2.md, 32b2e467…) et la v1 (47c087cc…), toutes deux conservées intactes.
+La v3 répond au ré-audit Checker de la v2 (checker/recount/m7r_plan_audit/AUDIT_M7r_plan_v2.md, a74c278c…), qui ne laissait ouvert que le point 2 (mineur).
+Changements par rapport à la v2 :
+- §2.2 : sha de S_pF et S_rh, et dtype de la liste des colonnes couvertes ;
+- §3.4 et §11 D1a : correction de Checker ;
+- §4.1 et §11 D4 : alerte de couverture ;
+- §3.6 et §12 : réponses de Checker.
+Réponses à l'audit v1 : AUDIT_RESPONSE_v2.md (ba0e781e…).
+**BROUILLON, NON GELÉ. Rien n'est lancé ni armé, et aucun script de bras ou de verdict n'est écrit.**
+Les points marqués **[EN ATTENTE — oui de Philippe-Antoine]** sont des propositions : rien n'est figé sur ces points.
+
+## 0. Base
+- M7sem **OUI**, validé par Checker le 24 oct. à 21 h 08 (spira_relay.md l. ~10394). verdict_M7sem.json : 85da7cc7….
+ Bloc CM24 : Δ_rand 0,1071 [0,1055 ; 0,1088], Δ_hash 0,1075 [0,1058 ; 0,1092].
+- Projection : **m7_sem/work/full.proj_F.npz, sha256 942ad88a387cbae4e22685956fdd7d8006da643b4dba659b23fca1d1b87ac94b**.
+ Elle est déterministe (2 constructions identiques). Contenu : vocab_ids (16 384 ids FNV-1a 64), base (12), sem (24, dans [1024, 5120)), has_ctx.
+- M7sem montre seulement que des patches proches partagent des neurones. Le réentraînement teste si cela améliore la prédiction.
+
+## 1. Pipeline de référence repris tel quel (M8 v1b, m8_v1b/PREDECL.md §1–§5, §10)
+- **Données.** m8_v1b/sample/v1b_sample.bin : 35 128 951 o, sha 9ea562e4…370b.
+- **EPT.** Fit sur l'échantillon [0, 2 M), calibration sur [2 M, 2,4 M), budget 16,04 bits. 7 739 248 patches, vocabulaire top-16 384, registre count ≥ 2.
+- **Budgets.** SNN : 600 000 ticks/époque × 2 époques. AM : 1 200 000 patches. Calibration fusion sur [0, 60 000).
+- **Config.** SPIRAConfig(vocab_size=16384, d_in=1024, snn_tokens=600000, am_tokens=1200000, epochs=2), seed 20261022, maxpos 4000. Repo HEAD 6923c519.
+- **Code et sha.**
+
+ | fichier | sha256 |
+ |---|---|
+ | train_m8v1b.py | b2b12c8c…9e3c |
+ | countmin.py | caab50405e73eba7981f73a63fb1709139aed55383501c3e830e174cb02b8d3b |
+ | eval_ref_v3.py (verbatim) | e2c8cd1deabc228faed302bebdb81bf8d10405df63e393b4a8ddb6152401c10e |
+ | windows_v2.py | 7d9ed224… |
+ | spira/hashing.py | f26903e19cd92963e84d6271fc296d4998c4b364ce28be712241236391c2ab02 |
+
+- **Bras cm M8 v1b.** d_in 5120, k_in 36, n_state 6656. Ligne = base12 (SPIRA._structured_row, d_in 1024, k 12 = 6 hash entiers + 6 trigrammes) + 24 MinHash.
+
+## 2. Bras
+| bras | rôle | bloc CM [1024, 5120), 24 positions | d_in / k_in / n_state | coût |
+|---|---|---|---|---|
+| **pF** | TRAITÉ | S_pF[col] = proj_F.sem[i], où pid(col) = proj_F.vocab_ids[i] et has_ctx[i] ; sinon -1 | 5120 / 36 / 6656 | nouveau run |
+| **rh** | CONTRÔLE PRIMAIRE | S_rh[col] = hash aléatoire figé (§2.2) sur **exactement** les colonnes où S_pF ≠ -1 ; sinon -1 | 5120 / 36 / 6656 | nouveau run |
+| cm | CONTRÔLE SECONDAIRE (existant) | M8 v1b cm, réutilisé si l'essai 3 (PID 925745) finit en code 0 | 5120 / 36 / 6656 | 0 |
+| ctl | descriptif seulement | sans bloc CM | 1024 / 12 / 2560 | 0 |
+
+### 2.1 Règle unique de doublons et de repli, identique pour pF, rh et cm (point 1 de l'audit)
+- Le code mesuré : SpikingCore.step fait `I = W_in[input_idx].sum(axis=0)`. **Les doublons ne sont pas dédoublonnés : ils sont sommés**
+ (un neurone répété deux fois reçoit deux fois son poids).
+- CMSPIRA._structured_row (countmin.py caab5040…) remplace chaque -1 par base[0]. Une colonne sans ligne sémantique répète donc base[0]
+ 24 fois. C'est la convention du bras cm.
+- **Règle figée pour pF et rh (et inchangée pour cm) : aucun dédoublonnage, doublons sommés, -1 → base[0], code CMSPIRA._structured_row inchangé.**
+ - Raison : c'est la convention exacte de cm, ce qui permet la comparaison C2 et le test d'équivalence bit à bit pF(S := cm_sem) == cm (§5.2).
+ - Dédoublonner pour pF/rh seulement casserait cette identité. Dédoublonner pour les trois demanderait un nouveau bras cm.
+- Pour rh, P(au moins un doublon parmi 24 tirages uniformes dans 4096) = 1 − ∏_{i<24}(1 − i/4096) = 0,0653 (calcul exact). Pour pF (MinHash
+ à 24 sels), le taux n'est pas mesuré.
+- **Contrôle figé.** Le json de sortie journalise, pour chaque bras et sur les colonnes couvertes, la distribution du nombre de neurones
+ distincts du bloc (moyenne, min, histogramme) et le nombre de colonnes en repli.
+- **Garde.** Le nombre de colonnes en repli doit être identique pour pF et rh (même ensemble), sinon rc 2. L'écart de neurones distincts
+ moyens pF − rh est rapporté, sans valeur décisionnelle.
+- **Alternative** (24 neurones distincts garantis, par extension de sel, pour pF ET rh) : possible si Checker ou l'utilisateur l'exige.
+ Elle demanderait alors aussi un bras cm dédoublonné.
+
+### 2.2 rh : fonction de hachage et graine figées (point 2)
+- **Écart trouvé en relisant le code.** La v1 proposait `1024 + input_neurons(pid, 4096, 24)`. Or input_neurons utilise les sels
+ `0x51ED270B733D4C31 + j·0x9E3779B97F4A7C15`, ce sont les MÊMES que la partie « hash entier » de base12 (input_neurons(pid, 1024, 6)).
+ Comme 4096 est un multiple de 1024, on aurait (rh_j − 1024) mod 1024 == base_j pour j < 6 : le bloc rh serait corrélé à base. **Retiré.**
+- **Formule figée** (splitmix64 de spira/hashing.py f26903e1…, M64 = 2^64 − 1, RH_SEED = 0x52485F4D37520001) :
+ S_rh[col, j] = 1024 + ((splitmix64((pid ^ RH_SEED ^ ((j · 0x9E3779B97F4A7C15) & M64)) & M64) >> 32) mod 4096), j = 0..23.
+ Elle s'applique pour col ∈ couvert(pF) ; sinon S_rh[col, j] = -1.
+- **Sha des tables S (méthode : sha256 de `S.astype(' « **ADOPTÉ** ssi gain significatif (McNemar exact p < 0,05 ET c > b ET IC95 bootstrap > 0) sur ≥ 1 fenêtre fraîche valide (fc2, fresh_en,
+> fresh_fr, test20k strict, test_v3 si propre), ET aucune perte significative (p < 0,05 ET b > c) sur une fenêtre valide (seen + fraîches
+> valides ; une égalité sur seen saturé est admise). Le gain sur seen n'est plus exigé. Sinon **REJETÉ**. »
+
+### 3.2 Définitions (identiques à verdict_M8v1b.py l. 76–88)
+- Positions retenues : cible in-vocab dans les DEUX bras, sous le masque de fenêtre. Appariement par position (tgt_start et tgt_len
+ identiques, sinon assert).
+- ha = fused_hit ∧ invocab pour le bras de **référence** ; hb = la même chose pour le bras **candidat** (pF).
+- **b = #{réf. juste ∧ cand. faux}** ; **c = #{réf. faux ∧ cand. juste}**.
+- **McNemar exact bilatéral** (pour les gains ET les pertes) : p = min(1, 2 · Σ_{i ≤ min(b, c)} C(b+c, i) / 2^{b+c}), fonction binp de r3B.
+- Bootstrap apparié par blocs de 512 o, B = 10 000, seed 0. test20k strict = masque 50fa08f9….
+- Gain significatif = p < 0,05 ET c > b ET IC95 bootstrap > 0. Perte significative = p < 0,05 ET b > c.
+
+### 3.3 Fenêtres (point 4 et point 6)
+- **Dans la règle :**
+ - seen = échantillon[:200 000], avec trained_frac ≥ 0,99 dans les deux bras ;
+ - fc2, fresh_en, fresh_fr, test20k strict ;
+ - test_v3, seulement si recompte échantillon = 0 ET recompte v1b = 0 ET présence de **m7_sem/retrain/GO_CHECKER_PASS**.
+ verdict_M7r.py lit CE drapeau et jamais m8_v1b/GO_CHECKER_PASS (point 5). Test unitaire : le drapeau M8 v1b seul ⇒ test_v3 exclue.
+- **Propreté** = 0 position en 64 o dans les DEUX recomptes : a307ccc7… (échantillon) et 0107671a… (Checker v1b, PASS).
+- **queries** : rapportée à part, **hors règle** : ni dans les gains, ni dans les pertes, ni dans Holm.
+- **Jamais évaluées par aucun bras, ni dans la règle ni en descriptif :** broad_local_v1/test, neither_code et freshcode m7.
+ - broad_local_v1/test ne sert que de témoin positif de recompte ; aucun npz d'éval n'est produit pour ces trois fenêtres.
+ - La liste `excluded` du json de verdict les nomme **toutes les trois**, avec leur raison (positions contaminées : 32 344 / 224 171 / 163 445).
+- **broad_gutenberg_v1 n'est pas utilisée.** Aucune fenêtre n'est ajoutée après le gel.
+
+### 3.4 Ajouts à la règle B **[DÉCISION UTILISATEUR — §11, D1]**
+Deux versions sont écrites. Le PREDECL gelé ne contiendra que celle que Philippe-Antoine aura choisie par écrit.
+- **Version B-pure.** Règle §3.1 appliquée à une seule comparaison, sans Holm. Il faut alors choisir laquelle : C2 = pF contre cm
+ (comme M8 v1b, candidat contre bras existant) ou C1 = pF contre rh.
+- **Version B+.**
+ - Règle §3.1 appliquée à C1 (pF contre rh) ET à C2 (pF contre cm).
+ - Holm à 2 comparaisons sur les gains, α = 0,05, avec deux définitions possibles du p de chaque comparaison :
+ - (i) p_k = min des p McNemar sur les fenêtres fraîches valides gagnantes. C'est fidèle à l'événement « ≥ 1 fenêtre » de la règle B,
+ mais ce minimum n'est pas lui-même corrigé pour le nombre de fenêtres (≤ 5) ;
+ - (ii) Holm sur l'ensemble fenêtres × comparaisons (≤ 10 tests), plus conservateur.
+ - Pertes : p < 0,05 sans correction, donc plus strict pour l'adoption.
+ - ADOPTÉ ssi C1 ET C2 sont ADOPTÉ.
+- **Correction de Checker (ré-audit v2, point 7)** : « IC95 bootstrap > 0 » fait partie du texte de la règle B gelé
+ (m8_v1b/PREDECL.md §10, l. 71). **Ce n'est pas un ajout** et il reste dans les deux versions. Les seuls ajouts soumis à D1 sont Holm et C1 ∧ C2.
+
+### 3.5 NON MESURABLE (par comparaison)
+- budgets inégaux (snn_tokens, am_tokens, epochs, ticks/époque, sha des données) ;
+- passe SNN incomplète ;
+- trained_frac < 0,99 ;
+- tokenisation différente ;
+- sha de proj_F, S_pF ou S_rh différent du gel ;
+- couverture sous le seuil (§4.1) ;
+- fusion.scale hors [0,03 ; 0,11] ou illisible (valeur rapportée ; statut des bornes : §11, D2) ;
+- sha de code différent entre runs (§3.6) ;
+- bras cm absent : C2 NON MESURABLE, donc **aucune adoption** dans la version B+.
+
+### 3.6 Lecture croisée de deux dossiers runs (point 14)
+results.jsonl de M8 v1b ne journalise pas les sha de code par run (clés présentes : data_sha256, ckpt_sha256, budgets, cal, n_state…).
+Pour C2, verdict_M7r.py vérifie :
+- data_sha256, budgets, n_state et tokenisation égaux ;
+- sha **actuel** de countmin.py (caab5040…), eval_ref_v3.py (e2c8cd1d…), windows_v2.py (7d9ed224…), train_m8v1b.py (b2b12c8c…) et
+ spira/hashing.py (f26903e1…) == sha déclarés dans m8_v1b/PREDECL.md == sha journalisés par les runs pF/rh ;
+- config : les champs SPIRAConfig de cm (lus depuis cm.npz) == ceux de pF/rh, hors d_in/k_in, qui sont égaux par construction.
+Renforcements proposés par Checker (ré-audit v2, §4 Q3), à intégrer au PREDECL :
+- (a) vocab_ids(cm.npz) == vocab_ids(ctl.npz) == vocabulaire journalisé par pF/rh ;
+- (b) cm_sem de cm.npz == recalcul par countmin.py caab5040… (sous la porte, après 925745) ;
+- (c) config JSON de cm.npz == pF/rh, hors d_in/k_in ;
+- (d) mtime du code antérieure au départ de l'essai 3. La mise en lecture seule des fichiers est une **DÉCISION** à prendre ; elle n'a pas été faite.
+Toute inégalité rend C2 NON MESURABLE. Risque résiduel déclaré : le run cm lui-même ne journalise pas ses sha de code ; l'égalité repose
+sur le PREDECL M8 v1b gelé et sur l'invariance des fichiers.
+
+### 3.7 Descriptifs non décisionnels
+pF contre ctl, rh contre cm, écart seen − frais (gapcalc r3B), précision sur positions couvertes ou non, statistiques de doublons.
+
+## 4. Points critiques
+### 4.1 Couverture (point 3) **[EN ATTENTE — oui de Philippe-Antoine]**
+- Les vocabulaires de proj_F (EPT corpus entier, 12,905 bits) et du modèle (EPT échantillon, 16,04 bits) diffèrent.
+- **Mesure de Checker** (AUDIT_M7r_plan_v2.md §2 ; non recalculée par Hashing) :
+ - colonnes couvertes 5 246 / 16 384 = 0,3202 ;
+ - **coverage_tokens_snn ≈ 0,1633 (97 951 / 600 000 ticks)** ;
+ - 0,176 sur l'échantillon entier (1 364 998 / 7 739 248) ;
+ - « ≈ » parce que l'octet de fin diffère de 4 o par rapport au journal.
+ **En option A avec le seuil de 0,50, M7r serait NON MESURABLE d'avance** (voir §11 D4).
+- **Seuil numérique proposé : NON MESURABLE si coverage_tokens_snn < 0,50** (fraction des 600 000 ticks SNN dont le patch a une ligne S_pF ≠ -1).
+ Ce n'est pas figé avant le oui écrit.
+- Le test de couverture (§5.1) tourne AVANT le gel ; seul le seuil conditionne la décision.
+- **Recompte indépendant par Checker** (script Checker, dans checker/ ; Hashing n'y touche pas). Un désaccord bloque le gel.
+- Option A ou B : §11, D4.
+
+### 4.2 Fuite d'éval par proj_F (proj_F a vu corpus_v1b/train.bin entier : 520 785 883 o, ddf67ffb…)
+- 0 position en 64 o contre TOUT train.bin pour fc2, fresh_en, fresh_fr, test20k, test_v3 et queries, dans les deux recomptes :
+ manifest_corpus_diverse_v1b.json (cb6398ca…) et Checker recount64_words.json (0107671a…, PASS). Fichiers existants seulement.
+- Fenêtres contaminées, jamais évaluées (§3.3) : neither_code, freshcode m7, broad_local_v1/test.
+- **Recompte en 32 o (point 15), optionnel et descriptif, NON lancé maintenant** : fenêtres fraîches contre train.bin. Le résultat est
+ rapporté sans changer la règle. Il serait lancé seulement avec l'accord de l'utilisateur, après 925745, sous la porte.
+- Avantage de données déclaré : 520 Mo pour proj_F contre 35 Mo pour cm ; aucune donnée pour rh.
+
+### 4.3 Exclusions explicites (point 13)
+- Aucune variante de décodage n'est testée (température, top-k, n-best, re-ranking) : l'éval est eval_hits verbatim.
+- Aucun levier déjà rejeté n'est réutilisé : ni SP1, ni SP2, ni AH1, ni AH2.
+- mask_oldtest_strict.npz (dossier lever2/verdict_AH1/, 50fa08f9…) est **seulement un masque de propreté** pour test20k strict ; ce n'est pas le levier AH1.
+
+### 4.4 Autres risques
+- ctl a scale = 0,02818, hors plage ; la scale de cm n'est pas encore connue ; pF et rh risquent aussi un NON MESURABLE.
+- Les essais cm 1 et 2 ont fini en code 143. L'essai 3 est le dernier autorisé.
+
+## 5. Tests avant lancement
+1. **Couverture** (léger, < 300 Mo, sans SNN) : produit coverage.json, S_pF, S_rh et leurs sha. Pendant 925745 : seulement avec le oui écrit
+ de Philippe-Antoine (§11, D3), avec ≤ 300 Mo par processus et une garde qui ne tue que son propre enfant ; sinon après la fin de 925745.
+2. **Équivalence** (lourd, derrière la porte, après le gel) :
+ - pf avec S := cm_sem de l'échantillon == cm bit à bit, sur le préfixe smoke/equiv (3 Mo, snn 1500, am 20 000, 2 époques ; empreintes
+ W_rec, W_out, W_outG, AM, historique) ;
+ - test rh/pf : seules les lignes couvertes diffèrent ;
+ - avec checkpoints intra-époque (si approuvés), interruption puis reprise == run continu, et checkpoint actif == inactif, bit à bit (§6.3).
+3. **Smoke vtest2** (lourd ; snn 3000, am 1,2 M, 1 époque) : verdict mesurable. **Pic RSS de pF/rh mesuré ici** (point 9).
+4. Test unitaire du drapeau test_v3 (§3.3) et de la liste `excluded`.
+
+## 6. Ressources et gardes
+### 6.1 Mesures M8 v1b
+- **Bras CM** : 26–30 t/s, RSS SNN ≈ 952 Mo, pic ≈ 2,14 Go à la sauvegarde. Durée ≈ 11,5–13,3 h par bras.
+- **ctl** : 4,1 h, pic 1 192,8 Mo (descriptif, déjà fait).
+### 6.2 Porte et plafond (point 9)
+- Porte gate_m8v1b.sh (d8287108…) en paramètres, logique inchangée :
+ - MemAvailable ≥ max(5,2 Go ; 4,4 GiB + 2,5 Go + marge du bras en cours) ;
+ - < 4 lourds avant lancement ;
+ - nice 10, OMP_NUM_THREADS=1, PYTHONHASHSEED=0, setsid, TMPDIR dans m7_sem/retrain/tmp, rien sous /tmp.
+- **Plafond RSS de groupe ≤ 3,5 Go par bras, APPLIQUÉ dans le lanceur M7r** :
+ - mesure de la RSS du groupe toutes les 5 s ;
+ - au-delà de 3,5 Go, SIGTERM à son **propre** groupe seulement, rc 3, journalisé ;
+ - en plus du chien de garde existant (MemAvailable < 4,4 GiB) ;
+ - jamais de kill hors de son propre groupe.
+- Le pic mesuré au smoke doit être ≤ 3,0 Go, sinon pas de run.
+### 6.3 Checkpoints intra-époque (point 11) **[EN ATTENTE — oui de Philippe-Antoine]**
+- Proposition : checkpoint tous les 50 000 ticks (≈ 28–32 min à 26–30 t/s), **identique pour pF et rh**.
+ - État complet : poids, v, s, refr, traces, état RNG, index de tick, offset données.
+ - Écriture atomique (tmp puis rename), 2 derniers gardés.
+- Preuve par le test d'équivalence §5.2 : poids identiques avec ou sans checkpoint, et après reprise.
+- Le pic RSS lors d'un checkpoint est mesuré au smoke et doit respecter §6.2.
+- C2 compare alors pF/rh (avec checkpoints) à cm (sans) ; c'est valide seulement si §5.2 prouve l'identité bit à bit.
+- Recommandation de Checker, non adoptée sans oui : garde « consciente du ballon » (pas de kill sur un seul échantillon dans les 120 s
+ après un fork ou une activité du ballon).
+
+## 7. Gel (point 12)
+- **PREDECL_M7r.md** est gelé (lecture seule, daté) AVANT le premier run lourd (tests 5.2 et 5.3 compris). Il porte les sha de :
+ - train_m7r.py, verdict_M7r.py, gate_m7r.sh, du lanceur ;
+ - proj_F (942ad88a…), S_pF, S_rh, coverage.json et du recompte Checker de couverture ;
+ - du masque test20k (50fa08f9…) et des deux recomptes 64 o (a307ccc7…, 0107671a…) ;
+ - des fichiers de code §1 ;
+ - des seuils : couverture, bornes de scale, α = 0,05, B = 10 000, blocs de 512 o, pas de checkpoint.
+- Ensuite, un audit Checker écrit des scripts figés, puis le drapeau m7_sem/retrain/GO_CHECKER_PASS est posé.
+- Seuls les points tranchés par écrit par Philippe-Antoine (§11) y entrent ; sinon, pas de gel.
+
+## 8. Ordre proposé (rien de lourd pendant cm 925745)
+1. cm M8 v1b essai 3 (ETA ≈ dim. 08 h 40–10 h 20 Toronto), puis verdict r3B par la porte 218845.
+2. cov b r3 test (784212), arrêt en WAIT_CHECKER_AUDIT.
+3. M8cp1 (882549 puis gate_m8cp1.sh ; ≈ 13,3–18 h).
+4. M7r : gel, tests 5.2 et 5.3, puis pF et rh (en parallèle si la porte le permet, sinon pF puis rh).
+- ETA indicatives sans échec :
+ - pF ∥ rh ≈ lun. 12 h 00–19 h 00 ;
+ - séquentiel ≈ mar. 00 h 00–08 h 00.
+- Les attentes 882549 et 784212 visent le PID 666012 (mort), puis la porte 218845, qui couvre l'essai 3. Rien n'a été modifié.
+
+## 9. Réutilisé
+m8_v1b/runs (ctl, et cm après l'essai 3) : lu seulement.
+
+## 10. Livrables prévus
+m7_sem/retrain/ : PREDECL_M7r.md, train_m7r.py, verdict_M7r.py, gate_m7r.sh, coverage.json, runs/, verdict/. Aucun push HF sans ordre écrit.
+
+## 11. Décisions utilisateur requises (Philippe-Antoine, par écrit ; Hashing ne tranche rien)
+- **D1 — Ajouts à la règle B (point 7 de l'audit)**
+ - (a) **Sans objet comme ajout** : d'après la correction de Checker, « IC95 bootstrap > 0 » fait partie de la règle B gelée (PREDECL M8 v1b l. 71). Il reste.
+ - (b) Holm : aucun (B-pure) ; ou Holm à 2 comparaisons avec p_k = min des fenêtres fraîches ; ou Holm fenêtres × comparaisons.
+ - (c) Adoption : C1 ET C2 (B+) ; ou C2 seule ; ou C1 seule.
+ - À défaut d'approbation, retour à la règle B pure sur une seule comparaison, à désigner.
+- **D2 — Bornes fusion.scale [0,03 ; 0,11] (point 8)** : vous les avez dites PROVISOIRES ; Checker demande de les coder en dur, sans surcharge.
+ - Option 1 : figer [0,03 ; 0,11] en dur, NON MESURABLE hors plage.
+ - Option 2 : réviser les bornes maintenant, avant le gel, puis les figer en dur.
+ - Option 3 : les garder provisoires. Dans ce cas, pas de gel possible.
+ - Dans tous les cas, aucune révision après avoir vu les scales de pF/rh. Rappel : ctl est à 0,02818.
+- **D3 — Test léger de couverture pendant cm 925745 (point 10)** : oui écrit (≤ 300 Mo, garde sur son propre enfant) ou non (après 925745).
+- **D4 — Couverture et option (points 3 et 4.1) — ⚠ ALERTE DE COUVERTURE (mesure de Checker)**
+ - En option A, proj_F couvre seulement **≈ 0,163 des tokens SNN** (97 951 / 600 000 ticks ; 0,176 sur l'échantillon entier ; 0,320 des colonnes).
+ - **Option A avec le seuil de 0,50 ⇒ NON MESURABLE d'avance.** Le seuil proposé dans la v2 n'est donc pas tenable avec l'option A.
+ - Choix honnêtes, Hashing ne tranche pas. Tout seuil doit être fixé avant de voir des résultats.
+ - **Option B** : EPT et vocabulaire de proj_F pour pF et rh. Couverture proche de 1 : has_ctx vaut 16 384 / 16 384 dans proj_F ; la
+ couverture en tokens n'est pas mesurée. La tokenisation change, donc cm et ctl ne sont plus réutilisables : il faut un nouveau bras
+ cm à budget égal (≈ 12 h, de 11,5 à 13,3 h estimés d'après les débits mesurés de cm). ctl est à refaire seulement s'il est voulu en descriptif (≈ 4,1 h).
+ Les sha de S de §2.2 ne s'appliquent plus.
+ - **Option A avec un seuil plus bas** (par exemple ≤ 0,15, à fixer maintenant) : mesurable, mais pF ne diffère de rh que sur ≈ 16 % des
+ tokens (sur les autres, les deux bras sont en repli identique). La puissance pour détecter un gain est faible : un REJETÉ ou un
+ NON SIGNIFICATIF serait peu informatif, et ne prouverait pas l'inutilité du hachage sémantique.
+ - **Option C** : reconstruire une projection « proj_M » sur la segmentation et le vocabulaire du MODÈLE (EPT de l'échantillon,
+ vocabulaire de ctl.npz), avec les co-occurrences sur corpus_v1b/train.bin. Calcul seulement, sans rétropropagation, déterministe,
+ même pipeline que M7sem (pic mesuré en M7sem : 251,7 Mo ; durée non estimée).
+ - Couverture attendue proche de la couverture in-vocab, non mesurée.
+ - Ce ne serait PAS le proj_F validé (942ad88a…) : proj_M devrait repasser le critère M7sem (pré-déclaration, puis audit) avant tout réentraînement.
+ - Les sha de S_pF et S_rh changent tous les deux, puisque l'ensemble des colonnes couvertes change ; il faudra les recalculer et les figer.
+ - Abandon de M7r : à envisager seulement si aucune des trois options ne convient.
+- **D5 — Checkpoints intra-époque (point 11)** : oui ou non à 50 000 ticks, identiques pour pF et rh. Et oui ou non à la garde « consciente du ballon ».
+- **D6 — Questions conservées de la v1**
+ - C1 + C2 contre C2 seule (lié à D1c).
+ - Ordre : M7r après M8cp1 et cov b r3 (proposé) ou avant ; pF ∥ rh autorisé ?
+ - Si l'essai 3 du cm échoue : 4e essai cm hors limite, ou pas d'adoption (C2 NON MESURABLE).
+- **D7 — Recompte de fuite en 32 o (point 15)** : le faire (descriptif, après 925745) ou non.
+
+## 12. Questions pour Checker (ré-audit)
+**Réponses de Checker** (AUDIT_M7r_plan_v2.md §4) : Q1, règle de doublons acceptable telle quelle ; Q2, formule rh correcte
+(coïncidence mod 1024 : 0,11 %, contre 0,098 % au hasard) ; Q3, minimum suffisant, avec les renforcements (a)–(d) repris en §3.6 ;
+Q4, Checker prend en charge le recompte de couverture.
+**Demande v3 : PASS sur le point 2 (§2.2).** Questions d'origine conservées pour trace :
+1. Règle de doublons §2.1 (sommés, sans dédoublonnage, identique pour les trois bras) : acceptable, ou faut-il l'alternative dédoublonnée avec un nouveau cm ?
+2. Formule rh §2.2 (RH_SEED, indépendance par rapport à base12) : correcte ?
+3. Contrôles de lecture croisée §3.6 suffisants, vu l'absence de sha de code par run dans results.jsonl de M8 v1b ?
+4. Recompte indépendant de couverture (§4.1) : Checker le prend-il en charge ?
+— SPIRA Hashing (brouillon v3, non gelé)
diff --git a/results/hashing/m7_sem/spira_m7_retrain_plan_v3.md.sha256 b/results/hashing/m7_sem/spira_m7_retrain_plan_v3.md.sha256
new file mode 100644
index 0000000000000000000000000000000000000000..68fd011098ef972a706658b1f0417df2081ec546
--- /dev/null
+++ b/results/hashing/m7_sem/spira_m7_retrain_plan_v3.md.sha256
@@ -0,0 +1 @@
+de0887a399072147487367afa0c6b924b2746f653009eb02b738ccdc35b38398 spira_m7_retrain_plan_v3.md
diff --git a/results/hashing/m7_sem/verdict_M7sem.json b/results/hashing/m7_sem/verdict_M7sem.json
new file mode 100644
index 0000000000000000000000000000000000000000..f442e8010fc98241e3e21d016b6a591b7cff71ab
--- /dev/null
+++ b/results/hashing/m7_sem/verdict_M7sem.json
@@ -0,0 +1,471 @@
+{
+ "mandat": "M7sem — SPIRA Hashing",
+ "verdict": "OUI",
+ "verdict_why": "vs aléatoire apparié: OK ; vs hash aléatoire: OK (δ=0.04167)",
+ "rule": {
+ "PREDECL_M7sem.md": "322912a0508ca3eb13929b6a6f3a671be5bdface2d997bd00613f5a8fd284a10",
+ "amendments": {
+ "AMENDMENT_1_M7sem.md": "cd12e8727a3f5c79547625d759ca4389533081e274f0c9e5adf040c3d4a0b01e",
+ "AMENDMENT_2_M7sem.md": "7dc7e28a12e26d91c812a7b711d1085902bd8fac3b58fa7736d645e2f8e5e9f5",
+ "AMENDMENT_3_M7sem.md": "139992e02ee35d0f6ac0be9239139efe15ddb234a6229c1ed39af9cfd87904f9"
+ },
+ "amendments_nature": "ressources seulement (tailles de tranches / libération mémoire) ; paramètres, graines, règle inchangés ; équivalence vérifiée"
+ },
+ "corpus": {
+ "path": "hashing_gen/corpus_v1b/train.bin",
+ "sha256": "ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3",
+ "bytes_counted": 520785883,
+ "fraction_counted": 1.0,
+ "n_patches": 157653771,
+ "avg_patch_len": 3.303351893815467,
+ "budget_bits": 12.90478515625,
+ "nA_patches": 78969726,
+ "nB_patches": 78684045
+ },
+ "projection": {
+ "frozen_deliverable_proj_F_npz_sha256": "942ad88a387cbae4e22685956fdd7d8006da643b4dba659b23fca1d1b87ac94b",
+ "proj_F_rows_sha256": "6f46591677ceb8ac91f70f5fab3be788d88f4184f3ba66b227f6f02890638cb0",
+ "tested_proj_A_npz_sha256": "61106ddd330a68daf1c619effd31b79d4b5a0264a2f8ad68b9becb644ef8b330",
+ "proj_A_rows_sha256": "3dc871f7c0e36d30b9499811be4810716fa6dd93d7ac9cbf63567413c5b80f06",
+ "meta": {
+ "A": {
+ "proj_sha256": "3dc871f7c0e36d30b9499811be4810716fa6dd93d7ac9cbf63567413c5b80f06",
+ "sem_sha256": "30b45af1cb058cd63fdcb762e1c8162087cf19504832123f9c0ef07ba8c415ac",
+ "base_sha256": "9eaf9af570b061314305c6f17b6d06cebc75ae6b7f9b3a599e3b93d9c4aaeb18",
+ "vocab_sha256": "e3b07f11b7ce2dc6c2434512396854b683286d8ac7c5ba5b629ab03f9412b9cb",
+ "n_with_ctx": 16384,
+ "d_in": 5120,
+ "k_in": 36
+ },
+ "F": {
+ "proj_sha256": "6f46591677ceb8ac91f70f5fab3be788d88f4184f3ba66b227f6f02890638cb0",
+ "sem_sha256": "73fcb29d4bb4789753f26d6eb5e78da61be7d566af4c1aef1cafeff0dadce76b",
+ "base_sha256": "c961b015c990900ed8906cbbfb6b882b6d4e9ef5dc2267cc995601cfe7180831",
+ "vocab_sha256": "6eb21c1c103397cbe627370952067f2f386f272e4904aa73c6c4ab1c435d8bd1",
+ "n_with_ctx": 16384,
+ "d_in": 5120,
+ "k_in": 36
+ },
+ "peak_rss_mb": 163.3,
+ "min_memavail_kb": 7633536
+ },
+ "d_in": 5120,
+ "k_in": 36,
+ "cm_block": [
+ 1024,
+ 5120
+ ],
+ "cm_k": 24
+ },
+ "determinism_two_full_builds": {
+ "all_equal": true,
+ "files": {
+ "ids.u64": {
+ "eq": true,
+ "sha256": "8a870fe8589534ccd9943a58c8c09ebf1db587de6bc0b2b37c35207e325abc5d"
+ },
+ "lens.u8": {
+ "eq": true,
+ "sha256": "2d353c95889cdfb4e8f3c863edf9ce16135806cd793f15179c7e5fde33496fb0"
+ },
+ "vocab_A.npy": {
+ "eq": true,
+ "sha256": "35e09d6f434375ddcc139e3bd324fcdc43d2ff1f4414c441cd0382412a933f5f"
+ },
+ "vocab_F.npy": {
+ "eq": true,
+ "sha256": "0ec727b4dd3caf1ef062d9ca48878b1d66ad6c8e8ace9211d7c6f532c32d7d28"
+ },
+ "colsA.u16": {
+ "eq": true,
+ "sha256": "49d26b84a6cba836fa7694eb093177f2cd176e9ed1edcd43a30dd52fc5af6004"
+ },
+ "colsF.u16": {
+ "eq": true,
+ "sha256": "2c4078115d1073d3ec4914866287f16c97fb41dc59009d13fff2877fbdf09a41"
+ },
+ "colcounts.npz": {
+ "eq": true,
+ "sha256": "1c21052f95a2845e3b44e70ce90dccba6a0582a2bd239541f3aa5a677410073a"
+ },
+ "topA.npy": {
+ "eq": true,
+ "sha256": "ee4fb58d7204684378bdbee283716e0be1a8aa78270ffc0d77a7cd5e1e41c56a"
+ },
+ "topF.npy": {
+ "eq": true,
+ "sha256": "e7a95a806d03c32cd776e284b9d52f68f1c73a678e8dcdbb2ee4bb9eba5ea998"
+ },
+ "ppmiB.npz": {
+ "eq": true,
+ "sha256": "a0692270bee7a3256177bd12275ffccc7e9a0defe7ca47ce94f76160a9d6046a"
+ },
+ "proj_A.npz": {
+ "eq": true,
+ "sha256": "61106ddd330a68daf1c619effd31b79d4b5a0264a2f8ad68b9becb644ef8b330"
+ },
+ "proj_F.npz": {
+ "eq": true,
+ "sha256": "942ad88a387cbae4e22685956fdd7d8006da643b4dba659b23fca1d1b87ac94b"
+ }
+ }
+ },
+ "equivalence_tests_final_code": {
+ "logs/final_t3m_t_equiv.log": [
+ "true"
+ ],
+ "logs/final_t6m_t_split.log": [
+ "true"
+ ]
+ },
+ "unit_tests": {
+ "logs/unit_count_file.log": "count_file multi-chunk == np.unique: True 45667",
+ "logs/t_a3b_unit.log": {
+ "overlap_equal": true,
+ "boot_equal": true,
+ "perm_equal": true,
+ "perm_equal_near_null": true,
+ "boot_equal_n16331_B10000": true,
+ "perm_equal_n16331_N10000": true,
+ "boot_equal_n4001_B10000": true,
+ "perm_equal_n4001_N10000": true,
+ "boot_equal_n57_B10000": true,
+ "perm_equal_n57_N10000": true
+ }
+ },
+ "coverage": {
+ "vocab_A_token_coverage_on_A": 0.8364741825240726,
+ "vocab_A_token_coverage_on_B": 0.8237726339564775,
+ "vocab_F_coverage": 0.8323738922806991,
+ "tokens_B_in_E_frac": 0.823740251279659,
+ "tokens_A_in_E_frac": 0.8356001640426105
+ },
+ "cooc": {
+ "tot": {
+ "A": 224109796.0,
+ "B": 216801612.0,
+ "F": 443154720.0
+ },
+ "distinct_pairs_nnz": {
+ "A": 28519961,
+ "B": 29363832,
+ "F": 43215728
+ }
+ },
+ "analysis": {
+ "params": {
+ "MIN_B_COUNT": 50,
+ "MIN_B_NNZ": 5,
+ "K_NEI": 5,
+ "MIN_COS": 0.2,
+ "EXCL_TOP": 50,
+ "R_RAND": 5,
+ "NBINS": 20,
+ "DELTA": 0.041666666666666664,
+ "B_BOOT": 10000,
+ "SEED_BOOT": 0,
+ "SEED_PAIRS": 20261024,
+ "N_PERM": 10000,
+ "SEED_PERM": 1
+ },
+ "n_vocab_A": 16384,
+ "n_has_ctx_A": 16384,
+ "n_eligible": 16331,
+ "n_anchors": 13886,
+ "n_close_pairs": 57678,
+ "n_random_pairs": 288390,
+ "close_cos": {
+ "mean": 0.3016014099121094,
+ "p10": 0.21618956327438354,
+ "p50": 0.2806844413280487
+ },
+ "coverage": {
+ "tokens_B_in_E_frac": 0.823740251279659,
+ "tokens_A_in_E_frac": 0.8356001640426105
+ },
+ "CM24_primary": {
+ "k": 24,
+ "mean_overlap_close": 0.11076219124565113,
+ "mean_overlap_random_matched": 0.006301073777407908,
+ "mean_overlap_close_randomhash": 0.005874568003976096,
+ "mean_overlap_random_randomhash": 0.0058429268236300375,
+ "anchor_mean_close": 0.11344784715220767,
+ "anchor_mean_random": 0.006309312336966089,
+ "anchor_mean_close_hash": 0.005981944244402835,
+ "delta_vs_random": 0.10713853481524156,
+ "delta_vs_random_ci95": [
+ 0.10548042842911326,
+ 0.10884877279474131
+ ],
+ "delta_vs_random_perm_p": 9.999000099990002e-05,
+ "delta_vs_hash": 0.10746590290780483,
+ "delta_vs_hash_ci95": [
+ 0.10580554630363115,
+ 0.10917925553515131
+ ],
+ "delta_vs_hash_perm_p": 9.999000099990002e-05,
+ "mean_shared_neurons_close": 2.6582925898956273,
+ "mean_shared_neurons_random": 0.1512257706577898,
+ "frac_close_pairs_share_ge1": 0.69166753354832,
+ "frac_random_pairs_share_ge1": 0.13764000138701066,
+ "auc_close_vs_random": 0.8105395395660676,
+ "auc_ci95": [
+ 0.8077141058727294,
+ 0.8134252999615206
+ ]
+ },
+ "dose_response_CM24": [
+ {
+ "cos": [
+ 0.2,
+ 0.3
+ ],
+ "n": 34787,
+ "mean_overlap": 0.09190454288479413
+ },
+ {
+ "cos": [
+ 0.3,
+ 0.4
+ ],
+ "n": 16884,
+ "mean_overlap": 0.1300812406222854
+ },
+ {
+ "cos": [
+ 0.4,
+ 0.5
+ ],
+ "n": 4080,
+ "mean_overlap": 0.151031454248366
+ },
+ {
+ "cos": [
+ 0.5,
+ 0.6
+ ],
+ "n": 917,
+ "mean_overlap": 0.17861686659396586
+ },
+ {
+ "cos": [
+ 0.6,
+ 0.8
+ ],
+ "n": 710,
+ "mean_overlap": 0.24401408450704226
+ },
+ {
+ "cos": [
+ 0.8,
+ 1.01
+ ],
+ "n": 300,
+ "mean_overlap": 0.13972222222222225
+ }
+ ],
+ "FULL36_secondary": {
+ "k": 36,
+ "mean_overlap_close": 0.0878613451691575,
+ "mean_overlap_random_matched": 0.008198292435783334,
+ "mean_overlap_close_randomhash": 0.007041487029524063,
+ "mean_overlap_random_randomhash": 0.007002573675308514,
+ "anchor_mean_close": 0.08978644224665398,
+ "anchor_mean_random": 0.008203426312673037,
+ "anchor_mean_close_hash": 0.006973583838771797,
+ "delta_vs_random": 0.08158301593398093,
+ "delta_vs_random_ci95": [
+ 0.08038200495703104,
+ 0.08280378718773504
+ ],
+ "delta_vs_random_perm_p": 9.999000099990002e-05,
+ "delta_vs_hash": 0.08281285840788218,
+ "delta_vs_hash_ci95": [
+ 0.08160682005190413,
+ 0.08403122432799355
+ ],
+ "delta_vs_hash_perm_p": 9.999000099990002e-05,
+ "mean_shared_neurons_close": 3.16300842608967,
+ "mean_shared_neurons_random": 0.29513852768820004,
+ "frac_close_pairs_share_ge1": 0.7731197336939561,
+ "frac_random_pairs_share_ge1": 0.2534449876902805,
+ "auc_close_vs_random": 0.828125905053273,
+ "auc_ci95": [
+ 0.825301003980877,
+ 0.8309767850595965
+ ]
+ },
+ "proxies_secondary": {
+ "case": {
+ "n_pairs": 721,
+ "examples": [
+ [
+ "bea",
+ "Bea"
+ ],
+ [
+ "boo",
+ "Boo"
+ ],
+ [
+ "buf",
+ "Buf"
+ ],
+ [
+ "bui",
+ "Bui"
+ ],
+ [
+ " they s",
+ " They s"
+ ],
+ [
+ " they w",
+ " They w"
+ ],
+ [
+ " they h",
+ " They h"
+ ],
+ [
+ " they a",
+ " They a"
+ ]
+ ],
+ "mean_overlap_close": 0.06096856218215441,
+ "mean_overlap_random_matched": 0.006703652334720297,
+ "mean_overlap_randomhash": 0.005547850208044383,
+ "delta_vs_random": 0.054264909847434116,
+ "delta_vs_random_ci95": [
+ 0.04769995376791493,
+ 0.06117660656495608
+ ],
+ "delta_vs_hash": 0.05542071197411003,
+ "delta_vs_hash_ci95": [
+ 0.04889042995839112,
+ 0.0623555247341655
+ ]
+ },
+ "space": {
+ "n_pairs": 1509,
+ "examples": [
+ [
+ "Even",
+ " Even"
+ ],
+ [
+ "bea",
+ " bea"
+ ],
+ [
+ "bef",
+ " bef"
+ ],
+ [
+ "beg",
+ " beg"
+ ],
+ [
+ "beh",
+ " beh"
+ ],
+ [
+ "bei",
+ " bei"
+ ],
+ [
+ "bel",
+ " bel"
+ ],
+ [
+ "bes",
+ " bes"
+ ]
+ ],
+ "mean_overlap_close": 0.16926220455047494,
+ "mean_overlap_random_matched": 0.00605257344819969,
+ "mean_overlap_randomhash": 0.006157499447757897,
+ "delta_vs_random": 0.16320963110227524,
+ "delta_vs_random_ci95": [
+ 0.1551964601281202,
+ 0.17162041639054562
+ ],
+ "delta_vs_hash": 0.16310470510271702,
+ "delta_vs_hash_ci95": [
+ 0.155124806715264,
+ 0.17147117296222664
+ ]
+ }
+ },
+ "circular_descriptive_projF": {
+ "status": "692 patches de E absents/sans contexte dans vocab_F ; non calculé"
+ },
+ "verdict_rule_output": {
+ "verdict": "OUI",
+ "why": "vs aléatoire apparié: OK ; vs hash aléatoire: OK (δ=0.04167)"
+ },
+ "peak_rss_mb": 251.7,
+ "min_memavail_kb": 7752192
+ },
+ "peak_rss_mb_per_step": {
+ "s1_segment.py_work_full.log": 207.7,
+ "s1_segment.py_work_full_r2.log": 207.9,
+ "s2_vocab.py_work_full.log": 144.9,
+ "s2_vocab.py_work_full_r2.log": 144.9,
+ "s3_cols.py_work_full.log": 123.9,
+ "s3_cols.py_work_full_r2.log": 123.9,
+ "s4_cooc.py_work_full.log": 222.6,
+ "s4_cooc.py_work_full_r2.log": 222.2,
+ "s5_proj.py_work_full.log": 163.3,
+ "s5_proj.py_work_full_r2.log": 164.8,
+ "s6_analysis_a3 (out json)": 251.7
+ },
+ "peak_rss_mb_max_completed": 251.7,
+ "guard_self_aborts": [
+ "s2 20:24 RSS 368 Mo (amend. 1)",
+ "s2 20:27 RSS 371 Mo (amend. 2)",
+ "s6 20:35:14 RSS 409 Mo (amend. 3)",
+ "s6_a3 20:39:37 RSS 299,5 Mo (amend. 3b)"
+ ],
+ "inputs_sha256": {
+ "/workspace/SPIRA/python/spira/ept.py": "d8222aabb3d4617bdce64977f38c454f69615c8681cb1652e9f44c36bf7a1c04",
+ "/workspace/SPIRA/python/spira/hashing.py": "f26903e19cd92963e84d6271fc296d4998c4b364ce28be712241236391c2ab02",
+ "/workspace/SPIRA/python/spira/model.py": "81021ea0bebd1a1743e2b4f232a825c532db56b9cee2f59df401b8b1df24d6ab",
+ "/workspace/spira_shared/semhash/countmin.py": "caab50405e73eba7981f73a63fb1709139aed55383501c3e830e174cb02b8d3b",
+ "repo_HEAD": "6923c5191049ee488d9418c7002f108abd9e8ea1"
+ },
+ "scripts_sha256": {
+ "code/chain_full.sh": "c869d1a0c2d1933895590f07bb15c676c029f4c4b27e256cad91ed94cd1b0971",
+ "code/chain_full_v2.sh": "4f1dbd6824483d2622f324d7adc3b182250293a36a278c3458f8fb934cb6f517",
+ "code/chain_full_v3.sh": "24897e841509620ad80e48b71d7783a2be76f8ff09c52e690ce41a0f967ecb4f",
+ "code/common.py": "ee0673148572f8acc863685fafc6df0410093dcb97ea576fb87f589ce58c63b4",
+ "code/make_verdict.py": "65580aaf66b0cb57b5d443586a3a4e878ac53a5e04c1886cccd70cacc465d3c4",
+ "code/run.sh": "4bc12ca27fb51df292bba74ad11c255eb82f580971a96e624d733af43a7dc55b",
+ "code/s1_segment.py": "4a44de5996245b693d61dab1c32150f8818bd6c1b7e510f68fa026a510adcff7",
+ "code/s2_vocab.py": "4f3113ea27ff0cd51d9fa0f4c899dbcf24518bfa5e8ac0454231e3ca4ba80ffe",
+ "code/s3_cols.py": "e0484a4acf6afa1c061e63c6cb36b9db2a71a066c8714f1f47efb59d7f0fdf0c",
+ "code/s4_cooc.py": "727b8c0d90e04da88d72b9b902e7cddda4d9956ad647a1825765d0d653dde632",
+ "code/s5_proj.py": "cd27b0cbddfa181872795dfaec6b469f89f418fc884b9a1f16908c9925c7ef22",
+ "code/s6_analysis.py": "5d0bf51055b37128ad9e125b90d9e1ce0d31f7fc67ac43b8893b9f0793773a60",
+ "code/s6_analysis_a3.py": "ef3273c8ffc8a42de9ca061d9d6501af68e77e699f9f4ef58129d83d25fd0d52",
+ "code/t_a3_unit.py": "a1351625335d20e9a22878d06d97701683068797ed81a022c79a902870051d97",
+ "code/t_equiv.py": "075eb1435c087c82612d1e58eca03dae8665bb275eaa43a2b2aa053578dcb738",
+ "code/t_split.py": "7b2c33c394c2e44f75050037ef9c5b52e4c2a13a42ac2523bcf61c0f39016f3b"
+ },
+ "outputs_sha256": {
+ "out/analysis_M7sem.json": "0c2c6b563bb6a60f3821528b42c9b5fbeeca26246579c89b83ba3249341a1ca5",
+ "work/full.cols.json": "ef3faa8c5cd2d227c659b69ebaeaac7d0ebcd7cd7afe0e97f08bec2e7b920625",
+ "work/full.cooc.json": "7ea1b1239b02100dd43c596444d17506e182cd6f967d061d9efda5b789d5300c",
+ "work/full.proj.json": "e804914aef7adeeb14545d3419513af228409966fe47cd8d4e3dfe1dc9f9cc67",
+ "work/full.seg.json": "b2f50b66cfbf0445f4632e956c57ab3b2c6cbc17e524cc7c149d4df7de1df480",
+ "work/full.vocab.json": "76cce67f73a44ab39f9a989d5e7fa3afea05a51b074def9985728b5b9cf350ce",
+ "work/full.colcounts.npz": "1c21052f95a2845e3b44e70ce90dccba6a0582a2bd239541f3aa5a677410073a",
+ "work/full.ppmiB.npz": "a0692270bee7a3256177bd12275ffccc7e9a0defe7ca47ce94f76160a9d6046a",
+ "work/full.proj_A.npz": "61106ddd330a68daf1c619effd31b79d4b5a0264a2f8ad68b9becb644ef8b330",
+ "work/full.proj_F.npz": "942ad88a387cbae4e22685956fdd7d8006da643b4dba659b23fca1d1b87ac94b",
+ "work/full.topA.npy": "ee4fb58d7204684378bdbee283716e0be1a8aa78270ffc0d77a7cd5e1e41c56a",
+ "work/full.topF.npy": "e7a95a806d03c32cd776e284b9d52f68f1c73a678e8dcdbb2ee4bb9eba5ea998",
+ "work/full.vocab_A.npy": "35e09d6f434375ddcc139e3bd324fcdc43d2ff1f4414c441cd0382412a933f5f",
+ "work/full.vocab_F.npy": "0ec727b4dd3caf1ef062d9ca48878b1d66ad6c8e8ace9211d7c6f532c32d7d28"
+ }
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/verdict_M7sem.md b/results/hashing/m7_sem/verdict_M7sem.md
new file mode 100644
index 0000000000000000000000000000000000000000..ddda8d99e97fd8f68cb244a03289cbf692df4e3e
--- /dev/null
+++ b/results/hashing/m7_sem/verdict_M7sem.md
@@ -0,0 +1,50 @@
+# Verdict M7sem — SPIRA Hashing — 2026-10-24 20 h 55 (Toronto)
+
+## Verdict (règle pré-déclarée, PREDECL_M7sem.md sha 322912a0508ca3eb13929b6a6f3a671be5bdface2d997bd00613f5a8fd284a10) : **OUI**
+Sur le bloc CM24 de proj_A (construite sur la moitié A seule), les patches proches (proximité définie sur la moitié B, disjointe) partagent nettement plus
+de neurones d'entrée que les paires aléatoires appariées en fréquence et que le hash aléatoire de mêmes d/k. Les deux Δ dépassent δ = 1/24 = 0,04167, avec la borne basse de l'IC95 > 0.
+Déterminisme : 2 constructions complètes indépendantes ont donné les 12 fichiers identiques au sha près. Équivalence avec le code de référence (code final) : ALL_EQUAL.
+
+## Corpus et comptage
+- corpus_v1b/train.bin (sha ddf67ffb…63ddb3), **520 785 883 octets comptés = 100 %**. C'est le corpus élargi défini par la chaîne M8 v1b (bras cm) ; le bras cm M8 n'en utilise qu'un échantillon de 35 Mo.
+- 157 653 771 patches EPT (longueur moyenne 3,3034 o ; budget 12,90478515625 bits). A = 78 969 726, B = 78 684 045 (blocs de 8 Mio pairs/impairs).
+- Comptes EXACTS (aucune approximation). Couverture en tokens de vocab_A : 83,65 % sur A, 82,38 % sur B ; vocab_F : 83,24 %. Tokens de B couverts par E : 82,37 %.
+- Paires de co-occurrence distinctes (±2) : A 28 519 961, B 29 363 832, F 43 215 728.
+
+## Projection figée (livrable)
+- proj_F.npz sha256 942ad88a387cbae4e22685956fdd7d8006da643b4dba659b23fca1d1b87ac94b (lignes : 6f46591677ceb8ac91f70f5fab3be788d88f4184f3ba66b227f6f02890638cb0), d_in 5120, k_in 36.
+- proj_A.npz (projection testée) : sha 61106ddd330a68daf1c619effd31b79d4b5a0264a2f8ad68b9becb644ef8b330 (lignes 3dc871f7…).
+- Configuration du bras cm M8 v1b : countmin.py caab5040…, EPT/hashing/model du repo 6923c519 (lecture seule).
+
+## Chiffres (CM24, primaire ; n = 16 331 éligibles, 13 886 ancres, 57 678 paires proches, 288 390 aléatoires)
+| | valeur | IC95 (bootstrap par ancre, B = 10 000) | p (permutation, 10 000) |
+|---|---|---|---|
+| Δ_rand (proches − aléatoires appariées) | 0,10714 | [0,10548 ; 0,10885] | 9,999e-5 (minimum atteignable) |
+| Δ_hash (proj_A − hash aléatoire, mêmes paires proches) | 0,10747 | [0,10581 ; 0,10918] | 9,999e-5 (minimum atteignable) |
+- Chevauchement moyen : proches 0,11076 (2,658 neurones sur 24) ; aléatoires appariées 0,00630 (0,151) ; hash aléatoire 0,00587. Le hasard théorique est d'environ 0,006.
+- Part des paires partageant au moins 1 neurone : proches 69,17 %, aléatoires 13,76 %. AUC proches vs aléatoires : 0,8105 [0,8077 ; 0,8134]. L'ancien M7 avait 0,619, mais ce chiffre n'est pas revérifiable et le protocole est différent : ne pas comparer.
+- Cosinus des paires proches : moyenne 0,302, médiane 0,281, p10 0,216.
+- Dose-réponse (chevauchement moyen par tranche de cosinus) : 0,2–0,3 : 0,092 (n 34 787) ; 0,3–0,4 : 0,130 (16 884) ; 0,4–0,5 : 0,151 (4 080) ; 0,5–0,6 : 0,179 (917) ; 0,6–0,8 : 0,244 (710) ; ≥ 0,8 : **0,140 (300), non monotone**.
+- Secondaire FULL36 : Δ_rand 0,08158 [0,08038 ; 0,08280] ; Δ_hash 0,08281 [0,08161 ; 0,08403] ; AUC 0,8281 [0,8253 ; 0,8310].
+- Proxys objectifs (secondaires, dans vocab_A) :
+ - casse, 721 paires : Δ_rand 0,0543 [0,0477 ; 0,0612], Δ_hash 0,0554 [0,0489 ; 0,0624] ;
+ - espace initial, 1 509 paires : Δ_rand 0,1632 [0,1552 ; 0,1716], Δ_hash 0,1631 [0,1551 ; 0,1715].
+- Descriptif circulaire proj_F : **NON CALCULÉ**, car 692 patches de E sont absents de vocab_F ou sans contexte (le script exige l'identité complète).
+
+## Réserves (honnêteté)
+1. La « proximité » est distributionnelle : cosinus PPMI ±2 sur B. La projection vient elle aussi des co-occurrences (sur A). Le test est non circulaire au sens des données (moitiés disjointes), mais il mesure la préservation de la similarité distributionnelle, ce qui n'est pas une sémantique au sens fort. Les patches sont des fragments d'octets (exemples de proxy : "bea"/"Bea", " they s"/" They s").
+2. L'IC est un bootstrap par ancre. Les dépendances via le membre j (partagé entre ancres) ne sont pas modélisées. L'effet vaut environ 65 fois la demi-largeur de l'IC, donc ce point ne peut pas inverser le verdict.
+3. La dose-réponse chute au-dessus de 0,8 (n = 300).
+4. Trois amendements, tous de ressources seulement (tailles de tranches, libération de mémoire), rédigés avant toute sortie de mesure complète, avec équivalence vérifiée :
+ - le s6 ancien et le nouveau donnent un JSON identique sur t6m ;
+ - le test unitaire overlap/boot/perm est bit-identique à n = 16 331 ;
+ - avant l'amendement 3b, les seuls nombres vus étaient E = 16 331 et les comptes de paires.
+5. Quatre auto-arrêts de la garde : 368, 371, 409 et 299,5 Mo. **La garde échantillonne : la RSS a donc dépassé brièvement 300 Mo trois fois** avant l'arrêt de mes propres processus. Aucun autre processus n'a été touché ; MemAvailable est resté ≥ 7,2 Go.
+6. Fumée pré-gel sur 6 Mo (NON MESURABLE, E = 1835), exclue et déclarée. Sur t3m, s6 échoue sur un tableau vide (cas dégénéré préexistant).
+7. Emplacement : le mandat disait /tmp. Tout est dans hashing_gen/m7_sem/, car /tmp a été effacé au redémarrage et les résultats M7 précédents ont été perdus.
+
+## Ressources
+- RSS maximale des étapes terminées : 251,7 Mo (s6). Les autres : s1 207,9, s2 144,9, s3 123,9, s4 222,6, s5 164,8 Mo.
+- Configuration : nice 10, 1 thread, PYTHONHASHSEED=0, un processus à la fois. Zéro backprop.
+
+Tous les sha (entrées, scripts, sorties, déterminisme) sont dans verdict_M7sem.json, SHA256SUMS_predecl et logs/determinism_r1_r2.txt.
diff --git a/results/hashing/m7_sem/work/full.cols.json b/results/hashing/m7_sem/work/full.cols.json
new file mode 100644
index 0000000000000000000000000000000000000000..f9d2056828d9f05b8764b114d269b1447fa55974
--- /dev/null
+++ b/results/hashing/m7_sem/work/full.cols.json
@@ -0,0 +1,10 @@
+{
+ "bytes": 520785883,
+ "colsA_sha256": "49d26b84a6cba836fa7694eb093177f2cd176e9ed1edcd43a30dd52fc5af6004",
+ "colsF_sha256": "2c4078115d1073d3ec4914866287f16c97fb41dc59009d13fff2877fbdf09a41",
+ "coverage_A_on_A": 0.8364741825240726,
+ "coverage_A_on_B": 0.8237726339564775,
+ "coverage_F": 0.8323738922806991,
+ "peak_rss_mb": 123.9,
+ "min_memavail_kb": 8004512
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/full.cooc.json b/results/hashing/m7_sem/work/full.cooc.json
new file mode 100644
index 0000000000000000000000000000000000000000..7198f78a41953bf3a771161d6e3a8a174989aca9
--- /dev/null
+++ b/results/hashing/m7_sem/work/full.cooc.json
@@ -0,0 +1,23 @@
+{
+ "T": 157653771,
+ "tot": {
+ "A": 224109796.0,
+ "B": 216801612.0,
+ "F": 443154720.0
+ },
+ "distinct_pairs_nnz": {
+ "A": 28519961,
+ "B": 29363832,
+ "F": 43215728
+ },
+ "npw": 512,
+ "kb": 256,
+ "topA_sha256": "1164d0617fa6fceb47b88fa7fb7520d98d7b0e23aee6b2ee661e5fba532dd6de",
+ "topA_rows_with_ctx": 16384,
+ "topF_sha256": "da2a491a4cb9a777ebd0e076e0e2007965c18be5cfae4b1c32893dd60699c8cc",
+ "topF_rows_with_ctx": 16384,
+ "ppmiB_ctx_sha256": "8e04d8f6aac7d00d6442dbbbd9b247684909e6849431af58cb59a8c214314f95",
+ "ppmiB_val_sha256": "7c4b528253f44665bf70fa4366365325c9c720090e53bc9906da43c48333b8cc",
+ "peak_rss_mb": 222.6,
+ "min_memavail_kb": 7242032
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/full.proj.json b/results/hashing/m7_sem/work/full.proj.json
new file mode 100644
index 0000000000000000000000000000000000000000..6a49a7c784749a137b3252bae56620e5abfc1031
--- /dev/null
+++ b/results/hashing/m7_sem/work/full.proj.json
@@ -0,0 +1,22 @@
+{
+ "A": {
+ "proj_sha256": "3dc871f7c0e36d30b9499811be4810716fa6dd93d7ac9cbf63567413c5b80f06",
+ "sem_sha256": "30b45af1cb058cd63fdcb762e1c8162087cf19504832123f9c0ef07ba8c415ac",
+ "base_sha256": "9eaf9af570b061314305c6f17b6d06cebc75ae6b7f9b3a599e3b93d9c4aaeb18",
+ "vocab_sha256": "e3b07f11b7ce2dc6c2434512396854b683286d8ac7c5ba5b629ab03f9412b9cb",
+ "n_with_ctx": 16384,
+ "d_in": 5120,
+ "k_in": 36
+ },
+ "F": {
+ "proj_sha256": "6f46591677ceb8ac91f70f5fab3be788d88f4184f3ba66b227f6f02890638cb0",
+ "sem_sha256": "73fcb29d4bb4789753f26d6eb5e78da61be7d566af4c1aef1cafeff0dadce76b",
+ "base_sha256": "c961b015c990900ed8906cbbfb6b882b6d4e9ef5dc2267cc995601cfe7180831",
+ "vocab_sha256": "6eb21c1c103397cbe627370952067f2f386f272e4904aa73c6c4ab1c435d8bd1",
+ "n_with_ctx": 16384,
+ "d_in": 5120,
+ "k_in": 36
+ },
+ "peak_rss_mb": 163.3,
+ "min_memavail_kb": 7633536
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/full.seg.json b/results/hashing/m7_sem/work/full.seg.json
new file mode 100644
index 0000000000000000000000000000000000000000..f5f8b447e8479199b1f4dd485796cb7575f48b92
--- /dev/null
+++ b/results/hashing/m7_sem/work/full.seg.json
@@ -0,0 +1,15 @@
+{
+ "corpus": "/workspace/spira_shared/hashing_gen/corpus_v1b/train.bin",
+ "limit": 0,
+ "bytes": 520785883,
+ "n_patches": 157653771,
+ "avg_len": 3.303351893815467,
+ "budget_bits": 12.90478515625,
+ "log2p_sha256": "a61967716dfd3e4890f6bd1474cf2fdf63ca9c2373093c4146982d50b42b038d",
+ "ch": 2097152,
+ "ids_sha256": "8a870fe8589534ccd9943a58c8c09ebf1db587de6bc0b2b37c35207e325abc5d",
+ "lens_sha256": "2d353c95889cdfb4e8f3c863edf9ce16135806cd793f15179c7e5fde33496fb0",
+ "seg_s": 228.1,
+ "peak_rss_mb": 207.7,
+ "min_memavail_kb": 7642172
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/full.vocab.json b/results/hashing/m7_sem/work/full.vocab.json
new file mode 100644
index 0000000000000000000000000000000000000000..fcffdcc241032a786dc8357eb213eeb912e3160f
--- /dev/null
+++ b/results/hashing/m7_sem/work/full.vocab.json
@@ -0,0 +1,21 @@
+{
+ "T": 157653771,
+ "nA": 78969726,
+ "nB": 78684045,
+ "distinct": {
+ "A": 263697,
+ "B": 278632,
+ "F": 326629
+ },
+ "split_block": 8388608,
+ "vocab_A_sha256": "e3b07f11b7ce2dc6c2434512396854b683286d8ac7c5ba5b629ab03f9412b9cb",
+ "vocab_A_n": 16384,
+ "vocab_A_min_count": 709,
+ "vocab_A_count_sum": 66056137,
+ "vocab_F_sha256": "6eb21c1c103397cbe627370952067f2f386f272e4904aa73c6c4ab1c435d8bd1",
+ "vocab_F_n": 16384,
+ "vocab_F_min_count": 1417,
+ "vocab_F_count_sum": 131226883,
+ "peak_rss_mb": 144.9,
+ "min_memavail_kb": 7903640
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/full_r2.cols.json b/results/hashing/m7_sem/work/full_r2.cols.json
new file mode 100644
index 0000000000000000000000000000000000000000..0fad2fbb0fd85ef0ac43d4b6fab54c88e300a841
--- /dev/null
+++ b/results/hashing/m7_sem/work/full_r2.cols.json
@@ -0,0 +1,10 @@
+{
+ "bytes": 520785883,
+ "colsA_sha256": "49d26b84a6cba836fa7694eb093177f2cd176e9ed1edcd43a30dd52fc5af6004",
+ "colsF_sha256": "2c4078115d1073d3ec4914866287f16c97fb41dc59009d13fff2877fbdf09a41",
+ "coverage_A_on_A": 0.8364741825240726,
+ "coverage_A_on_B": 0.8237726339564775,
+ "coverage_F": 0.8323738922806991,
+ "peak_rss_mb": 123.9,
+ "min_memavail_kb": 8507576
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/full_r2.cooc.json b/results/hashing/m7_sem/work/full_r2.cooc.json
new file mode 100644
index 0000000000000000000000000000000000000000..e254a268d1dd322c8b0737c237b07e03b5d88b9f
--- /dev/null
+++ b/results/hashing/m7_sem/work/full_r2.cooc.json
@@ -0,0 +1,23 @@
+{
+ "T": 157653771,
+ "tot": {
+ "A": 224109796.0,
+ "B": 216801612.0,
+ "F": 443154720.0
+ },
+ "distinct_pairs_nnz": {
+ "A": 28519961,
+ "B": 29363832,
+ "F": 43215728
+ },
+ "npw": 512,
+ "kb": 256,
+ "topA_sha256": "1164d0617fa6fceb47b88fa7fb7520d98d7b0e23aee6b2ee661e5fba532dd6de",
+ "topA_rows_with_ctx": 16384,
+ "topF_sha256": "da2a491a4cb9a777ebd0e076e0e2007965c18be5cfae4b1c32893dd60699c8cc",
+ "topF_rows_with_ctx": 16384,
+ "ppmiB_ctx_sha256": "8e04d8f6aac7d00d6442dbbbd9b247684909e6849431af58cb59a8c214314f95",
+ "ppmiB_val_sha256": "7c4b528253f44665bf70fa4366365325c9c720090e53bc9906da43c48333b8cc",
+ "peak_rss_mb": 222.2,
+ "min_memavail_kb": 7841824
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/full_r2.proj.json b/results/hashing/m7_sem/work/full_r2.proj.json
new file mode 100644
index 0000000000000000000000000000000000000000..3e7c15365ad985ed542aec89ecd18b3071882981
--- /dev/null
+++ b/results/hashing/m7_sem/work/full_r2.proj.json
@@ -0,0 +1,22 @@
+{
+ "A": {
+ "proj_sha256": "3dc871f7c0e36d30b9499811be4810716fa6dd93d7ac9cbf63567413c5b80f06",
+ "sem_sha256": "30b45af1cb058cd63fdcb762e1c8162087cf19504832123f9c0ef07ba8c415ac",
+ "base_sha256": "9eaf9af570b061314305c6f17b6d06cebc75ae6b7f9b3a599e3b93d9c4aaeb18",
+ "vocab_sha256": "e3b07f11b7ce2dc6c2434512396854b683286d8ac7c5ba5b629ab03f9412b9cb",
+ "n_with_ctx": 16384,
+ "d_in": 5120,
+ "k_in": 36
+ },
+ "F": {
+ "proj_sha256": "6f46591677ceb8ac91f70f5fab3be788d88f4184f3ba66b227f6f02890638cb0",
+ "sem_sha256": "73fcb29d4bb4789753f26d6eb5e78da61be7d566af4c1aef1cafeff0dadce76b",
+ "base_sha256": "c961b015c990900ed8906cbbfb6b882b6d4e9ef5dc2267cc995601cfe7180831",
+ "vocab_sha256": "6eb21c1c103397cbe627370952067f2f386f272e4904aa73c6c4ab1c435d8bd1",
+ "n_with_ctx": 16384,
+ "d_in": 5120,
+ "k_in": 36
+ },
+ "peak_rss_mb": 164.8,
+ "min_memavail_kb": 8855040
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/full_r2.seg.json b/results/hashing/m7_sem/work/full_r2.seg.json
new file mode 100644
index 0000000000000000000000000000000000000000..263fca528d4733358fbcadccf304d25477818b51
--- /dev/null
+++ b/results/hashing/m7_sem/work/full_r2.seg.json
@@ -0,0 +1,15 @@
+{
+ "corpus": "/workspace/spira_shared/hashing_gen/corpus_v1b/train.bin",
+ "limit": 0,
+ "bytes": 520785883,
+ "n_patches": 157653771,
+ "avg_len": 3.303351893815467,
+ "budget_bits": 12.90478515625,
+ "log2p_sha256": "a61967716dfd3e4890f6bd1474cf2fdf63ca9c2373093c4146982d50b42b038d",
+ "ch": 2097152,
+ "ids_sha256": "8a870fe8589534ccd9943a58c8c09ebf1db587de6bc0b2b37c35207e325abc5d",
+ "lens_sha256": "2d353c95889cdfb4e8f3c863edf9ce16135806cd793f15179c7e5fde33496fb0",
+ "seg_s": 229.1,
+ "peak_rss_mb": 207.9,
+ "min_memavail_kb": 7705976
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/full_r2.vocab.json b/results/hashing/m7_sem/work/full_r2.vocab.json
new file mode 100644
index 0000000000000000000000000000000000000000..deb5b32d49a04ecfcb213cba3db1953e1da74690
--- /dev/null
+++ b/results/hashing/m7_sem/work/full_r2.vocab.json
@@ -0,0 +1,21 @@
+{
+ "T": 157653771,
+ "nA": 78969726,
+ "nB": 78684045,
+ "distinct": {
+ "A": 263697,
+ "B": 278632,
+ "F": 326629
+ },
+ "split_block": 8388608,
+ "vocab_A_sha256": "e3b07f11b7ce2dc6c2434512396854b683286d8ac7c5ba5b629ab03f9412b9cb",
+ "vocab_A_n": 16384,
+ "vocab_A_min_count": 709,
+ "vocab_A_count_sum": 66056137,
+ "vocab_F_sha256": "6eb21c1c103397cbe627370952067f2f386f272e4904aa73c6c4ab1c435d8bd1",
+ "vocab_F_n": 16384,
+ "vocab_F_min_count": 1417,
+ "vocab_F_count_sum": 131226883,
+ "peak_rss_mb": 144.9,
+ "min_memavail_kb": 8447888
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/t3m.cols.json b/results/hashing/m7_sem/work/t3m.cols.json
new file mode 100644
index 0000000000000000000000000000000000000000..afdc37fa3e1ee59e7da3701b9fe6de572da85fea
--- /dev/null
+++ b/results/hashing/m7_sem/work/t3m.cols.json
@@ -0,0 +1,10 @@
+{
+ "bytes": 3000000,
+ "colsA_sha256": "5e0f0c4939ae93dba8c80866ec41a426a00554f7bf3da63d3e7a7f56f5b46243",
+ "colsF_sha256": "5e0f0c4939ae93dba8c80866ec41a426a00554f7bf3da63d3e7a7f56f5b46243",
+ "coverage_A_on_A": 0.9135354317823906,
+ "coverage_A_on_B": NaN,
+ "coverage_F": 0.9135354317823906,
+ "peak_rss_mb": 78.7,
+ "min_memavail_kb": 10506992
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/t3m.cooc.json b/results/hashing/m7_sem/work/t3m.cooc.json
new file mode 100644
index 0000000000000000000000000000000000000000..5c9d634290f03c0b39b88ab37228afcb652cbd71
--- /dev/null
+++ b/results/hashing/m7_sem/work/t3m.cooc.json
@@ -0,0 +1,23 @@
+{
+ "T": 666111,
+ "tot": {
+ "A": 2231390.0,
+ "B": 0.0,
+ "F": 2231390.0
+ },
+ "distinct_pairs_nnz": {
+ "A": 1280277,
+ "B": 0,
+ "F": 1280277
+ },
+ "npw": 512,
+ "kb": 256,
+ "topA_sha256": "57d0764a1eed910bd3d65c181487c2cf9445c40619734d4e30232f7f0b0e87db",
+ "topA_rows_with_ctx": 16384,
+ "topF_sha256": "57d0764a1eed910bd3d65c181487c2cf9445c40619734d4e30232f7f0b0e87db",
+ "topF_rows_with_ctx": 16384,
+ "ppmiB_ctx_sha256": "9f9b02f5ee6cbef5e018c1ee424095fc21a842ea6968c0d36114b5930dab2ba1",
+ "ppmiB_val_sha256": "080acf35a507ac9849cfcba47dc2ad83e01b75663a516279c8b9d243b719643e",
+ "peak_rss_mb": 126.9,
+ "min_memavail_kb": 10433424
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/t3m.equiv.json b/results/hashing/m7_sem/work/t3m.equiv.json
new file mode 100644
index 0000000000000000000000000000000000000000..946712e2af5d989c9dff2ee25b717bf0471de53d
--- /dev/null
+++ b/results/hashing/m7_sem/work/t3m.equiv.json
@@ -0,0 +1,17 @@
+{
+ "ids": true,
+ "lens": true,
+ "vocab": true,
+ "cols": true,
+ "top": true,
+ "sem": true,
+ "base": true,
+ "proj": true,
+ "ref_proj_sha256": "eef19441a09736719a66195f114d489661cb9f923dc182ce4b0caac01206cece",
+ "mine_proj_sha256": "eef19441a09736719a66195f114d489661cb9f923dc182ce4b0caac01206cece",
+ "budget_bits": 12.90478515625,
+ "n_patches": 666111,
+ "nbytes": 3000000,
+ "peak_rss_mb": 233.6,
+ "ALL_EQUAL": true
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/t3m.proj.json b/results/hashing/m7_sem/work/t3m.proj.json
new file mode 100644
index 0000000000000000000000000000000000000000..0404f17d7be6f26b029b0cfbd31bad533484260c
--- /dev/null
+++ b/results/hashing/m7_sem/work/t3m.proj.json
@@ -0,0 +1,22 @@
+{
+ "A": {
+ "proj_sha256": "eef19441a09736719a66195f114d489661cb9f923dc182ce4b0caac01206cece",
+ "sem_sha256": "044b767d0c98c97e39c14ad402c54489e14df231ff0e088a67cfa20f2ef34e8f",
+ "base_sha256": "92b450afea868cab7a83f61a7a75852327e1b412cab17726e5eb3263081d2354",
+ "vocab_sha256": "0c4f2ec9c83e85be4f2d3c90e0093e0a80a452ff1aea905598bd207dabae9b8f",
+ "n_with_ctx": 16384,
+ "d_in": 5120,
+ "k_in": 36
+ },
+ "F": {
+ "proj_sha256": "eef19441a09736719a66195f114d489661cb9f923dc182ce4b0caac01206cece",
+ "sem_sha256": "044b767d0c98c97e39c14ad402c54489e14df231ff0e088a67cfa20f2ef34e8f",
+ "base_sha256": "92b450afea868cab7a83f61a7a75852327e1b412cab17726e5eb3263081d2354",
+ "vocab_sha256": "0c4f2ec9c83e85be4f2d3c90e0093e0a80a452ff1aea905598bd207dabae9b8f",
+ "n_with_ctx": 16384,
+ "d_in": 5120,
+ "k_in": 36
+ },
+ "peak_rss_mb": 91.6,
+ "min_memavail_kb": 10444144
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/t3m.seg.json b/results/hashing/m7_sem/work/t3m.seg.json
new file mode 100644
index 0000000000000000000000000000000000000000..03afb5d750fa52ca34ef50b1244d164b39ac6f11
--- /dev/null
+++ b/results/hashing/m7_sem/work/t3m.seg.json
@@ -0,0 +1,15 @@
+{
+ "corpus": "/workspace/spira_shared/hashing_gen/corpus_v1b/train.bin",
+ "limit": 3000000,
+ "bytes": 3000000,
+ "n_patches": 666111,
+ "avg_len": 4.503753878858028,
+ "budget_bits": 12.90478515625,
+ "log2p_sha256": "a61967716dfd3e4890f6bd1474cf2fdf63ca9c2373093c4146982d50b42b038d",
+ "ch": 2097152,
+ "ids_sha256": "a228ac08550c66dd4787975db248e5a662958e10da4d7110a8f52f0dce67f35e",
+ "lens_sha256": "d9ebb1295e654e5823b9d1d940ef6fb9c74bf2aaa8d8c923cb71abae31aa7001",
+ "seg_s": 1.0,
+ "peak_rss_mb": 155.4,
+ "min_memavail_kb": 9106168
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/t3m.vocab.json b/results/hashing/m7_sem/work/t3m.vocab.json
new file mode 100644
index 0000000000000000000000000000000000000000..0bcd2a9fc469d7f9171eeee40cab9e5479082b65
--- /dev/null
+++ b/results/hashing/m7_sem/work/t3m.vocab.json
@@ -0,0 +1,21 @@
+{
+ "T": 666111,
+ "nA": 666111,
+ "nB": 0,
+ "distinct": {
+ "A": 42232,
+ "B": 0,
+ "F": 42232
+ },
+ "split_block": 8388608,
+ "vocab_A_sha256": "0c4f2ec9c83e85be4f2d3c90e0093e0a80a452ff1aea905598bd207dabae9b8f",
+ "vocab_A_n": 16384,
+ "vocab_A_min_count": 6,
+ "vocab_A_count_sum": 608516,
+ "vocab_F_sha256": "0c4f2ec9c83e85be4f2d3c90e0093e0a80a452ff1aea905598bd207dabae9b8f",
+ "vocab_F_n": 16384,
+ "vocab_F_min_count": 6,
+ "vocab_F_count_sum": 608516,
+ "peak_rss_mb": 83.1,
+ "min_memavail_kb": 10537848
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/t6m.cols.json b/results/hashing/m7_sem/work/t6m.cols.json
new file mode 100644
index 0000000000000000000000000000000000000000..0b6647f8b470836f02baaf94712c6fe146c2d415
--- /dev/null
+++ b/results/hashing/m7_sem/work/t6m.cols.json
@@ -0,0 +1,10 @@
+{
+ "bytes": 6000000,
+ "colsA_sha256": "5477df2b41dbef3e60372235db5e5a16414fdbd526cb89017f638db07aaf3e3b",
+ "colsF_sha256": "23923046b47a8233758a43242a18ae3ccad06aa1672f98186404b4f2412ac283",
+ "coverage_A_on_A": 0.9129620017271417,
+ "coverage_A_on_B": 0.9011621639103905,
+ "coverage_F": 0.9112351492282904,
+ "peak_rss_mb": 101.8,
+ "min_memavail_kb": 10506240
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/t6m.cooc.json b/results/hashing/m7_sem/work/t6m.cooc.json
new file mode 100644
index 0000000000000000000000000000000000000000..d6c4caa4627b700a4ea16600e6a68f77bac2adad
--- /dev/null
+++ b/results/hashing/m7_sem/work/t6m.cooc.json
@@ -0,0 +1,23 @@
+{
+ "T": 1328803,
+ "tot": {
+ "A": 2894982.0,
+ "B": 1513284.0,
+ "F": 4430784.0
+ },
+ "distinct_pairs_nnz": {
+ "A": 1576396,
+ "B": 920068,
+ "F": 2187345
+ },
+ "npw": 512,
+ "kb": 256,
+ "topA_sha256": "99996b4fd767bb6f68e2c23757c7ab41e5d4f0d2291d96f0e0f3bae254819fa4",
+ "topA_rows_with_ctx": 16384,
+ "topF_sha256": "313dc81854d9ef7031d59536aed7056f658b8d16e25f303aa646bdb9da28b755",
+ "topF_rows_with_ctx": 16384,
+ "ppmiB_ctx_sha256": "683ca23da1f28d2d23724cd57c10e2a64cd7b483fe7c7e1da3458007c3da1e85",
+ "ppmiB_val_sha256": "22be09bcac6dfb2d619a064d67ec5cc89597fed6d24e940364bb65a2e967919a",
+ "peak_rss_mb": 173.7,
+ "min_memavail_kb": 10333536
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/t6m.proj.json b/results/hashing/m7_sem/work/t6m.proj.json
new file mode 100644
index 0000000000000000000000000000000000000000..59bae8e6bb82d491d1edc878f6f58d5186e561ca
--- /dev/null
+++ b/results/hashing/m7_sem/work/t6m.proj.json
@@ -0,0 +1,22 @@
+{
+ "A": {
+ "proj_sha256": "81de79c90d2ce6547ba69a1d9c62062a7b35d4acfb212e5c25b20585a034795e",
+ "sem_sha256": "830dec17b7175c16c272fef01833c74788e5a40ece79650675fdfab09a0f6a40",
+ "base_sha256": "d3042142fca62390aee59706a45b5f6f7ea7192d52dec250620f935d2c3899d8",
+ "vocab_sha256": "50d990e7c7b319a8a9af8137270537e43ad8717fc4c4467becfcf585fb6c5277",
+ "n_with_ctx": 16384,
+ "d_in": 5120,
+ "k_in": 36
+ },
+ "F": {
+ "proj_sha256": "01174d042b92e333a40a4c8209b00a007c27e14460ab8b3ee0e39b776b814741",
+ "sem_sha256": "b013371d4332989f7e72479a4ddc85deb016ae63b6c5d9ff2322aad207b63cdc",
+ "base_sha256": "49bd5ae146c24889cf10a146e7d6b478832a7fcd42726256e3749038d5955727",
+ "vocab_sha256": "5d7c0e374055acd91328e52eab35c278d6d0529ea5361a3b8741cd4db4e3d74d",
+ "n_with_ctx": 16384,
+ "d_in": 5120,
+ "k_in": 36
+ },
+ "peak_rss_mb": 117.5,
+ "min_memavail_kb": 10357684
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/t6m.seg.json b/results/hashing/m7_sem/work/t6m.seg.json
new file mode 100644
index 0000000000000000000000000000000000000000..84ed8c6fd177bdbd7ae768b26ea7bf21d8a6d53c
--- /dev/null
+++ b/results/hashing/m7_sem/work/t6m.seg.json
@@ -0,0 +1,15 @@
+{
+ "corpus": "/workspace/spira_shared/hashing_gen/corpus_v1b/train.bin",
+ "limit": 6000000,
+ "bytes": 6000000,
+ "n_patches": 1328803,
+ "avg_len": 4.515342003291685,
+ "budget_bits": 12.90478515625,
+ "log2p_sha256": "a61967716dfd3e4890f6bd1474cf2fdf63ca9c2373093c4146982d50b42b038d",
+ "ch": 262144,
+ "ids_sha256": "098582e65c8c8276d4e51fe8d99948f204140fef1692173c8bada953b891a280",
+ "lens_sha256": "dbc68a66de85e3525ee099106d9f41cd2f5bb128b0e8f34ef59af4c7ed4d45d2",
+ "seg_s": 1.8,
+ "peak_rss_mb": 57.6,
+ "min_memavail_kb": 9146884
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/t6m.split_equiv.json b/results/hashing/m7_sem/work/t6m.split_equiv.json
new file mode 100644
index 0000000000000000000000000000000000000000..61fb47b3271803848dfc0504a462796367ab9f7b
--- /dev/null
+++ b/results/hashing/m7_sem/work/t6m.split_equiv.json
@@ -0,0 +1,11 @@
+{
+ "nA": 865013,
+ "nB": 463790,
+ "vocab_A": true,
+ "topA": true,
+ "semA": true,
+ "seg_ch": 262144,
+ "ids_sha256": "098582e65c8c8276d4e51fe8d99948f204140fef1692173c8bada953b891a280",
+ "peak_rss_mb": 264.0,
+ "ALL_EQUAL": true
+}
\ No newline at end of file
diff --git a/results/hashing/m7_sem/work/t6m.vocab.json b/results/hashing/m7_sem/work/t6m.vocab.json
new file mode 100644
index 0000000000000000000000000000000000000000..a98330e3a03ba801d3109dbe63e85ec13f8dd62b
--- /dev/null
+++ b/results/hashing/m7_sem/work/t6m.vocab.json
@@ -0,0 +1,21 @@
+{
+ "T": 1328803,
+ "nA": 865013,
+ "nB": 463790,
+ "distinct": {
+ "A": 45205,
+ "B": 37144,
+ "F": 50559
+ },
+ "split_block": 2097152,
+ "vocab_A_sha256": "50d990e7c7b319a8a9af8137270537e43ad8717fc4c4467becfcf585fb6c5277",
+ "vocab_A_n": 16384,
+ "vocab_A_min_count": 8,
+ "vocab_A_count_sum": 789724,
+ "vocab_F_sha256": "5d7c0e374055acd91328e52eab35c278d6d0529ea5361a3b8741cd4db4e3d74d",
+ "vocab_F_n": 16384,
+ "vocab_F_min_count": 12,
+ "vocab_F_count_sum": 1210852,
+ "peak_rss_mb": 91.7,
+ "min_memavail_kb": 10457756
+}
\ No newline at end of file
diff --git a/results/hashing/m7_v41/SHA256SUMS b/results/hashing/m7_v41/SHA256SUMS
new file mode 100644
index 0000000000000000000000000000000000000000..70112c88c8c31de7ba4dfa29d64c2e4049df6e75
--- /dev/null
+++ b/results/hashing/m7_v41/SHA256SUMS
@@ -0,0 +1,16 @@
+396f11a142475cca3ee413066423aab9d4e3f708db191d3b96b8321875182b5f cm_old_local_v1.npz
+fdee6dc046ea48c19b0c96510eaa6cece2ac4974cb9fd786c9aef142fe8cdfff code/crosscheck_mask_t20k.py
+e7c4ad734a7b2c567fb7c1eb6e827aea15c81673d62180f01bca1e1581d339fa code/mask_old_bench.py
+99ea3a2119dfbdab24f4fc45faed3fb2dd7188a0d3557b4127ef515ea7281f91 code/run_eval_m7_v41.sh
+aa36c8ec8278addf426fd5220db0b446085e5b95003d585778603a30c0a502f7 code/run_m7_old_local_v1.py
+00e2313f3e4c2026099cf071141c793f35a5b407548c8cbe9b2e4ae5ad5fe0e2 code/test_unit_mcn.out
+26d7b4b1b3f4ebd07c4eb5036eb93c01b22cd52156f405e44791111768af36db code/test_unit_mcn.py
+10ac5fed0693523187416793f330aa5d1b76dc06236b015fbb8b50e8be2f6fd1 code/verdict_m7_v41.py
+71505da18db5d189cc9cb4bc0fe748381e08f67bd62548ae456348bf2866baaa crosscheck_mask_t20k.json
+fc089ac386674a7186664cfad06b0d81251ace35e16de1ac12b223617a3e3379 eval_m7_old.log.txt
+77215abd17ace6b1b003254f643e2bddeae8b8115aac3445ca17b2c5192ba1d8 mask_old_bench.json
+e15cf361391e32bcfef97d4982f15fe011e443f2c1a6ef4a3c8120510f2e13a5 run_m7_old.log.txt
+c21c79524c5fe2f480f20453e9c5f0409ce88907d12cc2cda1c5345702028862 selftest_ref_vs_ref.md
+12b3f67e32c412bb590de3f37aeebd8048d16248128fb6e8043929dd80817f7e train_summary.json
+ffe7552f21f12b28089bf9604c74699ff8074543c7d750d7028aaf2ae7830f4c verdict_m7_old_v41.json
+f6a847d5c3e9f3303c2584c5b274f0a691272ba6697b84c59bb716ed602ad9a7 verdict_m7_old_v41.md
diff --git a/results/hashing/m7_v41/hf_push_m7_old.py b/results/hashing/m7_v41/hf_push_m7_old.py
new file mode 100644
index 0000000000000000000000000000000000000000..80cc6a727acbf7edf6e20db1a5876e3b2dffe703
--- /dev/null
+++ b/results/hashing/m7_v41/hf_push_m7_old.py
@@ -0,0 +1,28 @@
+"""SPIRA Hashing — push HF thefinalboss/SPIRA results/hashing/m7_old/ (un seul commit, fichiers lus en flux depuis le disque).
+Refuse si un chemin cible existe déjà (jamais d'écrasement) ou si MemAvailable < 3 Go. Jamais de données d'éval ni de vecteurs de hits."""
+import sys, os, hashlib
+from huggingface_hub import HfApi, CommitOperationAdd
+REPO = "thefinalboss/SPIRA"; P = "results/hashing/m7_old"; M = "/workspace/spira_shared/spira_m7"; D = "/workspace/spira_shared/hashing_gen/m7_v41"
+FILES = {f"{M}/cm_old_local_v1.npz": "cm_old_local_v1.npz", f"{M}/run_m7_old.log": "run_m7_old.log", f"{M}/train_summary.json": "train_summary.json",
+ f"{M}/run_m7_old_local_v1.py": "code/run_m7_old_local_v1.py",
+ f"{D}/verdict_m7_old_v41.md": "verdict_m7_old_v41.md", f"{D}/verdict_m7_old_v41.json": "verdict_m7_old_v41.json",
+ f"{D}/verdict_m7_v41.py": "code/verdict_m7_v41.py", f"{D}/mask_old_bench.py": "code/mask_old_bench.py", f"{D}/mask_old_bench.json": "mask_old_bench.json",
+ f"{D}/crosscheck_mask_t20k.py": "code/crosscheck_mask_t20k.py", f"{D}/crosscheck_mask_t20k.json": "crosscheck_mask_t20k.json",
+ f"{D}/test_unit_mcn.py": "code/test_unit_mcn.py", f"{D}/test_unit_mcn.out": "code/test_unit_mcn.out",
+ f"{D}/selftest_ref_vs_ref.md": "selftest_ref_vs_ref.md", f"{D}/run_eval_m7_v41.sh": "code/run_eval_m7_v41.sh", f"{D}/eval_m7_old.log": "eval_m7_old.log"}
+for k in FILES: assert os.path.isfile(k), k
+assert not any(x in v for v in FILES.values() for x in ("results_gate_v2", "hits", "partial", "nocal")), "fichier interdit"
+ma = int([l for l in open("/proc/meminfo") if l.startswith("MemAvailable")][0].split()[1]); assert ma >= 3 * 1024 * 1024, f"MemAvailable {ma} kB < 3 Go"
+def sha(p):
+ h = hashlib.sha256()
+ with open(p, "rb") as f:
+ for b in iter(lambda: f.read(1 << 20), b""): h.update(b)
+ return h.hexdigest()
+lines = [f"{sha(k)} {v}" for k, v in sorted(FILES.items(), key=lambda kv: kv[1])]
+open(f"{D}/SHA256SUMS", "w").write("\n".join(lines) + "\n"); FILES[f"{D}/SHA256SUMS"] = "SHA256SUMS"; print("\n".join(lines))
+api = HfApi(); ex = set(api.list_repo_files(REPO)); tgt = [f"{P}/{v}" for v in FILES.values()]; clash = [t for t in tgt if t in ex]
+if clash: sys.exit(f"ARRÊT : déjà présents sur HF (pas d'écrasement) : {clash}")
+ops = [CommitOperationAdd(path_in_repo=f"{P}/{v}", path_or_fileobj=k) for k, v in FILES.items()]
+ci = api.create_commit(REPO, operations=ops, commit_message=sys.argv[1] if len(sys.argv) > 1 else "results/hashing/m7_old: M7 old ckpt calibré + verdict v4.1")
+print("COMMIT", ci.oid, ci.commit_url)
+after = set(api.list_repo_files(REPO)); print("VERIF", all(t in after for t in tgt), len(tgt))
diff --git a/results/hashing/m7_v41/relay_entry_verdict.md b/results/hashing/m7_v41/relay_entry_verdict.md
new file mode 100644
index 0000000000000000000000000000000000000000..5986ff28b9be5e1b3daabb109cb76afdca74477e
--- /dev/null
+++ b/results/hashing/m7_v41/relay_entry_verdict.md
@@ -0,0 +1,23 @@
+
+### Hashing — 00 h 40 (America/Toronto) — verdict v4.1 M7 old contre old_ref : **REJETÉ** — demande de PASS Checker avant push HF
+- Candidat : spira_m7/cm_old_local_v1.npz (446 551 146 o, sha256 396f11a1…182b5f, calibré, sauvé 22 h 43). Réf : old_ref (hits checker/scale/hits_v4/old_ref__*.npz, lecture seule ; m9g v2b non utilisé). Éval par eval_bench_v4.py de Checker en CLI (sorties redirigées dans hashing_gen/m7_v41/), 827525, 23 h 33 → 00 h 21, pic RSS 1 004,7 Mo. Tokenizers identiques : appariement par position, hit = fused ∧ invocab. McNemar exact = décision ; bootstrap blocs 512 o, B = 10 000, seed 0 = indicatif.
+
+| fenêtre | n (pos.) / invocab | M7 % | réf % | Δ pts | b réf seule / c M7 seul | p McNemar | IC95 Δ bootstrap | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 8 000 / 5 868 | 98,279 | 98,330 | −0,051 | 8/5 | 0,581 | [−0,170 ; +0,068] | n.s. |
+| fc2 | 8 000 / 4 833 | 12,787 | 11,504 | +1,283 | 87/149 | 6,55e-5 | [+0,450 ; +2,098] | GAIN |
+| fresh_en | 8 000 / 5 714 | 4,533 | 3,395 | +1,138 | 60/125 | 2,01e-6 | [+0,647 ; +1,649] | GAIN |
+| fresh_fr | 8 000 / 3 179 | 0,189 | 0,283 | −0,094 | 7/4 | 0,549 | [−0,292 ; +0,098] | n.s. |
+| test20k propre (masque old) | 20 000 / 13 379 | 3,603 | 2,900 | +0,703 | 155/249 | 3,37e-6 | [+0,388 ; +1,013] | GAIN |
+| test_v3 | 20 000 / 12 922 | 4,697 | 4,117 | +0,580 | 241/316 | 1,69e-3 | [+0,047 ; +1,070] | GAIN |
+| queries (à part) | 7 099 / 3 349 | 1,165 | 0,000 | +1,165 | 0/39 | 3,64e-12 | [+0,968 ; +1,349] | GAIN (réf 0 hit) |
+
+- **Écart seen − moyenne fraîche** (fc2, fresh_en, fresh_fr, test20k propre, test_v3) : M7 +93,117 pts [IC95 +92,630 ; +93,591] (fraîche 5,162 %) ; réf +93,890 [+93,410 ; +94,345] (fraîche 4,440 %) ; M7 − réf −0,773 pt [−1,028 ; −0,508]. L'écart se referme un peu, mais seulement parce que le frais monte ; seen ne bouge pas.
+- **test20k** : broad_local_v1/test.bin. Masque mask_old_bench.npz (64-grammes confirmés contre old_local_v1/train.bin, règle [s−64, s+l)) : 434 640 octets couverts, mais tous à partir de l'octet 144 389, alors que les cibles évaluées sont dans [2 ; 88 765). Il y a donc 0 position exclue, ce que confirme un contre-hash indépendant (crosscheck_mask_t20k.json). Selon la règle strict-clean de Checker (00 h 30, broad_local_v1 inclus, 128 exclues) : 2,906 / 3,603 %, 155/248, p = 4,18e-6, GAIN aussi. J'adopte cette correction pour la suite.
+- **Verdict : REJETÉ.** Il n'y a pas de gain significatif sur seen (8/5, p = 0,581). Il y a des gains sur fc2, fresh_en, test20k et test_v3 (queries à part), et aucune perte significative. M7 old n'est pas appliqué.
+- **Incidents** : 21098 s'est terminé en CalledProcessError (gate final 789343 arrêté par SIGTERM à 23 h 10, alerte mémoire). results_gate_v2.jsonl est incomplet : ni utilisé ni poussé. Le plafond prlimit --as = 1,5 Gio a échoué au chargement (_ArrayMemoryError W_out 416 Mio). Relance unique à 2,5 Gio (VmPeak 1,64 Go).
+- Réf validée Checker citée dans le rapport (results_m8.jsonl l. 1/3/5/7 ; relais l. 3870, 3876, 3890–3891) : fused toutes positions seen 98,06 %, freshcode 55,81 %, fresh_en 3,25 %, fresh_fr 0,075 %.
+- **→ Checker : demande de PASS/FAIL explicite avant push.** Ton recompte de 00 h 27 / 00 h 30 couvre déjà les b/c, p et IC. Il me manque une ligne « PASS » (ou « FAIL ») sur le rapport et la liste de push. Fichiers : hashing_gen/m7_v41/verdict_m7_old_v41.{md,json} (md sha256 520b2027…ac15, json 45899fa1…b870), hits/m7_old__*.npz, results_m7_v41.jsonl (00058dd0…cd27), scripts verdict_m7_v41.py (10ac5fed…6fd1), mask_old_bench.py, crosscheck_mask_t20k.py, test_unit_mcn.py, run_eval_m7_v41.sh, hf_push_m7_old.py.
+- **Push prévu (seulement après PASS et MemAvailable ≥ 5,2 Go)** sous results/hashing/m7_old/ : cm_old_local_v1.npz, run_m7_old.log, train_summary.json, verdict md + json, mask_old_bench.json, crosscheck json, selftest md, eval_m7_old.log, code/ (scripts ci-dessus + run_m7_old_local_v1.py), SHA256SUMS. Pas de hits, pas de données d'éval, pas de results_gate_v2.jsonl, pas de partial/nocal. Je vérifie list_repo_files avant (0 fichier sous m7_old/ à 23 h 08). Sans PASS d'ici ~2 h, je ne pousse rien.
+- Rien tué. Aucun nouveau processus depuis la sortie de 827525 (à part le verdict léger enchaîné, < 5 s). Rien dans /tmp.
+Lu/appliqué — Hashing — SPIRA Hashing
diff --git a/results/hashing/m7_v41/results_m7_v41.jsonl b/results/hashing/m7_v41/results_m7_v41.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..f624800c1f023be5e6204598f8e95d59ded064f4
--- /dev/null
+++ b/results/hashing/m7_v41/results_m7_v41.jsonl
@@ -0,0 +1,7 @@
+{"tag": "m7_old", "corpus": "old_local_v1", "ckpt": "/workspace/spira_shared/spira_m7/cm_old_local_v1.npz", "kind": "cm", "window": "seen", "n_positions": 8000, "fused_invocab_pct": 98.279, "snn_invocab_pct": 29.448, "vocab_coverage": 0.7335, "fusion_saved": {"scale": 0.056658798957008934, "sigma_fast": 0.04551528212138245, "sigma_slow": 0.8033223958015442}, "fusion_cal": {"scale": 0.05598423216016823, "sigma_fast": 0.04552194186279601, "sigma_slow": 0.8131207682291667}, "load_s": 137.9, "eval_s": 256.1, "peak_rss_mb": 997.7, "maxpos": 0, "window_sha256": "7585ad82947bbe8b2ae6484b1922511b483c11d84bde5b0a53978135d0eb99ca", "window_bytes": 200000, "ept_budget_bits": 15.36572265625, "script": "eval_bench_v4.1", "seen_def": "train[2600000:2800000]"}
+{"tag": "m7_old", "corpus": "old_local_v1", "ckpt": "/workspace/spira_shared/spira_m7/cm_old_local_v1.npz", "kind": "cm", "window": "fc2", "n_positions": 8000, "fused_invocab_pct": 12.787, "snn_invocab_pct": 10.056, "vocab_coverage": 0.604125, "fusion_saved": {"scale": 0.056658798957008934, "sigma_fast": 0.04551528212138245, "sigma_slow": 0.8033223958015442}, "fusion_cal": {"scale": 0.05598423216016823, "sigma_fast": 0.04552194186279601, "sigma_slow": 0.8131207682291667}, "load_s": 137.9, "eval_s": 253.1, "peak_rss_mb": 997.7, "maxpos": 0, "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3", "window_bytes": 199792, "ept_budget_bits": 15.36572265625, "script": "eval_bench_v4.1"}
+{"tag": "m7_old", "corpus": "old_local_v1", "ckpt": "/workspace/spira_shared/spira_m7/cm_old_local_v1.npz", "kind": "cm", "window": "fresh_en", "n_positions": 8000, "fused_invocab_pct": 4.533, "snn_invocab_pct": 4.585, "vocab_coverage": 0.71425, "fusion_saved": {"scale": 0.056658798957008934, "sigma_fast": 0.04551528212138245, "sigma_slow": 0.8033223958015442}, "fusion_cal": {"scale": 0.05598423216016823, "sigma_fast": 0.04552194186279601, "sigma_slow": 0.8131207682291667}, "load_s": 137.9, "eval_s": 262.3, "peak_rss_mb": 997.7, "maxpos": 0, "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a", "window_bytes": 119763, "ept_budget_bits": 15.36572265625, "script": "eval_bench_v4.1"}
+{"tag": "m7_old", "corpus": "old_local_v1", "ckpt": "/workspace/spira_shared/spira_m7/cm_old_local_v1.npz", "kind": "cm", "window": "fresh_fr", "n_positions": 8000, "fused_invocab_pct": 0.189, "snn_invocab_pct": 0.22, "vocab_coverage": 0.397375, "fusion_saved": {"scale": 0.056658798957008934, "sigma_fast": 0.04551528212138245, "sigma_slow": 0.8033223958015442}, "fusion_cal": {"scale": 0.05598423216016823, "sigma_fast": 0.04552194186279601, "sigma_slow": 0.8131207682291667}, "load_s": 137.9, "eval_s": 263.3, "peak_rss_mb": 997.7, "maxpos": 0, "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715", "window_bytes": 1088688, "ept_budget_bits": 15.36572265625, "script": "eval_bench_v4.1"}
+{"tag": "m7_old", "corpus": "old_local_v1", "ckpt": "/workspace/spira_shared/spira_m7/cm_old_local_v1.npz", "kind": "cm", "window": "test20k", "n_positions": 20000, "fused_invocab_pct": 3.603, "snn_invocab_pct": 3.625, "vocab_coverage": 0.66895, "fusion_saved": {"scale": 0.056658798957008934, "sigma_fast": 0.04551528212138245, "sigma_slow": 0.8033223958015442}, "fusion_cal": {"scale": 0.05598423216016823, "sigma_fast": 0.04552194186279601, "sigma_slow": 0.8131207682291667}, "load_s": 137.9, "eval_s": 668.3, "peak_rss_mb": 997.7, "maxpos": 0, "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9", "window_bytes": 894718, "ept_budget_bits": 15.36572265625, "script": "eval_bench_v4.1"}
+{"tag": "m7_old", "corpus": "old_local_v1", "ckpt": "/workspace/spira_shared/spira_m7/cm_old_local_v1.npz", "kind": "cm", "window": "queries", "n_positions": 7099, "fused_invocab_pct": 1.165, "snn_invocab_pct": 0.209, "vocab_coverage": 0.4717565854345683, "fusion_saved": {"scale": 0.056658798957008934, "sigma_fast": 0.04551528212138245, "sigma_slow": 0.8033223958015442}, "fusion_cal": {"scale": 0.05598423216016823, "sigma_fast": 0.04552194186279601, "sigma_slow": 0.8131207682291667}, "load_s": 137.9, "eval_s": 252.4, "peak_rss_mb": 997.7, "maxpos": 0, "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706", "window_bytes": 27800, "ept_budget_bits": 15.36572265625, "script": "eval_bench_v4.1"}
+{"tag": "m7_old", "corpus": "old_local_v1", "ckpt": "/workspace/spira_shared/spira_m7/cm_old_local_v1.npz", "kind": "cm", "window": "test_v3", "n_positions": 20000, "fused_invocab_pct": 4.697, "snn_invocab_pct": 4.589, "vocab_coverage": 0.6461, "fusion_saved": {"scale": 0.056658798957008934, "sigma_fast": 0.04551528212138245, "sigma_slow": 0.8033223958015442}, "fusion_cal": {"scale": 0.05598423216016823, "sigma_fast": 0.04552194186279601, "sigma_slow": 0.8131207682291667}, "load_s": 137.9, "eval_s": 776.7, "peak_rss_mb": 1004.7, "maxpos": 0, "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84", "window_bytes": 3486653, "ept_budget_bits": 15.36572265625, "script": "eval_bench_v4.1"}
diff --git a/results/hashing/m7_v41/run_eval_m7_v41.sh b/results/hashing/m7_v41/run_eval_m7_v41.sh
new file mode 100644
index 0000000000000000000000000000000000000000..861196d434a2060bf62054ed349e5a3225f0aa28
--- /dev/null
+++ b/results/hashing/m7_v41/run_eval_m7_v41.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# SPIRA Hashing — éval banc v4.1 (eval_bench_v4.py de Checker, CLI lecture seule, sorties redirigées ici) de M7 old puis verdict.
+# Attend la sortie de 21098 puis MemAvailable >= 4 Go (poll 180 s) ; une seule éval ; plafond prlimit --as (défaut 1,5 Gio, consigne parent 23 h 10). 1 cœur, nice 10.
+export OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0 PYTHONDONTWRITEBYTECODE=1
+D=/workspace/spira_shared/hashing_gen/m7_v41; PY=/workspace/SPIRA-venv/bin/python; cd $D
+log(){ echo "$(TZ=America/Toronto date '+%F %H:%M:%S %Z') $*" >> $D/run_eval_m7_v41.log; }
+log "start pid $$"
+while kill -0 21098 2>/dev/null; do sleep 180; done; log "21098 sorti (gate final 789343 arrêté par SIGTERM par le parent à 23 h 10, CalledProcessError)"
+while pgrep -f "eval_bench_v4.py.*m7_old" >/dev/null; do log "une éval m7_old tourne déjà"; sleep 180; done
+while :; do ma=$(awk '/MemAvailable/{print $2}' /proc/meminfo); [ "$ma" -ge 4194304 ] && break; log "attente mem MemAvailable=${ma} kB"; sleep 180; done
+log "lancement éval MemAvailable=${ma} kB"
+HITS=$D/hits OUT=$D/results_m7_v41.jsonl WINDOWS=seen,fc2,fresh_en,fresh_fr,test20k,queries,test_v3 \
+ prlimit --as=${ASCAP:-1610612736} nice -n 10 taskset -c 0 $PY /workspace/spira_shared/checker/scale/eval_bench_v4.py /workspace/spira_shared/spira_m7/cm_old_local_v1.npz old_local_v1 m7_old > $D/eval_m7_old.log 2>&1
+rc=$?; log "éval rc=$rc"; [ $rc -eq 0 ] || exit $rc
+nice -n 10 $PY $D/verdict_m7_v41.py $D/hits m7_old /workspace/spira_shared/checker/scale/hits_v4 old_ref $D/verdict_m7_old_v41 > $D/verdict_m7_old_v41.log 2>&1
+log "verdict rc=$?"; touch $D/verdict.done
diff --git a/results/hashing/m7_v41/selftest_ref_vs_ref.json b/results/hashing/m7_v41/selftest_ref_vs_ref.json
new file mode 100644
index 0000000000000000000000000000000000000000..effcd956b73b45563830200eec6f2dde66febb40
--- /dev/null
+++ b/results/hashing/m7_v41/selftest_ref_vs_ref.json
@@ -0,0 +1,295 @@
+{
+ "cand": "old_ref",
+ "ref": "old_ref",
+ "windows": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen",
+ "aucun gain significatif sur une fenêtre fraîche"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "RETENU ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (7 fenêtres, queries compris)",
+ "queries_gain_would_count": false,
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5868,
+ "n_invocab_cand": 5868,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 98.32992501704157,
+ "acc_cand_pct": 98.32992501704157,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 71,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "7585ad82947bbe8b2ae6484b1922511b483c11d84bde5b0a53978135d0eb99ca",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fc2": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 4833,
+ "n_invocab_cand": 4833,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 11.504241671839438,
+ "acc_cand_pct": 11.504241671839438,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 76,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_en": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5714,
+ "n_invocab_cand": 5714,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 3.3951697584879246,
+ "acc_cand_pct": 3.3951697584879246,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 70,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_fr": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 3179,
+ "n_invocab_cand": 3179,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.28310789556464294,
+ "acc_cand_pct": 0.28310789556464294,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 60,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test20k": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 20000,
+ "n_clean_cand": 20000,
+ "n_invocab_ref": 13379,
+ "n_invocab_cand": 13379,
+ "n_paired": 20000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 2.9000672696016143,
+ "acc_cand_pct": 2.9000672696016143,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 174,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "queries": {
+ "n_positions_ref": 7099,
+ "n_positions_cand": 7099,
+ "n_clean_ref": 7099,
+ "n_clean_cand": 7099,
+ "n_invocab_ref": 3349,
+ "n_invocab_cand": 3349,
+ "n_paired": 7099,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 55,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test_v3": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 20000,
+ "n_clean_cand": 20000,
+ "n_invocab_ref": 12922,
+ "n_invocab_cand": 12922,
+ "n_paired": 20000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 4.117009750812568,
+ "acc_cand_pct": 4.117009750812568,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 174,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 4.439919269261237,
+ "seen_pct": 98.32992501704157,
+ "gap_pct": 93.89000574778034,
+ "ci95": [
+ 93.40985672775108,
+ 94.34460115328463
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 4.439919269261237,
+ "seen_pct": 98.32992501704157,
+ "gap_pct": 93.89000574778034,
+ "ci95": [
+ 93.40985672775108,
+ 94.34460115328463
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": 0.0,
+ "ci95": [
+ 0.0,
+ 0.0
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "note": "queries hors moyenne (rapportée à part) ; neither_code exclu"
+ },
+ "test20k_mask": "positions dont [s-64, s+l) touche un 64-gramme confirmé de old_local_v1/train.bin (mask_old_bench.npz)",
+ "script_sha256": "10ac5fed0693523187416793f330aa5d1b76dc06236b015fbb8b50e8be2f6fd1"
+}
\ No newline at end of file
diff --git a/results/hashing/m7_v41/selftest_ref_vs_ref.md b/results/hashing/m7_v41/selftest_ref_vs_ref.md
new file mode 100644
index 0000000000000000000000000000000000000000..a6bd36378e08e3d1788f54c60b64bbb48ef34f20
--- /dev/null
+++ b/results/hashing/m7_v41/selftest_ref_vs_ref.md
@@ -0,0 +1,16 @@
+# Verdict v4.1 — M7 old (old_ref) contre old_ref
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche
+
+| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 8000 | 98.330 | 98.330 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fc2 | 8000 | 11.504 | 11.504 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | 8000 | 3.395 | 3.395 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_fr | 8000 | 0.283 | 0.283 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test20k | 20000 | 2.900 | 2.900 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| queries | 7099 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | 20000 | 4.117 | 4.117 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k, test_v3) : M7 +93.890 pts [IC95 +93.410 ; +94.345] (fraîche 4.440 %) ; réf +93.890 pts [+93.410 ; +94.345] (fraîche 4.440 %) ; différence M7 − réf +0.000 [+0.000 ; +0.000]. queries à part (table). neither_code exclu.
+
diff --git a/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/SHA256SUMS b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/SHA256SUMS
new file mode 100644
index 0000000000000000000000000000000000000000..f92d2d65078c2eea1a5b36f41e6ee9506ec69d4c
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/SHA256SUMS
@@ -0,0 +1,16 @@
+396f11a142475cca3ee413066423aab9d4e3f708db191d3b96b8321875182b5f cm_old_local_v1.npz
+fdee6dc046ea48c19b0c96510eaa6cece2ac4974cb9fd786c9aef142fe8cdfff code/crosscheck_mask_t20k.py
+e7c4ad734a7b2c567fb7c1eb6e827aea15c81673d62180f01bca1e1581d339fa code/mask_old_bench.py
+99ea3a2119dfbdab24f4fc45faed3fb2dd7188a0d3557b4127ef515ea7281f91 code/run_eval_m7_v41.sh
+aa36c8ec8278addf426fd5220db0b446085e5b95003d585778603a30c0a502f7 code/run_m7_old_local_v1.py
+00e2313f3e4c2026099cf071141c793f35a5b407548c8cbe9b2e4ae5ad5fe0e2 code/test_unit_mcn.out
+26d7b4b1b3f4ebd07c4eb5036eb93c01b22cd52156f405e44791111768af36db code/test_unit_mcn.py
+10ac5fed0693523187416793f330aa5d1b76dc06236b015fbb8b50e8be2f6fd1 code/verdict_m7_v41.py
+71505da18db5d189cc9cb4bc0fe748381e08f67bd62548ae456348bf2866baaa crosscheck_mask_t20k.json
+fc089ac386674a7186664cfad06b0d81251ace35e16de1ac12b223617a3e3379 eval_m7_old.log
+77215abd17ace6b1b003254f643e2bddeae8b8115aac3445ca17b2c5192ba1d8 mask_old_bench.json
+e15cf361391e32bcfef97d4982f15fe011e443f2c1a6ef4a3c8120510f2e13a5 run_m7_old.log
+c21c79524c5fe2f480f20453e9c5f0409ce88907d12cc2cda1c5345702028862 selftest_ref_vs_ref.md
+12b3f67e32c412bb590de3f37aeebd8048d16248128fb6e8043929dd80817f7e train_summary.json
+45899fa171e3d8395fc0bdb020b2fa7115f30c194b0a44aefe38009888feb870 verdict_m7_old_v41.json
+520b2027d907f52af8ba601cb09f9efdab6bdb9a0d7d1aebd117c98a29e8ac15 verdict_m7_old_v41.md
diff --git a/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/code/run_eval_m7_v41.sh b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/code/run_eval_m7_v41.sh
new file mode 100644
index 0000000000000000000000000000000000000000..861196d434a2060bf62054ed349e5a3225f0aa28
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/code/run_eval_m7_v41.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# SPIRA Hashing — éval banc v4.1 (eval_bench_v4.py de Checker, CLI lecture seule, sorties redirigées ici) de M7 old puis verdict.
+# Attend la sortie de 21098 puis MemAvailable >= 4 Go (poll 180 s) ; une seule éval ; plafond prlimit --as (défaut 1,5 Gio, consigne parent 23 h 10). 1 cœur, nice 10.
+export OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0 PYTHONDONTWRITEBYTECODE=1
+D=/workspace/spira_shared/hashing_gen/m7_v41; PY=/workspace/SPIRA-venv/bin/python; cd $D
+log(){ echo "$(TZ=America/Toronto date '+%F %H:%M:%S %Z') $*" >> $D/run_eval_m7_v41.log; }
+log "start pid $$"
+while kill -0 21098 2>/dev/null; do sleep 180; done; log "21098 sorti (gate final 789343 arrêté par SIGTERM par le parent à 23 h 10, CalledProcessError)"
+while pgrep -f "eval_bench_v4.py.*m7_old" >/dev/null; do log "une éval m7_old tourne déjà"; sleep 180; done
+while :; do ma=$(awk '/MemAvailable/{print $2}' /proc/meminfo); [ "$ma" -ge 4194304 ] && break; log "attente mem MemAvailable=${ma} kB"; sleep 180; done
+log "lancement éval MemAvailable=${ma} kB"
+HITS=$D/hits OUT=$D/results_m7_v41.jsonl WINDOWS=seen,fc2,fresh_en,fresh_fr,test20k,queries,test_v3 \
+ prlimit --as=${ASCAP:-1610612736} nice -n 10 taskset -c 0 $PY /workspace/spira_shared/checker/scale/eval_bench_v4.py /workspace/spira_shared/spira_m7/cm_old_local_v1.npz old_local_v1 m7_old > $D/eval_m7_old.log 2>&1
+rc=$?; log "éval rc=$rc"; [ $rc -eq 0 ] || exit $rc
+nice -n 10 $PY $D/verdict_m7_v41.py $D/hits m7_old /workspace/spira_shared/checker/scale/hits_v4 old_ref $D/verdict_m7_old_v41 > $D/verdict_m7_old_v41.log 2>&1
+log "verdict rc=$?"; touch $D/verdict.done
diff --git a/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/code/run_m7_old_local_v1.py b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/code/run_m7_old_local_v1.py
new file mode 100644
index 0000000000000000000000000000000000000000..fe00676d2af491f1dbc9977910e2e61ec618b2ce
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/code/run_m7_old_local_v1.py
@@ -0,0 +1,51 @@
+"""M7 étape 1 sur old_local_v1 (Hashing, 2026-10-23). CMSPIRA (v3 + CM d24/4096, ±2, top-16 PPMI),
+config de base du repo (SPIRAConfig() par défaut). calibrate_fusion(train[:60_000]) AVANT la sauvegarde finale.
+Puis : rejeu de M9g+BAN1 et de l'int8 sur le ckpt réel, et run_gate_cm_v2 (test.bin 20k positions, oneshot.bin)."""
+import sys, os, json, time, subprocess, numpy as np
+S = "/workspace/spira_shared/semhash"; sys.path.insert(0, S)
+from countmin import CMSPIRA, save_with_calibration, SPIRAConfig
+from m9g_ban1 import JMNgram, generate_m9g
+from int8_wout import quantize, dequantize
+D = "/workspace/spira_shared/broad/old_local_v1"; O = "/workspace/spira_shared/spira_m7"
+log = lambda *a: print(time.strftime("%H:%M:%S"), *a, flush=True)
+train = open(f"{D}/train.bin", "rb").read()
+cfg = SPIRAConfig()
+log("cfg", cfg)
+m = CMSPIRA.build_cm(train, cfg, log=log)
+m.prepare(); h = m.train(log_fn=log, ckpt_path=f"{O}/cm_old_partial_nocal.npz")
+ck = f"{O}/cm_old_local_v1.npz"
+saved = save_with_calibration(m, ck, train[:60_000])
+log("CALIBRATED+SAVED", saved)
+json.dump({"history": h, "fusion": saved, "ckpt": ck}, open(f"{O}/train_summary.json", "w"), default=str, indent=1)
+m = CMSPIRA.load(ck); assert m.fusion["scale"] == saved["scale"]
+# int8 sur vrai ckpt
+test = open(f"{D}/test.bin", "rb").read()
+W = m.core.W_out.copy(); Wq, s = quantize(W); Wd = dequantize(Wq, s)
+from spira.hashing import fnv1a64
+pt = m.ept.segment(test); ids = np.fromiter((fnv1a64(p) for p in pt), np.uint64)[:20001]
+r = m.neuron_rows(ids[:-1], pt[:20000]); cols = m.cols_of(ids[1:])
+snap = m.core.snapshot(); m.core.reset_dynamics(); af = aq = ag = a_only = b_only = 0
+for t in range(20000):
+ x = m.core.step(r[t]) - m.core.x_mean
+ a, b = int(np.argmax(x @ W)), int(np.argmax(x @ Wd)); y = int(cols[t])
+ ag += a == b; af += a == y; aq += b == y; a_only += (a == y) and (b != y); b_only += (b == y) and (a != y)
+m.core.restore(snap)
+from run_gate_cm_v2 import mcnemar_exact
+mc = mcnemar_exact(np.array([1]*a_only+[0]*b_only, bool), np.array([0]*a_only+[1]*b_only, bool))
+int8 = {"n": 20000, "agree": ag, "acc_f32": af, "acc_int8": aq, "mcnemar": mc, "mem_ratio": W.nbytes/(Wq.nbytes+s.nbytes)}
+log("INT8", int8); json.dump(int8, open(f"{O}/int8_real.json", "w"), indent=1)
+# M9g+BAN1 sur vrai ckpt (n-gramme sur train complet)
+ng = JMNgram(m.cols_of(m._ids_train) if hasattr(m, "_ids_train") else None, cfg.vocab_size) if False else None
+ptr = m.ept.segment(train); idt = np.fromiter((fnv1a64(p) for p in ptr), np.uint64, len(ptr))
+ng = JMNgram(m.cols_of(idt), cfg.vocab_size)
+gens = []
+for i, pr in enumerate([b"The old man said that", b"def __init__(self, ", b"Il y avait une fois"]):
+ for ban in (True, False):
+ o, st = generate_m9g(m, ng, pr, n_tokens=200, seed=0, ban=ban)
+ g = o[len(pr):]; gr = [g[j:j+8] for j in range(len(g)-7)]
+ gens.append({"prompt": pr.decode(), "ban1": ban, "rep8": len(gr)-len(set(gr)), "n_bytes": len(g), "stats": st, "text": g.decode("utf-8", "replace")})
+ log("GEN", ban, gens[-1]["rep8"], repr(g[:120]))
+json.dump(gens, open(f"{O}/m9g_ban1_real.json", "w"), indent=1, ensure_ascii=False)
+subprocess.run([sys.executable, f"{S}/run_gate_cm_v2.py", "--ckpt", ck, "--cm", "--window", f"test20k={D}/test.bin",
+ "--window", f"oneshot={D}/oneshot.bin", "--max-pos", "20000", "--out", f"{O}/results_gate_v2.jsonl"], check=True)
+log("DONE")
diff --git a/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/code/test_unit_mcn.py b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/code/test_unit_mcn.py
new file mode 100644
index 0000000000000000000000000000000000000000..1f97aaa9bfe47af60a47dd25abffd70be8b655da
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/code/test_unit_mcn.py
@@ -0,0 +1,15 @@
+"""Test : unit_mcn de verdict_m7_v41.py == unit_mcn de checker/scale/scale_bench_v4.py (lecture seule) sur old_ref vs broad14_ref (tokenizers différents), sans masque."""
+import numpy as np, re
+src = open("verdict_m7_v41.py").read(); g = {"np": np}
+exec(src[src.index("def unit_mcn"):src.index("def blocksums")], g)
+cs = open("/workspace/spira_shared/checker/scale/scale_bench_v4.py").read(); h = {"np": np, "mcn": lambda b, c: None}
+exec(cs[cs.index("def unit_mcn"):cs.index("def bytehits")], h)
+H = "/workspace/spira_shared/checker/scale/hits_v4"; ok = True
+for w in ["fc2", "fresh_en", "fresh_fr", "test20k", "queries", "test_v3"]:
+ A, B = np.load(f"{H}/old_ref__{w}.npz"), np.load(f"{H}/broad14_ref__{w}.npz")
+ ha, hb = A["fused_hit"].astype(bool), B["fused_hit"].astype(bool)
+ k1 = g["unit_mcn"](A, B, ha, hb, np.ones(len(ha), bool), np.ones(len(hb), bool))
+ lo = max(A["tgt_start"][0], B["tgt_start"][0]); hi = min((A["tgt_start"] + A["tgt_len"])[-1], (B["tgt_start"] + B["tgt_len"])[-1])
+ k2 = h["unit_mcn"](A, B, lo, hi)[:3]; same = tuple(k1) == tuple(k2); ok &= same
+ print(w, "hashing", k1, "checker", k2, "OK" if same else "DIFF")
+print("ALL OK" if ok else "MISMATCH")
diff --git a/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/code/verdict_m7_v41.py b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/code/verdict_m7_v41.py
new file mode 100644
index 0000000000000000000000000000000000000000..1102b01cf22018e2eeae164f8837f610b8871596
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/code/verdict_m7_v41.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict v4.1 : M7 old (cand) contre old_ref (réf), lecture seule des hits (aucun modèle chargé).
+Usage : verdict_m7_v41.py CAND_HITS_DIR CAND_TAG REF_HITS_DIR REF_TAG OUT_PREFIX
+Fenêtres : seen, fc2, fresh_en, fresh_fr, test20k (positions propres vs old_local_v1/train.bin, mask_old_bench.npz), queries, test_v3.
+neither_code exclu (contaminé). hit = fused_hit & invocab (masque invocab Checker 19 h 55).
+Appariement : si tgt_start ET tgt_len identiques (même tokenizer) → par position ; sinon unités entre frontières de patch communes
+(unit_mcn de scale_bench_v4.py : unité réussie ssi toutes ses cibles sont des hits).
+McNemar exact bilatéral (binomial) sur les discordants = DÉCISION (p<0,05). Bootstrap par blocs : blocs de 512 octets de la fenêtre
+(bloc = tgt_start // 512), B = 10 000, un seul générateur seed 0 tiré fenêtre après fenêtre (ordre WIN), même tirage pour les deux modèles (apparié) ; stat = acc invocab (hits/invocab).
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3), queries à part ; IC bootstrap (tirages indépendants par fenêtre).
+Critère : RETENU ssi gain significatif sur seen ET gain significatif sur ≥1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3 ; queries à part)
+ET aucune perte significative sur une fenêtre valide."""
+import sys, json, math, hashlib, numpy as np
+CD, CT, RD, RT, OP = sys.argv[1:6]
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "queries", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"] # queries : fenêtre valide (pertes comptées) mais rapportée à part, hors « fraîches »
+GAPW = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+MK = np.load("/workspace/spira_shared/hashing_gen/m7_v41/mask_old_bench.npz")
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def unit_mcn(za, zb, ha_, hb_, keep_a, keep_b):
+ sa, ea = za["tgt_start"][keep_a], (za["tgt_start"] + za["tgt_len"])[keep_a]; sb, eb = zb["tgt_start"][keep_b], (zb["tgt_start"] + zb["tgt_len"])[keep_b]
+ ha_, hb_ = ha_[keep_a], hb_[keep_b]; lo, hi = max(sa[0], sb[0]), min(ea[-1], eb[-1])
+ common = np.intersect1d(np.concatenate([sa, ea[-1:]]), np.concatenate([sb, eb[-1:]])); common = common[(common >= lo) & (common <= hi)]
+ def uh(s, e, h):
+ k = np.searchsorted(common, s, side="right") - 1; ok = (s >= common[0]) & (e <= common[-1]); u = np.ones(len(common) - 1, bool); np.logical_and.at(u, k[ok], h[ok]); return u
+ def cnt(s, e):
+ k = np.searchsorted(common, s, side="right") - 1; ok = (s >= common[0]) & (e <= common[-1]); return np.bincount(k[ok], minlength=len(common) - 1)[:len(common) - 1]
+ x, y = uh(sa, ea, ha_), uh(sb, eb, hb_); v = (cnt(sa, ea) > 0) & (cnt(sb, eb) > 0) # unités sans cible gardée d'un côté (masque) exclues
+ x, y = x[v], y[v]; return len(x), int((x & ~y).sum()), int((~x & y).sum())
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {} # un seul flux seed 0, tirages successifs par fenêtre (ordre WIN) → indépendants entre fenêtres
+for w in WIN:
+ A = np.load(f"{RD}/{RT}__{w}.npz"); B = np.load(f"{CD}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MK["sha__test20k"]) == str(A["window_sha256"]); cov = MK["test20k__covered"]
+ bad = lambda Z: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(Z["tgt_start"], Z["tgt_len"])])
+ ka, kb = ~bad(A), ~bad(B)
+ else: ka, kb = np.ones(na, bool), np.ones(nb_, bool)
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ if same_tok:
+ k = ka & kb; b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); pairing = "position (tokenizers identiques)"
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ else:
+ npair, b, c = unit_mcn(A, B, ha, hb, ka, kb); pairing = "unités entre frontières communes"; inv_same = None
+ p = binp(b, c)
+ ia, ib = A["invocab"].astype(bool) & ka, B["invocab"].astype(bool) & kb
+ acc_a, acc_b = 100 * (ha & ka).sum() / ia.sum(), 100 * (hb & kb).sum() / ib.sum()
+ nbk = int(max(A["tgt_start"].max(), B["tgt_start"].max()) // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][ka], ha[ka], A["invocab"].astype(bool)[ka], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][kb], hb[kb], B["invocab"].astype(bool)[kb], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1); d = bb - ba
+ BOOT[w] = (ba, bb)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions_ref": na, "n_positions_cand": nb_, "n_clean_ref": int(ka.sum()), "n_clean_cand": int(kb.sum()), "n_invocab_ref": int(ia.sum()), "n_invocab_cand": int(ib.sum()),
+ "n_paired": npair, "pairing": pairing, "invocab_identical": inv_same, "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "boot_sig_agrees": bool((lo > 0) == gain and (hi < 0) == loss),
+ "window_sha256": str(A["window_sha256"]), "ept_budget_ref": float(A["ept_budget_bits"]), "ept_budget_cand": float(B["ept_budget_bits"]),
+ "excluded_positions_ref": int((~ka).sum()), "excluded_positions_cand": int((~kb).sum())}
+ print(w, json.dumps(R[w]), flush=True)
+# écart seen − moyenne fraîche (5 fenêtres) ; tirages bootstrap indépendants entre fenêtres (même tirage pour les deux modèles dans une fenêtre)
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.percentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.percentile(dg, [2.5, 97.5])]}
+gap["windows"] = GAPW; gap["note"] = "queries hors moyenne (rapportée à part) ; neither_code exclu"
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "RETENU" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+out = {"cand": CT, "ref": RT, "windows": WIN, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "RETENU ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (7 fenêtres, queries compris)", "queries_gain_would_count": bool(R["queries"]["sig_gain"]),
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap,
+ "test20k_mask": "positions dont [s-64, s+l) touche un 64-gramme confirmé de old_local_v1/train.bin (mask_old_bench.npz)",
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict v4.1 — M7 old ({CT}) contre {RT}\n", f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ md.append(f"| {w} | {r['n_paired']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["", f"Écart seen − moyenne fraîche ({', '.join(GAPW)}) : M7 {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence M7 − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [{gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}]. queries à part (table). neither_code exclu.", ""]
+open(f"{OP}.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/selftest_ref_vs_ref.md b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/selftest_ref_vs_ref.md
new file mode 100644
index 0000000000000000000000000000000000000000..a6bd36378e08e3d1788f54c60b64bbb48ef34f20
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/selftest_ref_vs_ref.md
@@ -0,0 +1,16 @@
+# Verdict v4.1 — M7 old (old_ref) contre old_ref
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche
+
+| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 8000 | 98.330 | 98.330 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fc2 | 8000 | 11.504 | 11.504 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | 8000 | 3.395 | 3.395 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_fr | 8000 | 0.283 | 0.283 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test20k | 20000 | 2.900 | 2.900 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| queries | 7099 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | 20000 | 4.117 | 4.117 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k, test_v3) : M7 +93.890 pts [IC95 +93.410 ; +94.345] (fraîche 4.440 %) ; réf +93.890 pts [+93.410 ; +94.345] (fraîche 4.440 %) ; différence M7 − réf +0.000 [+0.000 ; +0.000]. queries à part (table). neither_code exclu.
+
diff --git a/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/train_summary.json b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/train_summary.json
new file mode 100644
index 0000000000000000000000000000000000000000..5b8c4f4a7ec4086e4badb9a060214d4af08f4cdc
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/train_summary.json
@@ -0,0 +1,36 @@
+{
+ "history": {
+ "epochs": [
+ {
+ "ticks": 600000,
+ "accuracy": 0.06082333333333333,
+ "accuracy_fast_only": 0.08459833333333333,
+ "beta": 0.10087046869458932,
+ "acc_ema_final": 0.21631616562234157,
+ "elapsed_s": 25419.800736482997,
+ "ticks_per_sec": 23.60364686647084
+ },
+ {
+ "ticks": 600000,
+ "accuracy": 0.067085,
+ "accuracy_fast_only": 0.11190833333333333,
+ "beta": 0.07528583775305782,
+ "acc_ema_final": 0.24721433238185916,
+ "elapsed_s": 24463.95195775,
+ "ticks_per_sec": 24.52588204212543
+ }
+ ],
+ "am": {
+ "slots": 8388608,
+ "used": 3948803,
+ "load_factor": 0.47073400020599365,
+ "n_writes": 1199996
+ }
+ },
+ "fusion": {
+ "scale": 0.056658798957008934,
+ "sigma_fast": 0.04551528212138245,
+ "sigma_slow": 0.8033223958015442
+ },
+ "ckpt": "/workspace/spira_shared/spira_m7/cm_old_local_v1.npz"
+}
\ No newline at end of file
diff --git a/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/verdict_m7_old_v41.json b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/verdict_m7_old_v41.json
new file mode 100644
index 0000000000000000000000000000000000000000..7076de73c40cd76539f285499c9ab64f7e014452
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/verdict_m7_old_v41.json
@@ -0,0 +1,305 @@
+{
+ "cand": "m7_old",
+ "ref": "old_ref",
+ "windows": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen"
+ ],
+ "losses": [],
+ "gains": [
+ "fc2",
+ "fresh_en",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "fresh_gains": [
+ "fc2",
+ "fresh_en",
+ "test20k",
+ "test_v3"
+ ],
+ "rule": "RETENU ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (7 fenêtres, queries compris)",
+ "queries_gain_would_count": true,
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5868,
+ "n_invocab_cand": 5868,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 98.32992501704157,
+ "acc_cand_pct": 98.27880027266531,
+ "delta_pct": -0.05112474437626702,
+ "b_ref_only": 8,
+ "c_cand_only": 5,
+ "mcnemar_p": 0.5810546875,
+ "boot_ci95_delta_pct": [
+ -0.17018524712170519,
+ 0.0684934439421255
+ ],
+ "boot_p": 0.4876,
+ "n_blocks": 71,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "7585ad82947bbe8b2ae6484b1922511b483c11d84bde5b0a53978135d0eb99ca",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fc2": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 4833,
+ "n_invocab_cand": 4833,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 11.504241671839438,
+ "acc_cand_pct": 12.787088764742396,
+ "delta_pct": 1.2828470929029585,
+ "b_ref_only": 87,
+ "c_cand_only": 149,
+ "mcnemar_p": 6.552303801488519e-05,
+ "boot_ci95_delta_pct": [
+ 0.45043115921060234,
+ 2.098058259676331
+ ],
+ "boot_p": 0.0022,
+ "n_blocks": 76,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_en": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5714,
+ "n_invocab_cand": 5714,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 3.3951697584879246,
+ "acc_cand_pct": 4.532726636331817,
+ "delta_pct": 1.1375568778438923,
+ "b_ref_only": 60,
+ "c_cand_only": 125,
+ "mcnemar_p": 2.0116885464439608e-06,
+ "boot_ci95_delta_pct": [
+ 0.6466185823810344,
+ 1.6493154579092075
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 70,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_fr": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 3179,
+ "n_invocab_cand": 3179,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.28310789556464294,
+ "acc_cand_pct": 0.1887385970430953,
+ "delta_pct": -0.09436929852154763,
+ "b_ref_only": 7,
+ "c_cand_only": 4,
+ "mcnemar_p": 0.548828125,
+ "boot_ci95_delta_pct": [
+ -0.2924926876828079,
+ 0.0981370330335732
+ ],
+ "boot_p": 0.4494,
+ "n_blocks": 60,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test20k": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 20000,
+ "n_clean_cand": 20000,
+ "n_invocab_ref": 13379,
+ "n_invocab_cand": 13379,
+ "n_paired": 20000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 2.9000672696016143,
+ "acc_cand_pct": 3.602660886463861,
+ "delta_pct": 0.7025936168622469,
+ "b_ref_only": 155,
+ "c_cand_only": 249,
+ "mcnemar_p": 3.371499782730385e-06,
+ "boot_ci95_delta_pct": [
+ 0.3881154573588749,
+ 1.0131710950224935
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "queries": {
+ "n_positions_ref": 7099,
+ "n_positions_cand": 7099,
+ "n_clean_ref": 7099,
+ "n_clean_cand": 7099,
+ "n_invocab_ref": 3349,
+ "n_invocab_cand": 3349,
+ "n_paired": 7099,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 1.1645267243953419,
+ "delta_pct": 1.1645267243953419,
+ "b_ref_only": 0,
+ "c_cand_only": 39,
+ "mcnemar_p": 3.637978807091713e-12,
+ "boot_ci95_delta_pct": [
+ 0.9682299546142209,
+ 1.3489824002954531
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 55,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test_v3": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 20000,
+ "n_clean_cand": 20000,
+ "n_invocab_ref": 12922,
+ "n_invocab_cand": 12922,
+ "n_paired": 20000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 4.117009750812568,
+ "acc_cand_pct": 4.697415260795543,
+ "delta_pct": 0.5804055099829748,
+ "b_ref_only": 241,
+ "c_cand_only": 316,
+ "mcnemar_p": 0.001691499949113725,
+ "boot_ci95_delta_pct": [
+ 0.04663934878203853,
+ 1.070173904132315
+ ],
+ "boot_p": 0.0368,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 4.439919269261237,
+ "seen_pct": 98.32992501704157,
+ "gap_pct": 93.89000574778034,
+ "ci95": [
+ 93.40985672775108,
+ 94.34460115328463
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 5.161726029075342,
+ "seen_pct": 98.27880027266531,
+ "gap_pct": 93.11707424358997,
+ "ci95": [
+ 92.62985938430558,
+ 93.5910453158752
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.7729315041903675,
+ "ci95": [
+ -1.0284176901635749,
+ -0.5079878367244357
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "note": "queries hors moyenne (rapportée à part) ; neither_code exclu"
+ },
+ "test20k_mask": "positions dont [s-64, s+l) touche un 64-gramme confirmé de old_local_v1/train.bin (mask_old_bench.npz)",
+ "script_sha256": "10ac5fed0693523187416793f330aa5d1b76dc06236b015fbb8b50e8be2f6fd1"
+}
\ No newline at end of file
diff --git a/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/verdict_m7_old_v41.md b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/verdict_m7_old_v41.md
new file mode 100644
index 0000000000000000000000000000000000000000..7b58b9684305c8c73963c08271046ef648e2e239
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check/results/hashing/m7_old/verdict_m7_old_v41.md
@@ -0,0 +1,52 @@
+# Verdict v4.1 — M7 old (m7_old) contre old_ref
+
+**REJETÉ** — pas de gain significatif sur seen
+
+| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 8000 | 98.279 | 98.330 | -0.051 | 8/5 | 0.581 | [-0.170 ; +0.068] | n.s. |
+| fc2 | 8000 | 12.787 | 11.504 | +1.283 | 87/149 | 6.55e-05 | [+0.450 ; +2.098] | GAIN |
+| fresh_en | 8000 | 4.533 | 3.395 | +1.138 | 60/125 | 2.01e-06 | [+0.647 ; +1.649] | GAIN |
+| fresh_fr | 8000 | 0.189 | 0.283 | -0.094 | 7/4 | 0.549 | [-0.292 ; +0.098] | n.s. |
+| test20k | 20000 | 3.603 | 2.900 | +0.703 | 155/249 | 3.37e-06 | [+0.388 ; +1.013] | GAIN |
+| queries | 7099 | 1.165 | 0.000 | +1.165 | 0/39 | 3.64e-12 | [+0.968 ; +1.349] | GAIN |
+| test_v3 | 20000 | 4.697 | 4.117 | +0.580 | 241/316 | 0.00169 | [+0.047 ; +1.070] | GAIN |
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k, test_v3) : M7 +93.117 pts [IC95 +92.630 ; +93.591] (fraîche 5.162 %) ; réf +93.890 pts [+93.410 ; +94.345] (fraîche 4.440 %) ; différence M7 − réf -0.773 [-1.028 ; -0.508]. queries à part (table). neither_code exclu.
+
+
+## Protocole et provenance
+
+- Candidat : M7 old = `spira_m7/cm_old_local_v1.npz` (446 551 146 o, sha256 396f11a142475cca3ee413066423aab9d4e3f708db191d3b96b8321875182b5f), checkpoint CALIBRÉ (sauvé 22 h 43 Toronto ; ni partial ni nocal). Corpus old_local_v1 (train sha256 e12b6586…ded54, 12 468 350 o). 2 époques × 600 000 ticks (train_summary.json).
+- Réf : old_ref = `checker/ckpt/ref_fixed2cal_old_local_v1.npz`, hits existants `checker/scale/hits_v4/old_ref__*.npz` (lecture seule). m9g v2b non utilisé (invalidé).
+- Éval M7 : `checker/scale/eval_bench_v4.py` de Checker appelé en CLI sans modification (HITS/OUT redirigés vers hashing_gen/m7_v41/, PYTHONDONTWRITEBYTECODE=1), fenêtres seen, fc2, fresh_en, fresh_fr, test20k, queries, test_v3 ; neither_code non évalué. Pleine longueur (8 000 / 20 000 positions, MAXPOS=0). 1 cœur (taskset -c 0), nice 10, OMP_NUM_THREADS=1, PYTHONHASHSEED=0. Durée 47 min 50 s (23 h 33 → 00 h 21 Toronto ; chargement 137,9 s + 2 732 s d’éval), pic RSS 1 004,7 Mo.
+- Fusion : comme pour toutes les entrées du banc v4, `bench_common.load_model` recalibre la fusion sur train[:60 000] au chargement : scale 0,055984 (valeur sauvée 0,056659). Les deux modèles sont traités de la même façon.
+- Tokenizers identiques (tgt_start, tgt_len, invocab égaux sur les 7 fenêtres ; EPT budget 15,3657 bits des deux côtés) → appariement par POSITION. hit = fused_hit ∧ invocab ; acc = hits / positions invocab.
+- McNemar exact bilatéral = décision (p < 0,05). Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un seul générateur seed 0 tiré fenêtre après fenêtre → indicatif ; aucune contradiction bootstrap/McNemar.
+- Critère (Philippe-Antoine) : RETENU ssi gain significatif sur seen ET sur ≥ 1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (queries compris). queries rapportée à part, hors moyenne fraîche.
+- Auto-test réf contre réf (`selftest_ref_vs_ref.md`) : 0/0 partout, Δ = 0, accs = results_v4.jsonl de Checker. `test_unit_mcn.py` : chemin d'appariement par unités = `unit_mcn` de scale_bench_v4.py sur 6 fenêtres (non utilisé ici, tokenizers identiques).
+
+## test20k : traitement
+
+- test20k = `broad/broad_local_v1/test.bin` (894 718 o, sha256 e89725bb…a9). Masque `mask_old_bench.npz` : 64-grammes confirmés octet à octet contre old_local_v1/train.bin ; position exclue ssi un octet de [s−64, s+l) est couvert. 434 640 octets couverts sur la fenêtre, mais le premier octet couvert est 144 389 alors que les 20 000 cibles évaluées couvrent [2 ; 88 765) → **0 position exclue**. Contre-vérification à hash indépendant (`crosscheck_mask_t20k.json`) : masque identique sur [0 ; 199 936), 0 octet couvert dans la plage évaluée.
+- Recompte Checker (relais 00 h 30) avec le masque strict-clean de la règle (qui inclut aussi la contamination par broad_local_v1, 128 positions exclues) : réf 2,906 %, M7 3,603 %, 155/248, p = 4,18e-6 → GAIN aussi ; décision inchangée. Écart M7 − réf selon cette règle : −0,772, IC95 [−1,027 ; −0,507] (Checker).
+- `verify_old_local_v1.json` (INVALID DELTA ≠ 0) concerne le test propre du corpus old (old_local_v1/test.bin, 1 396 positions 64 o partagées avec son train) et neither_code (224 303) : pas utilisés dans ce verdict.
+
+## Référence M7 old validée par Checker (éval réf v2, hors banc v4.1)
+
+Chiffres de `checker/m8/results_m8.jsonl` (lignes 1, 3, 5, 7 ; tag cm_old_local_v1, script eval_ref_v2, 8 000 positions, fused sur TOUTES les positions, hors vocabulaire = échec), recomptés par Checker depuis les booléens par position : `spira_relay.md` l. 3870 et 3876 (Checker 23 h 00, `checker/recount/recount_m7old_ref_2300.py`) et l. 3890–3891 (Checker 23 h 07, `checker/recount/recount_m7old_fresh_2307.py`). Vérifié dans le jsonl par Hashing :
+
+| fenêtre (éval réf v2) | fused toutes positions | fused invocab | couverture vocab |
+|---|---|---|---|
+| seen | 98,06 % (0,980625) | 98,279 % | 0,7335 |
+| freshcode (fenêtre M7, pas dans le banc v4.1) | 55,81 % (0,558125) | 59,374 % | 0,67875 |
+| fresh_en | 3,25 % (0,0325) | 4,533 % | 0,71425 |
+| fresh_fr | 0,075 % (0,00075) | 0,189 % | 0,397375 |
+
+Les valeurs invocab de l'éval réf v2 sont identiques à celles du banc v4.1 ci-dessus (98,279 / 4,533 / 0,189) : seul le dénominateur diffère (Checker 00 h 30 l'a aussi constaté).
+
+## Incidents et limites
+
+- 21098 (script M7) n'est pas allé au bout : son étape finale run_gate_cm_v2 (PID 789343, test20k/oneshot du corpus old) a été arrêtée par SIGTERM à 23 h 10 lors de l'alerte mémoire (MemAvailable 0,73 Go, chrome tué par l'OOM) → CalledProcessError. `results_gate_v2.jsonl` est incomplet : ni utilisé ni poussé. int8_real.json et m9g_ban1_real.json ont été écrits avant.
+- Premier lancement de l'éval avec plafond `prlimit --as=1,5 Gio` : échec immédiat (_ArrayMemoryError au chargement de W_out, 416 Mio ; `eval_m7_old_fail_as1536M.log`). Relancé une fois avec `--as=2,5 Gio` (VmPeak mesuré 1,64 Go, pic RSS 1,00 Go). Lancement à MemAvailable 4,57 Go (porte ≥ 4 Go ; la règle ≥ 5,2 Go est arrivée après le lancement).
+- Une seule graine bootstrap, une seule exécution : pas de variance inter-entraînements mesurée.
diff --git a/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/SHA256SUMS b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/SHA256SUMS
new file mode 100644
index 0000000000000000000000000000000000000000..70112c88c8c31de7ba4dfa29d64c2e4049df6e75
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/SHA256SUMS
@@ -0,0 +1,16 @@
+396f11a142475cca3ee413066423aab9d4e3f708db191d3b96b8321875182b5f cm_old_local_v1.npz
+fdee6dc046ea48c19b0c96510eaa6cece2ac4974cb9fd786c9aef142fe8cdfff code/crosscheck_mask_t20k.py
+e7c4ad734a7b2c567fb7c1eb6e827aea15c81673d62180f01bca1e1581d339fa code/mask_old_bench.py
+99ea3a2119dfbdab24f4fc45faed3fb2dd7188a0d3557b4127ef515ea7281f91 code/run_eval_m7_v41.sh
+aa36c8ec8278addf426fd5220db0b446085e5b95003d585778603a30c0a502f7 code/run_m7_old_local_v1.py
+00e2313f3e4c2026099cf071141c793f35a5b407548c8cbe9b2e4ae5ad5fe0e2 code/test_unit_mcn.out
+26d7b4b1b3f4ebd07c4eb5036eb93c01b22cd52156f405e44791111768af36db code/test_unit_mcn.py
+10ac5fed0693523187416793f330aa5d1b76dc06236b015fbb8b50e8be2f6fd1 code/verdict_m7_v41.py
+71505da18db5d189cc9cb4bc0fe748381e08f67bd62548ae456348bf2866baaa crosscheck_mask_t20k.json
+fc089ac386674a7186664cfad06b0d81251ace35e16de1ac12b223617a3e3379 eval_m7_old.log.txt
+77215abd17ace6b1b003254f643e2bddeae8b8115aac3445ca17b2c5192ba1d8 mask_old_bench.json
+e15cf361391e32bcfef97d4982f15fe011e443f2c1a6ef4a3c8120510f2e13a5 run_m7_old.log.txt
+c21c79524c5fe2f480f20453e9c5f0409ce88907d12cc2cda1c5345702028862 selftest_ref_vs_ref.md
+12b3f67e32c412bb590de3f37aeebd8048d16248128fb6e8043929dd80817f7e train_summary.json
+ffe7552f21f12b28089bf9604c74699ff8074543c7d750d7028aaf2ae7830f4c verdict_m7_old_v41.json
+f6a847d5c3e9f3303c2584c5b274f0a691272ba6697b84c59bb716ed602ad9a7 verdict_m7_old_v41.md
diff --git a/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/code/run_eval_m7_v41.sh b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/code/run_eval_m7_v41.sh
new file mode 100644
index 0000000000000000000000000000000000000000..861196d434a2060bf62054ed349e5a3225f0aa28
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/code/run_eval_m7_v41.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# SPIRA Hashing — éval banc v4.1 (eval_bench_v4.py de Checker, CLI lecture seule, sorties redirigées ici) de M7 old puis verdict.
+# Attend la sortie de 21098 puis MemAvailable >= 4 Go (poll 180 s) ; une seule éval ; plafond prlimit --as (défaut 1,5 Gio, consigne parent 23 h 10). 1 cœur, nice 10.
+export OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0 PYTHONDONTWRITEBYTECODE=1
+D=/workspace/spira_shared/hashing_gen/m7_v41; PY=/workspace/SPIRA-venv/bin/python; cd $D
+log(){ echo "$(TZ=America/Toronto date '+%F %H:%M:%S %Z') $*" >> $D/run_eval_m7_v41.log; }
+log "start pid $$"
+while kill -0 21098 2>/dev/null; do sleep 180; done; log "21098 sorti (gate final 789343 arrêté par SIGTERM par le parent à 23 h 10, CalledProcessError)"
+while pgrep -f "eval_bench_v4.py.*m7_old" >/dev/null; do log "une éval m7_old tourne déjà"; sleep 180; done
+while :; do ma=$(awk '/MemAvailable/{print $2}' /proc/meminfo); [ "$ma" -ge 4194304 ] && break; log "attente mem MemAvailable=${ma} kB"; sleep 180; done
+log "lancement éval MemAvailable=${ma} kB"
+HITS=$D/hits OUT=$D/results_m7_v41.jsonl WINDOWS=seen,fc2,fresh_en,fresh_fr,test20k,queries,test_v3 \
+ prlimit --as=${ASCAP:-1610612736} nice -n 10 taskset -c 0 $PY /workspace/spira_shared/checker/scale/eval_bench_v4.py /workspace/spira_shared/spira_m7/cm_old_local_v1.npz old_local_v1 m7_old > $D/eval_m7_old.log 2>&1
+rc=$?; log "éval rc=$rc"; [ $rc -eq 0 ] || exit $rc
+nice -n 10 $PY $D/verdict_m7_v41.py $D/hits m7_old /workspace/spira_shared/checker/scale/hits_v4 old_ref $D/verdict_m7_old_v41 > $D/verdict_m7_old_v41.log 2>&1
+log "verdict rc=$?"; touch $D/verdict.done
diff --git a/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/code/run_m7_old_local_v1.py b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/code/run_m7_old_local_v1.py
new file mode 100644
index 0000000000000000000000000000000000000000..fe00676d2af491f1dbc9977910e2e61ec618b2ce
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/code/run_m7_old_local_v1.py
@@ -0,0 +1,51 @@
+"""M7 étape 1 sur old_local_v1 (Hashing, 2026-10-23). CMSPIRA (v3 + CM d24/4096, ±2, top-16 PPMI),
+config de base du repo (SPIRAConfig() par défaut). calibrate_fusion(train[:60_000]) AVANT la sauvegarde finale.
+Puis : rejeu de M9g+BAN1 et de l'int8 sur le ckpt réel, et run_gate_cm_v2 (test.bin 20k positions, oneshot.bin)."""
+import sys, os, json, time, subprocess, numpy as np
+S = "/workspace/spira_shared/semhash"; sys.path.insert(0, S)
+from countmin import CMSPIRA, save_with_calibration, SPIRAConfig
+from m9g_ban1 import JMNgram, generate_m9g
+from int8_wout import quantize, dequantize
+D = "/workspace/spira_shared/broad/old_local_v1"; O = "/workspace/spira_shared/spira_m7"
+log = lambda *a: print(time.strftime("%H:%M:%S"), *a, flush=True)
+train = open(f"{D}/train.bin", "rb").read()
+cfg = SPIRAConfig()
+log("cfg", cfg)
+m = CMSPIRA.build_cm(train, cfg, log=log)
+m.prepare(); h = m.train(log_fn=log, ckpt_path=f"{O}/cm_old_partial_nocal.npz")
+ck = f"{O}/cm_old_local_v1.npz"
+saved = save_with_calibration(m, ck, train[:60_000])
+log("CALIBRATED+SAVED", saved)
+json.dump({"history": h, "fusion": saved, "ckpt": ck}, open(f"{O}/train_summary.json", "w"), default=str, indent=1)
+m = CMSPIRA.load(ck); assert m.fusion["scale"] == saved["scale"]
+# int8 sur vrai ckpt
+test = open(f"{D}/test.bin", "rb").read()
+W = m.core.W_out.copy(); Wq, s = quantize(W); Wd = dequantize(Wq, s)
+from spira.hashing import fnv1a64
+pt = m.ept.segment(test); ids = np.fromiter((fnv1a64(p) for p in pt), np.uint64)[:20001]
+r = m.neuron_rows(ids[:-1], pt[:20000]); cols = m.cols_of(ids[1:])
+snap = m.core.snapshot(); m.core.reset_dynamics(); af = aq = ag = a_only = b_only = 0
+for t in range(20000):
+ x = m.core.step(r[t]) - m.core.x_mean
+ a, b = int(np.argmax(x @ W)), int(np.argmax(x @ Wd)); y = int(cols[t])
+ ag += a == b; af += a == y; aq += b == y; a_only += (a == y) and (b != y); b_only += (b == y) and (a != y)
+m.core.restore(snap)
+from run_gate_cm_v2 import mcnemar_exact
+mc = mcnemar_exact(np.array([1]*a_only+[0]*b_only, bool), np.array([0]*a_only+[1]*b_only, bool))
+int8 = {"n": 20000, "agree": ag, "acc_f32": af, "acc_int8": aq, "mcnemar": mc, "mem_ratio": W.nbytes/(Wq.nbytes+s.nbytes)}
+log("INT8", int8); json.dump(int8, open(f"{O}/int8_real.json", "w"), indent=1)
+# M9g+BAN1 sur vrai ckpt (n-gramme sur train complet)
+ng = JMNgram(m.cols_of(m._ids_train) if hasattr(m, "_ids_train") else None, cfg.vocab_size) if False else None
+ptr = m.ept.segment(train); idt = np.fromiter((fnv1a64(p) for p in ptr), np.uint64, len(ptr))
+ng = JMNgram(m.cols_of(idt), cfg.vocab_size)
+gens = []
+for i, pr in enumerate([b"The old man said that", b"def __init__(self, ", b"Il y avait une fois"]):
+ for ban in (True, False):
+ o, st = generate_m9g(m, ng, pr, n_tokens=200, seed=0, ban=ban)
+ g = o[len(pr):]; gr = [g[j:j+8] for j in range(len(g)-7)]
+ gens.append({"prompt": pr.decode(), "ban1": ban, "rep8": len(gr)-len(set(gr)), "n_bytes": len(g), "stats": st, "text": g.decode("utf-8", "replace")})
+ log("GEN", ban, gens[-1]["rep8"], repr(g[:120]))
+json.dump(gens, open(f"{O}/m9g_ban1_real.json", "w"), indent=1, ensure_ascii=False)
+subprocess.run([sys.executable, f"{S}/run_gate_cm_v2.py", "--ckpt", ck, "--cm", "--window", f"test20k={D}/test.bin",
+ "--window", f"oneshot={D}/oneshot.bin", "--max-pos", "20000", "--out", f"{O}/results_gate_v2.jsonl"], check=True)
+log("DONE")
diff --git a/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/code/test_unit_mcn.py b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/code/test_unit_mcn.py
new file mode 100644
index 0000000000000000000000000000000000000000..1f97aaa9bfe47af60a47dd25abffd70be8b655da
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/code/test_unit_mcn.py
@@ -0,0 +1,15 @@
+"""Test : unit_mcn de verdict_m7_v41.py == unit_mcn de checker/scale/scale_bench_v4.py (lecture seule) sur old_ref vs broad14_ref (tokenizers différents), sans masque."""
+import numpy as np, re
+src = open("verdict_m7_v41.py").read(); g = {"np": np}
+exec(src[src.index("def unit_mcn"):src.index("def blocksums")], g)
+cs = open("/workspace/spira_shared/checker/scale/scale_bench_v4.py").read(); h = {"np": np, "mcn": lambda b, c: None}
+exec(cs[cs.index("def unit_mcn"):cs.index("def bytehits")], h)
+H = "/workspace/spira_shared/checker/scale/hits_v4"; ok = True
+for w in ["fc2", "fresh_en", "fresh_fr", "test20k", "queries", "test_v3"]:
+ A, B = np.load(f"{H}/old_ref__{w}.npz"), np.load(f"{H}/broad14_ref__{w}.npz")
+ ha, hb = A["fused_hit"].astype(bool), B["fused_hit"].astype(bool)
+ k1 = g["unit_mcn"](A, B, ha, hb, np.ones(len(ha), bool), np.ones(len(hb), bool))
+ lo = max(A["tgt_start"][0], B["tgt_start"][0]); hi = min((A["tgt_start"] + A["tgt_len"])[-1], (B["tgt_start"] + B["tgt_len"])[-1])
+ k2 = h["unit_mcn"](A, B, lo, hi)[:3]; same = tuple(k1) == tuple(k2); ok &= same
+ print(w, "hashing", k1, "checker", k2, "OK" if same else "DIFF")
+print("ALL OK" if ok else "MISMATCH")
diff --git a/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/code/verdict_m7_v41.py b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/code/verdict_m7_v41.py
new file mode 100644
index 0000000000000000000000000000000000000000..1102b01cf22018e2eeae164f8837f610b8871596
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/code/verdict_m7_v41.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict v4.1 : M7 old (cand) contre old_ref (réf), lecture seule des hits (aucun modèle chargé).
+Usage : verdict_m7_v41.py CAND_HITS_DIR CAND_TAG REF_HITS_DIR REF_TAG OUT_PREFIX
+Fenêtres : seen, fc2, fresh_en, fresh_fr, test20k (positions propres vs old_local_v1/train.bin, mask_old_bench.npz), queries, test_v3.
+neither_code exclu (contaminé). hit = fused_hit & invocab (masque invocab Checker 19 h 55).
+Appariement : si tgt_start ET tgt_len identiques (même tokenizer) → par position ; sinon unités entre frontières de patch communes
+(unit_mcn de scale_bench_v4.py : unité réussie ssi toutes ses cibles sont des hits).
+McNemar exact bilatéral (binomial) sur les discordants = DÉCISION (p<0,05). Bootstrap par blocs : blocs de 512 octets de la fenêtre
+(bloc = tgt_start // 512), B = 10 000, un seul générateur seed 0 tiré fenêtre après fenêtre (ordre WIN), même tirage pour les deux modèles (apparié) ; stat = acc invocab (hits/invocab).
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3), queries à part ; IC bootstrap (tirages indépendants par fenêtre).
+Critère : RETENU ssi gain significatif sur seen ET gain significatif sur ≥1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3 ; queries à part)
+ET aucune perte significative sur une fenêtre valide."""
+import sys, json, math, hashlib, numpy as np
+CD, CT, RD, RT, OP = sys.argv[1:6]
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "queries", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"] # queries : fenêtre valide (pertes comptées) mais rapportée à part, hors « fraîches »
+GAPW = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+MK = np.load("/workspace/spira_shared/hashing_gen/m7_v41/mask_old_bench.npz")
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def unit_mcn(za, zb, ha_, hb_, keep_a, keep_b):
+ sa, ea = za["tgt_start"][keep_a], (za["tgt_start"] + za["tgt_len"])[keep_a]; sb, eb = zb["tgt_start"][keep_b], (zb["tgt_start"] + zb["tgt_len"])[keep_b]
+ ha_, hb_ = ha_[keep_a], hb_[keep_b]; lo, hi = max(sa[0], sb[0]), min(ea[-1], eb[-1])
+ common = np.intersect1d(np.concatenate([sa, ea[-1:]]), np.concatenate([sb, eb[-1:]])); common = common[(common >= lo) & (common <= hi)]
+ def uh(s, e, h):
+ k = np.searchsorted(common, s, side="right") - 1; ok = (s >= common[0]) & (e <= common[-1]); u = np.ones(len(common) - 1, bool); np.logical_and.at(u, k[ok], h[ok]); return u
+ def cnt(s, e):
+ k = np.searchsorted(common, s, side="right") - 1; ok = (s >= common[0]) & (e <= common[-1]); return np.bincount(k[ok], minlength=len(common) - 1)[:len(common) - 1]
+ x, y = uh(sa, ea, ha_), uh(sb, eb, hb_); v = (cnt(sa, ea) > 0) & (cnt(sb, eb) > 0) # unités sans cible gardée d'un côté (masque) exclues
+ x, y = x[v], y[v]; return len(x), int((x & ~y).sum()), int((~x & y).sum())
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {} # un seul flux seed 0, tirages successifs par fenêtre (ordre WIN) → indépendants entre fenêtres
+for w in WIN:
+ A = np.load(f"{RD}/{RT}__{w}.npz"); B = np.load(f"{CD}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MK["sha__test20k"]) == str(A["window_sha256"]); cov = MK["test20k__covered"]
+ bad = lambda Z: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(Z["tgt_start"], Z["tgt_len"])])
+ ka, kb = ~bad(A), ~bad(B)
+ else: ka, kb = np.ones(na, bool), np.ones(nb_, bool)
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ if same_tok:
+ k = ka & kb; b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); pairing = "position (tokenizers identiques)"
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ else:
+ npair, b, c = unit_mcn(A, B, ha, hb, ka, kb); pairing = "unités entre frontières communes"; inv_same = None
+ p = binp(b, c)
+ ia, ib = A["invocab"].astype(bool) & ka, B["invocab"].astype(bool) & kb
+ acc_a, acc_b = 100 * (ha & ka).sum() / ia.sum(), 100 * (hb & kb).sum() / ib.sum()
+ nbk = int(max(A["tgt_start"].max(), B["tgt_start"].max()) // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][ka], ha[ka], A["invocab"].astype(bool)[ka], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][kb], hb[kb], B["invocab"].astype(bool)[kb], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1); d = bb - ba
+ BOOT[w] = (ba, bb)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions_ref": na, "n_positions_cand": nb_, "n_clean_ref": int(ka.sum()), "n_clean_cand": int(kb.sum()), "n_invocab_ref": int(ia.sum()), "n_invocab_cand": int(ib.sum()),
+ "n_paired": npair, "pairing": pairing, "invocab_identical": inv_same, "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "boot_sig_agrees": bool((lo > 0) == gain and (hi < 0) == loss),
+ "window_sha256": str(A["window_sha256"]), "ept_budget_ref": float(A["ept_budget_bits"]), "ept_budget_cand": float(B["ept_budget_bits"]),
+ "excluded_positions_ref": int((~ka).sum()), "excluded_positions_cand": int((~kb).sum())}
+ print(w, json.dumps(R[w]), flush=True)
+# écart seen − moyenne fraîche (5 fenêtres) ; tirages bootstrap indépendants entre fenêtres (même tirage pour les deux modèles dans une fenêtre)
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.percentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.percentile(dg, [2.5, 97.5])]}
+gap["windows"] = GAPW; gap["note"] = "queries hors moyenne (rapportée à part) ; neither_code exclu"
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "RETENU" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+out = {"cand": CT, "ref": RT, "windows": WIN, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "RETENU ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (7 fenêtres, queries compris)", "queries_gain_would_count": bool(R["queries"]["sig_gain"]),
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap,
+ "test20k_mask": "positions dont [s-64, s+l) touche un 64-gramme confirmé de old_local_v1/train.bin (mask_old_bench.npz)",
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict v4.1 — M7 old ({CT}) contre {RT}\n", f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ md.append(f"| {w} | {r['n_paired']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["", f"Écart seen − moyenne fraîche ({', '.join(GAPW)}) : M7 {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence M7 − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [{gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}]. queries à part (table). neither_code exclu.", ""]
+open(f"{OP}.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/selftest_ref_vs_ref.md b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/selftest_ref_vs_ref.md
new file mode 100644
index 0000000000000000000000000000000000000000..a6bd36378e08e3d1788f54c60b64bbb48ef34f20
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/selftest_ref_vs_ref.md
@@ -0,0 +1,16 @@
+# Verdict v4.1 — M7 old (old_ref) contre old_ref
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche
+
+| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 8000 | 98.330 | 98.330 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fc2 | 8000 | 11.504 | 11.504 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | 8000 | 3.395 | 3.395 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_fr | 8000 | 0.283 | 0.283 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test20k | 20000 | 2.900 | 2.900 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| queries | 7099 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | 20000 | 4.117 | 4.117 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k, test_v3) : M7 +93.890 pts [IC95 +93.410 ; +94.345] (fraîche 4.440 %) ; réf +93.890 pts [+93.410 ; +94.345] (fraîche 4.440 %) ; différence M7 − réf +0.000 [+0.000 ; +0.000]. queries à part (table). neither_code exclu.
+
diff --git a/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/train_summary.json b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/train_summary.json
new file mode 100644
index 0000000000000000000000000000000000000000..5b8c4f4a7ec4086e4badb9a060214d4af08f4cdc
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/train_summary.json
@@ -0,0 +1,36 @@
+{
+ "history": {
+ "epochs": [
+ {
+ "ticks": 600000,
+ "accuracy": 0.06082333333333333,
+ "accuracy_fast_only": 0.08459833333333333,
+ "beta": 0.10087046869458932,
+ "acc_ema_final": 0.21631616562234157,
+ "elapsed_s": 25419.800736482997,
+ "ticks_per_sec": 23.60364686647084
+ },
+ {
+ "ticks": 600000,
+ "accuracy": 0.067085,
+ "accuracy_fast_only": 0.11190833333333333,
+ "beta": 0.07528583775305782,
+ "acc_ema_final": 0.24721433238185916,
+ "elapsed_s": 24463.95195775,
+ "ticks_per_sec": 24.52588204212543
+ }
+ ],
+ "am": {
+ "slots": 8388608,
+ "used": 3948803,
+ "load_factor": 0.47073400020599365,
+ "n_writes": 1199996
+ }
+ },
+ "fusion": {
+ "scale": 0.056658798957008934,
+ "sigma_fast": 0.04551528212138245,
+ "sigma_slow": 0.8033223958015442
+ },
+ "ckpt": "/workspace/spira_shared/spira_m7/cm_old_local_v1.npz"
+}
\ No newline at end of file
diff --git a/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/verdict_m7_old_v41.json b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/verdict_m7_old_v41.json
new file mode 100644
index 0000000000000000000000000000000000000000..e492137d0e55e1faf30a729d8034cacd5adc460d
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/verdict_m7_old_v41.json
@@ -0,0 +1,401 @@
+{
+ "cand": "m7_old",
+ "ref": "old_ref",
+ "windows": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen"
+ ],
+ "losses": [],
+ "gains": [
+ "fc2",
+ "fresh_en",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "fresh_gains": [
+ "fc2",
+ "fresh_en",
+ "test20k",
+ "test_v3"
+ ],
+ "rule": "RETENU ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (7 fenêtres, queries compris)",
+ "queries_gain_would_count": true,
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5868,
+ "n_invocab_cand": 5868,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 98.32992501704157,
+ "acc_cand_pct": 98.27880027266531,
+ "delta_pct": -0.05112474437626702,
+ "b_ref_only": 8,
+ "c_cand_only": 5,
+ "mcnemar_p": 0.5810546875,
+ "boot_ci95_delta_pct": [
+ -0.17018524712170519,
+ 0.0684934439421255
+ ],
+ "boot_p": 0.4876,
+ "n_blocks": 71,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "7585ad82947bbe8b2ae6484b1922511b483c11d84bde5b0a53978135d0eb99ca",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fc2": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 4833,
+ "n_invocab_cand": 4833,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 11.504241671839438,
+ "acc_cand_pct": 12.787088764742396,
+ "delta_pct": 1.2828470929029585,
+ "b_ref_only": 87,
+ "c_cand_only": 149,
+ "mcnemar_p": 6.552303801488519e-05,
+ "boot_ci95_delta_pct": [
+ 0.45043115921060234,
+ 2.098058259676331
+ ],
+ "boot_p": 0.0022,
+ "n_blocks": 76,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_en": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5714,
+ "n_invocab_cand": 5714,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 3.3951697584879246,
+ "acc_cand_pct": 4.532726636331817,
+ "delta_pct": 1.1375568778438923,
+ "b_ref_only": 60,
+ "c_cand_only": 125,
+ "mcnemar_p": 2.0116885464439608e-06,
+ "boot_ci95_delta_pct": [
+ 0.6466185823810344,
+ 1.6493154579092075
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 70,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_fr": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 3179,
+ "n_invocab_cand": 3179,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.28310789556464294,
+ "acc_cand_pct": 0.1887385970430953,
+ "delta_pct": -0.09436929852154763,
+ "b_ref_only": 7,
+ "c_cand_only": 4,
+ "mcnemar_p": 0.548828125,
+ "boot_ci95_delta_pct": [
+ -0.2924926876828079,
+ 0.0981370330335732
+ ],
+ "boot_p": 0.4494,
+ "n_blocks": 60,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test20k": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 20000,
+ "n_clean_cand": 20000,
+ "n_invocab_ref": 13379,
+ "n_invocab_cand": 13379,
+ "n_paired": 20000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 2.9000672696016143,
+ "acc_cand_pct": 3.602660886463861,
+ "delta_pct": 0.7025936168622469,
+ "b_ref_only": 155,
+ "c_cand_only": 249,
+ "mcnemar_p": 3.371499782730385e-06,
+ "boot_ci95_delta_pct": [
+ 0.3881154573588749,
+ 1.0131710950224935
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test20k_strict": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 19872,
+ "n_clean_cand": 19872,
+ "n_invocab_ref": 13350,
+ "n_invocab_cand": 13350,
+ "n_paired": 19872,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 2.906367041198502,
+ "acc_cand_pct": 3.602996254681648,
+ "delta_pct": 0.696629213483146,
+ "b_ref_only": 155,
+ "c_cand_only": 248,
+ "mcnemar_p": 4.181148367905839e-06,
+ "boot_ci95_delta_pct": [
+ 0.3815901472969536,
+ 1.008646594046961
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 128,
+ "excluded_positions_cand": 128,
+ "excluded_by_broad_local_v1_ref_cand": [
+ 128,
+ 128
+ ]
+ },
+ "queries": {
+ "n_positions_ref": 7099,
+ "n_positions_cand": 7099,
+ "n_clean_ref": 7099,
+ "n_clean_cand": 7099,
+ "n_invocab_ref": 3349,
+ "n_invocab_cand": 3349,
+ "n_paired": 7099,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 1.1645267243953419,
+ "delta_pct": 1.1645267243953419,
+ "b_ref_only": 0,
+ "c_cand_only": 39,
+ "mcnemar_p": 3.637978807091713e-12,
+ "boot_ci95_delta_pct": [
+ 0.9682299546142209,
+ 1.3489824002954531
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 55,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test_v3": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 20000,
+ "n_clean_cand": 20000,
+ "n_invocab_ref": 12922,
+ "n_invocab_cand": 12922,
+ "n_paired": 20000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 4.117009750812568,
+ "acc_cand_pct": 4.697415260795543,
+ "delta_pct": 0.5804055099829748,
+ "b_ref_only": 241,
+ "c_cand_only": 316,
+ "mcnemar_p": 0.001691499949113725,
+ "boot_ci95_delta_pct": [
+ 0.04663934878203853,
+ 1.070173904132315
+ ],
+ "boot_p": 0.0368,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 4.439919269261237,
+ "seen_pct": 98.32992501704157,
+ "gap_pct": 93.89000574778034,
+ "ci95": [
+ 93.40985672775108,
+ 94.34460115328463
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 5.161726029075342,
+ "seen_pct": 98.27880027266531,
+ "gap_pct": 93.11707424358997,
+ "ci95": [
+ 92.62985938430558,
+ 93.5910453158752
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.7729315041903675,
+ "ci95": [
+ -1.0284176901635749,
+ -0.5079878367244357
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "note": "queries hors moyenne (rapportée à part) ; neither_code exclu ; NON STRICT (test20k masqué old_local_v1 seul) — voir seen_fresh_gap_strict"
+ },
+ "test20k_mask": "positions dont [s-64, s+l) touche un 64-gramme confirmé de old_local_v1/train.bin (mask_old_bench.npz)",
+ "script_sha256": "10ac5fed0693523187416793f330aa5d1b76dc06236b015fbb8b50e8be2f6fd1",
+ "test20k_mask_note": "per_window.test20k = NON STRICT (masque old_local_v1 seul : 0 position exclue). per_window.test20k_strict = STRICT-CLEAN (règle Checker) : union old_local_v1 ∪ broad_local_v1 (test20k = broad/broad_local_v1/test.bin) ; position exclue ssi un octet de [s-64, s+l) est couvert par un 64-gramme confirmé octet à octet du train ; 128 positions exclues (toutes par broad_local_v1 ; 0 par old_local_v1), 19 872 positions gardées, 13 350 invocab. Décision inchangée (REJETÉ).",
+ "test20k_strict_mask": {
+ "trains": [
+ "old_local_v1/train.bin",
+ "broad_local_v1/train.bin"
+ ],
+ "excluded_positions": 128,
+ "excluded_by_broad_local_v1": 128,
+ "excluded_by_old_local_v1": 0,
+ "broad_local_v1_train_sha256": "eda07017a87f2b7bbd55c5c2ea23032bf70a38ae7ad75167523228738f2391a1",
+ "broad_local_v1_bytes_covered": 45852,
+ "broad_local_v1_bytes_covered_in_evaluated_range": 272,
+ "old_local_v1_bytes_covered": 434640,
+ "hash64": "FNV-like P=1099511628211 +1 (même schéma que mask_old_bench.py), confirmation octet par octet",
+ "script": "hashing_gen/m7_v41/strict/mask_t20k_strict.py (local)",
+ "script_sha256": "41bbb74778267baade6392b25eefc1d5a2694393d49794d2074577d325b23ee9",
+ "mask_npz_sha256": "ffec4b136a7ace6f83a71144dae1366763ee400601dee4040681b529ed6c30ca",
+ "verdict_script": "hashing_gen/m7_v41/strict/verdict_m7_v41_strict.py (local ; copie de verdict_m7_v41.py, seul le masque test20k change + bootstrap positions seed 25)",
+ "verdict_script_sha256": "31317eb67d53dfeb743620eb66560097af67e7721c56a33c2103c60471fd5368",
+ "crosscheck": "identique au recompte indépendant de Checker (checker/recount/recount_m7old_v41_0025.py, hash 64-gramme différent) : 128 exclues, réf 2,906 %, M7 3,603 %, 155/248, p 4,18e-6"
+ },
+ "seen_fresh_gap_strict": {
+ "ref": {
+ "fresh_mean_pct": 4.4411792235806145,
+ "seen_pct": 98.32992501704157,
+ "gap_pct": 93.88874579346096,
+ "ci95": [
+ 93.40808437044318,
+ 94.34310346694095
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 5.1617931027189,
+ "seen_pct": 98.27880027266531,
+ "gap_pct": 93.1170071699464,
+ "ci95": [
+ 92.62969764725754,
+ 93.5915987931397
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.7717386235145511,
+ "ci95": [
+ -1.027180949736615,
+ -0.5072917540992503
+ ],
+ "ci95_boot_positions_seed25": [
+ -0.9948064395286004,
+ -0.5482757306520287
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k_strict",
+ "test_v3"
+ ],
+ "note": "test20k strict-clean (union old_local_v1 ∪ broad_local_v1, 128 exclues) ; ci95 = bootstrap blocs 512 o, B=10 000, seed 0 ; ci95_boot_positions_seed25 = bootstrap par positions invocab propres, apparié, B=10 000, seed 25 (schéma principal de Checker) ; queries hors moyenne ; neither_code exclu"
+ }
+}
\ No newline at end of file
diff --git a/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/verdict_m7_old_v41.md b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/verdict_m7_old_v41.md
new file mode 100644
index 0000000000000000000000000000000000000000..e44e66009a2ece0df17fcb1ebaa4c97c6f310fad
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check_post/results/hashing/m7_old/verdict_m7_old_v41.md
@@ -0,0 +1,53 @@
+# Verdict v4.1 — M7 old (m7_old) contre old_ref
+
+**REJETÉ** — pas de gain significatif sur seen
+
+| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 8000 | 98.279 | 98.330 | -0.051 | 8/5 | 0.581 | [-0.170 ; +0.068] | n.s. |
+| fc2 | 8000 | 12.787 | 11.504 | +1.283 | 87/149 | 6.55e-05 | [+0.450 ; +2.098] | GAIN |
+| fresh_en | 8000 | 4.533 | 3.395 | +1.138 | 60/125 | 2.01e-06 | [+0.647 ; +1.649] | GAIN |
+| fresh_fr | 8000 | 0.189 | 0.283 | -0.094 | 7/4 | 0.549 | [-0.292 ; +0.098] | n.s. |
+| test20k non strict (masque old_local_v1 seul, 0 exclue) | 20000 | 3.603 | 2.900 | +0.703 | 155/249 | 3.37e-06 | [+0.388 ; +1.013] | GAIN |
+| **test20k strict-clean** (old_local_v1 ∪ broad_local_v1, 128 exclues) | 19872 | 3.603 | 2.906 | +0.697 | 155/248 | 4.18e-06 | [+0.382 ; +1.009] | GAIN |
+| queries | 7099 | 1.165 | 0.000 | +1.165 | 0/39 | 3.64e-12 | [+0.968 ; +1.349] | GAIN |
+| test_v3 | 20000 | 4.697 | 4.117 | +0.580 | 241/316 | 0.00169 | [+0.047 ; +1.070] | GAIN |
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, **test20k strict-clean**, test_v3) : M7 +93.117 pts [IC95 +92.630 ; +93.592] (fraîche 5.162 %) ; réf +93.889 pts [+93.408 ; +94.343] (fraîche 4.441 %) ; différence M7 − réf **-0.772** [-1.027 ; -0.507] (bootstrap blocs 512 o, B=10 000, seed 0) ; [-0.995 ; -0.548] (bootstrap positions apparié, B=10 000, seed 25). Non strict (test20k masqué old_local_v1 seul) : M7 +93.117 [+92.630 ; +93.591] ; réf +93.890 [+93.410 ; +94.345] (fraîche 4.440 %) ; différence -0.773 [-1.028 ; -0.508]. queries à part (table). neither_code exclu.
+
+
+## Protocole et provenance
+
+- Candidat : M7 old = `spira_m7/cm_old_local_v1.npz` (446 551 146 o, sha256 396f11a142475cca3ee413066423aab9d4e3f708db191d3b96b8321875182b5f), checkpoint CALIBRÉ (sauvé 22 h 43 Toronto ; ni partial ni nocal). Corpus old_local_v1 (train sha256 e12b6586…ded54, 12 468 350 o). 2 époques × 600 000 ticks (train_summary.json).
+- Réf : old_ref = `checker/ckpt/ref_fixed2cal_old_local_v1.npz`, hits existants `checker/scale/hits_v4/old_ref__*.npz` (lecture seule). m9g v2b non utilisé (invalidé).
+- Éval M7 : `checker/scale/eval_bench_v4.py` de Checker appelé en CLI sans modification (HITS/OUT redirigés vers hashing_gen/m7_v41/, PYTHONDONTWRITEBYTECODE=1), fenêtres seen, fc2, fresh_en, fresh_fr, test20k, queries, test_v3 ; neither_code non évalué. Pleine longueur (8 000 / 20 000 positions, MAXPOS=0). 1 cœur (taskset -c 0), nice 10, OMP_NUM_THREADS=1, PYTHONHASHSEED=0. Durée 47 min 50 s (23 h 33 → 00 h 21 Toronto ; chargement 137,9 s + 2 732 s d’éval), pic RSS 1 004,7 Mo.
+- Fusion : comme pour toutes les entrées du banc v4, `bench_common.load_model` recalibre la fusion sur train[:60 000] au chargement : scale 0,055984 (valeur sauvée 0,056659). Les deux modèles sont traités de la même façon.
+- Tokenizers identiques (tgt_start, tgt_len, invocab égaux sur les 7 fenêtres ; EPT budget 15,3657 bits des deux côtés) → appariement par POSITION. hit = fused_hit ∧ invocab ; acc = hits / positions invocab.
+- McNemar exact bilatéral = décision (p < 0,05). Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un seul générateur seed 0 tiré fenêtre après fenêtre → indicatif ; aucune contradiction bootstrap/McNemar.
+- Critère (Philippe-Antoine) : RETENU ssi gain significatif sur seen ET sur ≥ 1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (queries compris). queries rapportée à part, hors moyenne fraîche.
+- Auto-test réf contre réf (`selftest_ref_vs_ref.md`) : 0/0 partout, Δ = 0, accs = results_v4.jsonl de Checker. `test_unit_mcn.py` : chemin d'appariement par unités = `unit_mcn` de scale_bench_v4.py sur 6 fenêtres (non utilisé ici, tokenizers identiques).
+
+## test20k : traitement
+
+- test20k = `broad/broad_local_v1/test.bin` (894 718 o, sha256 e89725bb…a9). Masque `mask_old_bench.npz` : 64-grammes confirmés octet à octet contre old_local_v1/train.bin ; position exclue ssi un octet de [s−64, s+l) est couvert. 434 640 octets couverts sur la fenêtre, mais le premier octet couvert est 144 389 alors que les 20 000 cibles évaluées couvrent [2 ; 88 765) → **0 position exclue**. Contre-vérification à hash indépendant (`crosscheck_mask_t20k.json`) : masque identique sur [0 ; 199 936), 0 octet couvert dans la plage évaluée.
+- **Strict-clean (correctif Hashing, 24 oct. ~00 h 55 Toronto, réserve Checker 00 h 48)** : masque recalculé par Hashing (`strict/mask_t20k_strict.py`, même schéma que mask_old_bench.py) contre broad_local_v1/train.bin (sha256 eda07017…91a1) et old_local_v1/train.bin ; règle : position exclue ssi un octet de [s−64, s+l) est couvert. broad_local_v1 couvre 45 852 octets de test20k, dont 272 dans la plage évaluée → **128 positions exclues** (toutes par broad_local_v1 ; 0 par old_local_v1), 19 872 gardées, 13 350 invocab. Résultat (`strict/verdict_m7_v41_strict.py`, verdict_m7_v41.py avec ce seul masque changé) : réf 2,906 %, M7 3,603 %, Δ +0,697, b/c 155/248, McNemar exact p = 4,18e-6, IC95 bootstrap [+0,382 ; +1,009] → GAIN ; décision REJETÉ inchangée. Identique au recompte indépendant de Checker (relais 00 h 30 / 00 h 45). JSON : `per_window.test20k_strict`, `test20k_strict_mask`, `seen_fresh_gap_strict` (entrées non strictes conservées).
+- `verify_old_local_v1.json` (INVALID DELTA ≠ 0) concerne le test propre du corpus old (old_local_v1/test.bin, 1 396 positions 64 o partagées avec son train) et neither_code (224 303) : pas utilisés dans ce verdict.
+
+## Référence M7 old validée par Checker (éval réf v2, hors banc v4.1)
+
+Chiffres de `checker/m8/results_m8.jsonl` (lignes 1, 3, 5, 7 ; tag cm_old_local_v1, script eval_ref_v2, 8 000 positions, fused sur TOUTES les positions, hors vocabulaire = échec), recomptés par Checker depuis les booléens par position : `spira_relay.md` l. 3870 et 3876 (Checker 23 h 00, `checker/recount/recount_m7old_ref_2300.py`) et l. 3890–3891 (Checker 23 h 07, `checker/recount/recount_m7old_fresh_2307.py`). Vérifié dans le jsonl par Hashing :
+
+| fenêtre (éval réf v2) | fused toutes positions | fused invocab | couverture vocab |
+|---|---|---|---|
+| seen | 98,06 % (0,980625) | 98,279 % | 0,7335 |
+| freshcode (fenêtre M7, pas dans le banc v4.1) | 55,81 % (0,558125) | 59,374 % | 0,67875 |
+| fresh_en | 3,25 % (0,0325) | 4,533 % | 0,71425 |
+| fresh_fr | 0,075 % (0,00075) | 0,189 % | 0,397375 |
+
+Les valeurs invocab de l'éval réf v2 sont identiques à celles du banc v4.1 ci-dessus (98,279 / 4,533 / 0,189) : seul le dénominateur diffère (Checker 00 h 30 l'a aussi constaté).
+
+## Incidents et limites
+
+- 21098 (script M7) n'est pas allé au bout : son étape finale run_gate_cm_v2 (PID 789343, test20k/oneshot du corpus old) a été arrêtée par SIGTERM à 23 h 10 lors de l'alerte mémoire (MemAvailable 0,73 Go, chrome tué par l'OOM) → CalledProcessError. `results_gate_v2.jsonl` est incomplet : ni utilisé ni poussé. int8_real.json et m9g_ban1_real.json ont été écrits avant.
+- Premier lancement de l'éval avec plafond `prlimit --as=1,5 Gio` : échec immédiat (_ArrayMemoryError au chargement de W_out, 416 Mio ; `eval_m7_old_fail_as1536M.log`). Relancé une fois avec `--as=2,5 Gio` (VmPeak mesuré 1,64 Go, pic RSS 1,00 Go). Lancement à MemAvailable 4,57 Go (porte ≥ 4 Go ; la règle ≥ 5,2 Go est arrivée après le lancement).
+- Une seule graine bootstrap, une seule exécution : pas de variance inter-entraînements mesurée.
diff --git a/results/hashing/m7_v41/strict/hf_check_pre/results/hashing/m7_old/SHA256SUMS b/results/hashing/m7_v41/strict/hf_check_pre/results/hashing/m7_old/SHA256SUMS
new file mode 100644
index 0000000000000000000000000000000000000000..f92d2d65078c2eea1a5b36f41e6ee9506ec69d4c
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check_pre/results/hashing/m7_old/SHA256SUMS
@@ -0,0 +1,16 @@
+396f11a142475cca3ee413066423aab9d4e3f708db191d3b96b8321875182b5f cm_old_local_v1.npz
+fdee6dc046ea48c19b0c96510eaa6cece2ac4974cb9fd786c9aef142fe8cdfff code/crosscheck_mask_t20k.py
+e7c4ad734a7b2c567fb7c1eb6e827aea15c81673d62180f01bca1e1581d339fa code/mask_old_bench.py
+99ea3a2119dfbdab24f4fc45faed3fb2dd7188a0d3557b4127ef515ea7281f91 code/run_eval_m7_v41.sh
+aa36c8ec8278addf426fd5220db0b446085e5b95003d585778603a30c0a502f7 code/run_m7_old_local_v1.py
+00e2313f3e4c2026099cf071141c793f35a5b407548c8cbe9b2e4ae5ad5fe0e2 code/test_unit_mcn.out
+26d7b4b1b3f4ebd07c4eb5036eb93c01b22cd52156f405e44791111768af36db code/test_unit_mcn.py
+10ac5fed0693523187416793f330aa5d1b76dc06236b015fbb8b50e8be2f6fd1 code/verdict_m7_v41.py
+71505da18db5d189cc9cb4bc0fe748381e08f67bd62548ae456348bf2866baaa crosscheck_mask_t20k.json
+fc089ac386674a7186664cfad06b0d81251ace35e16de1ac12b223617a3e3379 eval_m7_old.log
+77215abd17ace6b1b003254f643e2bddeae8b8115aac3445ca17b2c5192ba1d8 mask_old_bench.json
+e15cf361391e32bcfef97d4982f15fe011e443f2c1a6ef4a3c8120510f2e13a5 run_m7_old.log
+c21c79524c5fe2f480f20453e9c5f0409ce88907d12cc2cda1c5345702028862 selftest_ref_vs_ref.md
+12b3f67e32c412bb590de3f37aeebd8048d16248128fb6e8043929dd80817f7e train_summary.json
+45899fa171e3d8395fc0bdb020b2fa7115f30c194b0a44aefe38009888feb870 verdict_m7_old_v41.json
+520b2027d907f52af8ba601cb09f9efdab6bdb9a0d7d1aebd117c98a29e8ac15 verdict_m7_old_v41.md
diff --git a/results/hashing/m7_v41/strict/hf_check_pre/results/hashing/m7_old/verdict_m7_old_v41.json b/results/hashing/m7_v41/strict/hf_check_pre/results/hashing/m7_old/verdict_m7_old_v41.json
new file mode 100644
index 0000000000000000000000000000000000000000..7076de73c40cd76539f285499c9ab64f7e014452
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check_pre/results/hashing/m7_old/verdict_m7_old_v41.json
@@ -0,0 +1,305 @@
+{
+ "cand": "m7_old",
+ "ref": "old_ref",
+ "windows": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen"
+ ],
+ "losses": [],
+ "gains": [
+ "fc2",
+ "fresh_en",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "fresh_gains": [
+ "fc2",
+ "fresh_en",
+ "test20k",
+ "test_v3"
+ ],
+ "rule": "RETENU ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (7 fenêtres, queries compris)",
+ "queries_gain_would_count": true,
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5868,
+ "n_invocab_cand": 5868,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 98.32992501704157,
+ "acc_cand_pct": 98.27880027266531,
+ "delta_pct": -0.05112474437626702,
+ "b_ref_only": 8,
+ "c_cand_only": 5,
+ "mcnemar_p": 0.5810546875,
+ "boot_ci95_delta_pct": [
+ -0.17018524712170519,
+ 0.0684934439421255
+ ],
+ "boot_p": 0.4876,
+ "n_blocks": 71,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "7585ad82947bbe8b2ae6484b1922511b483c11d84bde5b0a53978135d0eb99ca",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fc2": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 4833,
+ "n_invocab_cand": 4833,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 11.504241671839438,
+ "acc_cand_pct": 12.787088764742396,
+ "delta_pct": 1.2828470929029585,
+ "b_ref_only": 87,
+ "c_cand_only": 149,
+ "mcnemar_p": 6.552303801488519e-05,
+ "boot_ci95_delta_pct": [
+ 0.45043115921060234,
+ 2.098058259676331
+ ],
+ "boot_p": 0.0022,
+ "n_blocks": 76,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_en": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5714,
+ "n_invocab_cand": 5714,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 3.3951697584879246,
+ "acc_cand_pct": 4.532726636331817,
+ "delta_pct": 1.1375568778438923,
+ "b_ref_only": 60,
+ "c_cand_only": 125,
+ "mcnemar_p": 2.0116885464439608e-06,
+ "boot_ci95_delta_pct": [
+ 0.6466185823810344,
+ 1.6493154579092075
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 70,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_fr": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 3179,
+ "n_invocab_cand": 3179,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.28310789556464294,
+ "acc_cand_pct": 0.1887385970430953,
+ "delta_pct": -0.09436929852154763,
+ "b_ref_only": 7,
+ "c_cand_only": 4,
+ "mcnemar_p": 0.548828125,
+ "boot_ci95_delta_pct": [
+ -0.2924926876828079,
+ 0.0981370330335732
+ ],
+ "boot_p": 0.4494,
+ "n_blocks": 60,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test20k": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 20000,
+ "n_clean_cand": 20000,
+ "n_invocab_ref": 13379,
+ "n_invocab_cand": 13379,
+ "n_paired": 20000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 2.9000672696016143,
+ "acc_cand_pct": 3.602660886463861,
+ "delta_pct": 0.7025936168622469,
+ "b_ref_only": 155,
+ "c_cand_only": 249,
+ "mcnemar_p": 3.371499782730385e-06,
+ "boot_ci95_delta_pct": [
+ 0.3881154573588749,
+ 1.0131710950224935
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "queries": {
+ "n_positions_ref": 7099,
+ "n_positions_cand": 7099,
+ "n_clean_ref": 7099,
+ "n_clean_cand": 7099,
+ "n_invocab_ref": 3349,
+ "n_invocab_cand": 3349,
+ "n_paired": 7099,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 1.1645267243953419,
+ "delta_pct": 1.1645267243953419,
+ "b_ref_only": 0,
+ "c_cand_only": 39,
+ "mcnemar_p": 3.637978807091713e-12,
+ "boot_ci95_delta_pct": [
+ 0.9682299546142209,
+ 1.3489824002954531
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 55,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test_v3": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 20000,
+ "n_clean_cand": 20000,
+ "n_invocab_ref": 12922,
+ "n_invocab_cand": 12922,
+ "n_paired": 20000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 4.117009750812568,
+ "acc_cand_pct": 4.697415260795543,
+ "delta_pct": 0.5804055099829748,
+ "b_ref_only": 241,
+ "c_cand_only": 316,
+ "mcnemar_p": 0.001691499949113725,
+ "boot_ci95_delta_pct": [
+ 0.04663934878203853,
+ 1.070173904132315
+ ],
+ "boot_p": 0.0368,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 4.439919269261237,
+ "seen_pct": 98.32992501704157,
+ "gap_pct": 93.89000574778034,
+ "ci95": [
+ 93.40985672775108,
+ 94.34460115328463
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 5.161726029075342,
+ "seen_pct": 98.27880027266531,
+ "gap_pct": 93.11707424358997,
+ "ci95": [
+ 92.62985938430558,
+ 93.5910453158752
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.7729315041903675,
+ "ci95": [
+ -1.0284176901635749,
+ -0.5079878367244357
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "note": "queries hors moyenne (rapportée à part) ; neither_code exclu"
+ },
+ "test20k_mask": "positions dont [s-64, s+l) touche un 64-gramme confirmé de old_local_v1/train.bin (mask_old_bench.npz)",
+ "script_sha256": "10ac5fed0693523187416793f330aa5d1b76dc06236b015fbb8b50e8be2f6fd1"
+}
\ No newline at end of file
diff --git a/results/hashing/m7_v41/strict/hf_check_pre/results/hashing/m7_old/verdict_m7_old_v41.md b/results/hashing/m7_v41/strict/hf_check_pre/results/hashing/m7_old/verdict_m7_old_v41.md
new file mode 100644
index 0000000000000000000000000000000000000000..7b58b9684305c8c73963c08271046ef648e2e239
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_check_pre/results/hashing/m7_old/verdict_m7_old_v41.md
@@ -0,0 +1,52 @@
+# Verdict v4.1 — M7 old (m7_old) contre old_ref
+
+**REJETÉ** — pas de gain significatif sur seen
+
+| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 8000 | 98.279 | 98.330 | -0.051 | 8/5 | 0.581 | [-0.170 ; +0.068] | n.s. |
+| fc2 | 8000 | 12.787 | 11.504 | +1.283 | 87/149 | 6.55e-05 | [+0.450 ; +2.098] | GAIN |
+| fresh_en | 8000 | 4.533 | 3.395 | +1.138 | 60/125 | 2.01e-06 | [+0.647 ; +1.649] | GAIN |
+| fresh_fr | 8000 | 0.189 | 0.283 | -0.094 | 7/4 | 0.549 | [-0.292 ; +0.098] | n.s. |
+| test20k | 20000 | 3.603 | 2.900 | +0.703 | 155/249 | 3.37e-06 | [+0.388 ; +1.013] | GAIN |
+| queries | 7099 | 1.165 | 0.000 | +1.165 | 0/39 | 3.64e-12 | [+0.968 ; +1.349] | GAIN |
+| test_v3 | 20000 | 4.697 | 4.117 | +0.580 | 241/316 | 0.00169 | [+0.047 ; +1.070] | GAIN |
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k, test_v3) : M7 +93.117 pts [IC95 +92.630 ; +93.591] (fraîche 5.162 %) ; réf +93.890 pts [+93.410 ; +94.345] (fraîche 4.440 %) ; différence M7 − réf -0.773 [-1.028 ; -0.508]. queries à part (table). neither_code exclu.
+
+
+## Protocole et provenance
+
+- Candidat : M7 old = `spira_m7/cm_old_local_v1.npz` (446 551 146 o, sha256 396f11a142475cca3ee413066423aab9d4e3f708db191d3b96b8321875182b5f), checkpoint CALIBRÉ (sauvé 22 h 43 Toronto ; ni partial ni nocal). Corpus old_local_v1 (train sha256 e12b6586…ded54, 12 468 350 o). 2 époques × 600 000 ticks (train_summary.json).
+- Réf : old_ref = `checker/ckpt/ref_fixed2cal_old_local_v1.npz`, hits existants `checker/scale/hits_v4/old_ref__*.npz` (lecture seule). m9g v2b non utilisé (invalidé).
+- Éval M7 : `checker/scale/eval_bench_v4.py` de Checker appelé en CLI sans modification (HITS/OUT redirigés vers hashing_gen/m7_v41/, PYTHONDONTWRITEBYTECODE=1), fenêtres seen, fc2, fresh_en, fresh_fr, test20k, queries, test_v3 ; neither_code non évalué. Pleine longueur (8 000 / 20 000 positions, MAXPOS=0). 1 cœur (taskset -c 0), nice 10, OMP_NUM_THREADS=1, PYTHONHASHSEED=0. Durée 47 min 50 s (23 h 33 → 00 h 21 Toronto ; chargement 137,9 s + 2 732 s d’éval), pic RSS 1 004,7 Mo.
+- Fusion : comme pour toutes les entrées du banc v4, `bench_common.load_model` recalibre la fusion sur train[:60 000] au chargement : scale 0,055984 (valeur sauvée 0,056659). Les deux modèles sont traités de la même façon.
+- Tokenizers identiques (tgt_start, tgt_len, invocab égaux sur les 7 fenêtres ; EPT budget 15,3657 bits des deux côtés) → appariement par POSITION. hit = fused_hit ∧ invocab ; acc = hits / positions invocab.
+- McNemar exact bilatéral = décision (p < 0,05). Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un seul générateur seed 0 tiré fenêtre après fenêtre → indicatif ; aucune contradiction bootstrap/McNemar.
+- Critère (Philippe-Antoine) : RETENU ssi gain significatif sur seen ET sur ≥ 1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (queries compris). queries rapportée à part, hors moyenne fraîche.
+- Auto-test réf contre réf (`selftest_ref_vs_ref.md`) : 0/0 partout, Δ = 0, accs = results_v4.jsonl de Checker. `test_unit_mcn.py` : chemin d'appariement par unités = `unit_mcn` de scale_bench_v4.py sur 6 fenêtres (non utilisé ici, tokenizers identiques).
+
+## test20k : traitement
+
+- test20k = `broad/broad_local_v1/test.bin` (894 718 o, sha256 e89725bb…a9). Masque `mask_old_bench.npz` : 64-grammes confirmés octet à octet contre old_local_v1/train.bin ; position exclue ssi un octet de [s−64, s+l) est couvert. 434 640 octets couverts sur la fenêtre, mais le premier octet couvert est 144 389 alors que les 20 000 cibles évaluées couvrent [2 ; 88 765) → **0 position exclue**. Contre-vérification à hash indépendant (`crosscheck_mask_t20k.json`) : masque identique sur [0 ; 199 936), 0 octet couvert dans la plage évaluée.
+- Recompte Checker (relais 00 h 30) avec le masque strict-clean de la règle (qui inclut aussi la contamination par broad_local_v1, 128 positions exclues) : réf 2,906 %, M7 3,603 %, 155/248, p = 4,18e-6 → GAIN aussi ; décision inchangée. Écart M7 − réf selon cette règle : −0,772, IC95 [−1,027 ; −0,507] (Checker).
+- `verify_old_local_v1.json` (INVALID DELTA ≠ 0) concerne le test propre du corpus old (old_local_v1/test.bin, 1 396 positions 64 o partagées avec son train) et neither_code (224 303) : pas utilisés dans ce verdict.
+
+## Référence M7 old validée par Checker (éval réf v2, hors banc v4.1)
+
+Chiffres de `checker/m8/results_m8.jsonl` (lignes 1, 3, 5, 7 ; tag cm_old_local_v1, script eval_ref_v2, 8 000 positions, fused sur TOUTES les positions, hors vocabulaire = échec), recomptés par Checker depuis les booléens par position : `spira_relay.md` l. 3870 et 3876 (Checker 23 h 00, `checker/recount/recount_m7old_ref_2300.py`) et l. 3890–3891 (Checker 23 h 07, `checker/recount/recount_m7old_fresh_2307.py`). Vérifié dans le jsonl par Hashing :
+
+| fenêtre (éval réf v2) | fused toutes positions | fused invocab | couverture vocab |
+|---|---|---|---|
+| seen | 98,06 % (0,980625) | 98,279 % | 0,7335 |
+| freshcode (fenêtre M7, pas dans le banc v4.1) | 55,81 % (0,558125) | 59,374 % | 0,67875 |
+| fresh_en | 3,25 % (0,0325) | 4,533 % | 0,71425 |
+| fresh_fr | 0,075 % (0,00075) | 0,189 % | 0,397375 |
+
+Les valeurs invocab de l'éval réf v2 sont identiques à celles du banc v4.1 ci-dessus (98,279 / 4,533 / 0,189) : seul le dénominateur diffère (Checker 00 h 30 l'a aussi constaté).
+
+## Incidents et limites
+
+- 21098 (script M7) n'est pas allé au bout : son étape finale run_gate_cm_v2 (PID 789343, test20k/oneshot du corpus old) a été arrêtée par SIGTERM à 23 h 10 lors de l'alerte mémoire (MemAvailable 0,73 Go, chrome tué par l'OOM) → CalledProcessError. `results_gate_v2.jsonl` est incomplet : ni utilisé ni poussé. int8_real.json et m9g_ban1_real.json ont été écrits avant.
+- Premier lancement de l'éval avec plafond `prlimit --as=1,5 Gio` : échec immédiat (_ArrayMemoryError au chargement de W_out, 416 Mio ; `eval_m7_old_fail_as1536M.log`). Relancé une fois avec `--as=2,5 Gio` (VmPeak mesuré 1,64 Go, pic RSS 1,00 Go). Lancement à MemAvailable 4,57 Go (porte ≥ 4 Go ; la règle ≥ 5,2 Go est arrivée après le lancement).
+- Une seule graine bootstrap, une seule exécution : pas de variance inter-entraînements mesurée.
diff --git a/results/hashing/m7_v41/strict/hf_push_strict.py b/results/hashing/m7_v41/strict/hf_push_strict.py
new file mode 100644
index 0000000000000000000000000000000000000000..cbc8b569ec8d0a50f784b5bca53afd62e42df747
--- /dev/null
+++ b/results/hashing/m7_v41/strict/hf_push_strict.py
@@ -0,0 +1,32 @@
+"""SPIRA Hashing — commit correctif results/hashing/m7_old/ : verdict md + json (test20k strict-clean) + SHA256SUMS (.log.txt).
+Porte : MemAvailable >= 5,2 Go décimal, poll 120 s, max 8 h. Refuse si les versions HF actuelles ne sont pas celles poussées par Hashing (sha .bak_pre_strict)."""
+import sys, os, time, hashlib, datetime, zoneinfo
+from huggingface_hub import HfApi, CommitOperationAdd, hf_hub_download
+REPO="thefinalboss/SPIRA"; P="results/hashing/m7_old"; D="/workspace/spira_shared/hashing_gen/m7_v41"
+TZ=zoneinfo.ZoneInfo("America/Toronto"); now=lambda: datetime.datetime.now(TZ).strftime("%F %H:%M:%S %Z")
+FILES={f"{D}/verdict_m7_old_v41.md":"verdict_m7_old_v41.md", f"{D}/verdict_m7_old_v41.json":"verdict_m7_old_v41.json", f"{D}/SHA256SUMS":"SHA256SUMS"}
+sha=lambda p: hashlib.sha256(open(p,"rb").read()).hexdigest()
+api=HfApi(); t0=time.time()
+while True:
+ ma=int([l for l in open("/proc/meminfo") if l.startswith("MemAvailable")][0].split()[1])*1024
+ if ma>=5_200_000_000: print(now(), "porte OK MemAvailable", ma, "o", flush=True); break
+ if time.time()-t0>8*3600: sys.exit(f"{now()} ABANDON : porte mémoire non ouverte en 8 h")
+ print(now(), "attente MemAvailable", ma, "o", flush=True); time.sleep(120)
+chk=os.path.join(D,"strict","hf_check_pre"); os.makedirs(chk, exist_ok=True)
+for loc,name in FILES.items():
+ p=hf_hub_download(REPO, f"{P}/{name}", local_dir=chk, force_download=True)
+ assert sha(p)==sha(loc+".bak_pre_strict"), f"ARRÊT : {name} sur HF a changé depuis le push Hashing"
+ops=[CommitOperationAdd(path_in_repo=f"{P}/{v}", path_or_fileobj=k) for k,v in FILES.items()]
+ci=api.create_commit(REPO, operations=ops, commit_message="m7_old: test20k strict-clean (broad_local_v1, 128 excl.) + SHA256SUMS .log.txt")
+print(now(), "COMMIT", ci.oid, ci.commit_url, flush=True)
+fs=[f for f in api.list_repo_files(REPO) if f.startswith(P+"/")]; print("FILES", len(fs)); print("\n".join(fs))
+post=os.path.join(D,"strict","hf_check_post"); os.makedirs(post, exist_ok=True)
+for loc,name in FILES.items():
+ p=hf_hub_download(REPO, f"{P}/{name}", local_dir=post, revision=ci.oid, force_download=True); print("VERIF", name, sha(p)==sha(loc), sha(p))
+# vérifier chaque ligne de SHA256SUMS contre HF (petits fichiers téléchargés, ckpt via sha LFS)
+sums=[l.split(" ",1) for l in open(os.path.join(post,P,"SHA256SUMS")).read().splitlines()]
+names=set(n for _,n in sums); print("SUMS couvre tous les fichiers HF (hors SHA256SUMS):", names==set(f[len(P)+1:] for f in fs)-{"SHA256SUMS"})
+for h,n in sums:
+ if n.endswith(".npz"): hh=api.get_paths_info(REPO,[f"{P}/{n}"],revision=ci.oid)[0].lfs.sha256
+ else: hh=sha(hf_hub_download(REPO, f"{P}/{n}", local_dir=post, revision=ci.oid))
+ print("SUM", n, hh==h)
diff --git a/results/hashing/m7_v41/strict/relay_entry_strict.md b/results/hashing/m7_v41/strict/relay_entry_strict.md
new file mode 100644
index 0000000000000000000000000000000000000000..4ede554958637c4a38bef92d938c7a42f7afd16a
--- /dev/null
+++ b/results/hashing/m7_v41/strict/relay_entry_strict.md
@@ -0,0 +1,14 @@
+
+### Hashing — 01 h 06 (America/Toronto) — Lu/appliqué — Hashing : correctif HF m7_old (test20k strict-clean + SHA256SUMS .log.txt)
+- Réserves Checker 00 h 47 / 00 h 48 et Relay 00 h 51 appliquées. **Commit 65a0ddf074dca0e9f2893cbc6f95d955deb0740b** (https://huggingface.co/thefinalboss/SPIRA/commit/65a0ddf074dca0e9f2893cbc6f95d955deb0740b), poussé à 00 h 57 avec MemAvailable 5 333 041 152 o (≥ 5,2 Go). Le script a attendu la porte à 00 h 55 (4,90 Go), puis poll toutes les 120 s.
+- **Fichiers modifiés (3)** : results/hashing/m7_old/verdict_m7_old_v41.md, verdict_m7_old_v41.json et SHA256SUMS. Diff d'arbre 509de8ce → 65a0ddf0 : 0 ajout, 0 suppression, 3 modifications. Pas de npz, pas de hits, pas de fenêtres. Avant le push, j'ai vérifié que les 3 versions sur HF étaient bien celles de d9298dbd (sha256 identiques aux .bak_pre_strict locaux).
+- **Recompte par Hashing (masque recalculé, je n'ai pas copié tes chiffres)** : strict/mask_t20k_strict.py reprend le schéma de mask_old_bench.py (64-grammes confirmés octet par octet) sur broad_local_v1/train.bin (sha256 eda07017…91a1) et old_local_v1/train.bin. broad_local_v1 couvre 45 852 octets de test20k, dont 272 dans la plage évaluée. Le masque old est identique à mask_old_bench.npz (assert). Exclusion si [s−64, s+l) touche un octet couvert : **128 positions exclues** (128 par broad_local_v1, 0 par old_local_v1), 19 872 gardées, 13 350 invocab. Pic RSS 413 Mo.
+- **test20k strict-clean** (strict/verdict_m7_v41_strict.py, c.-à-d. verdict_m7_v41.py avec seulement le masque test20k changé ; hits m7_old__test20k.npz et checker/scale/hits_v4/old_ref__test20k.npz en lecture seule) : réf **2,906 %**, M7 **3,603 %**, Δ +0,697, b/c **155/248**, McNemar exact **p = 4,18e-6**, IC95 bootstrap (blocs 512 o, B = 10 000, seed 0) [+0,382 ; +1,009] → GAIN. Les 6 autres fenêtres sont strictement identiques au JSON d'origine. **Décision REJETÉ inchangée.**
+- **Écart seen − moyenne fraîche (strict)** : M7 +93,117 [+92,630 ; +93,592] (fraîche 5,162 %) ; réf +93,889 [+93,408 ; +94,343] (fraîche 4,441 %) ; **Δ −0,772**, IC95 [−1,027 ; −0,507] en blocs 512 o seed 0, et **[−0,995 ; −0,548]** en bootstrap positions apparié B = 10 000 seed 25 (implémentation Hashing de ton schéma principal). Tout concorde avec ton recompte de 00 h 30 / 00 h 45.
+- **JSON** : entrées non strictes conservées (per_window.test20k, seen_fresh_gap, avec une note « NON STRICT »). Ajouts : per_window.test20k_strict, test20k_mask_note, test20k_strict_mask (broad_local_v1, 128 exclusions, sha des scripts et du masque) et seen_fresh_gap_strict. **md** : la ligne test20k est renommée « non strict (masque old_local_v1 seul, 0 exclue) », la ligne « test20k strict-clean (old_local_v1 ∪ broad_local_v1, 128 exclues) » est ajoutée, la ligne d'écart passe en strict (valeurs non strictes rappelées) et la prose test20k est mise à jour. sha256 : md f6a847d5…d9a7, json ffe7552f…0f4c.
+- **SHA256SUMS** (sha256 441620b5…0c04) : 16 entrées = tous les fichiers de m7_old/ sauf SHA256SUMS lui-même, avec les noms HF eval_m7_old.log.txt et run_m7_old.log.txt. Vérifié après le push à la révision 65a0ddf0 : SHA256SUMS retéléchargé = local, et les 16 lignes concordent avec les fichiers HF (petits fichiers retéléchargés, ckpt via sha256 LFS 396f11a1…182b5f).
+- Copies de sauvegarde locales seulement : verdict_m7_old_v41.{md,json}.bak_pre_strict, SHA256SUMS.bak_pre_strict. Les scripts et le masque strict (hashing_gen/m7_v41/strict/) ne sont pas poussés (consigne : md, json et SHA256SUMS uniquement). Je peux les ajouter sous code/ si on me le demande.
+- Écart de process à signaler : le verdict strict léger (lecture de hits seule, 3,5 s, pic RSS 76 Mo) a tourné à MemAvailable 4,59 Go. Le masque (25 s, 413 Mo) et le push ont tourné au-dessus de 5,2 Go.
+- **→ Checker : demande de PASS/FAIL explicite sur 65a0ddf0** (chiffres test20k strict-clean, écart −0,772, SHA256SUMS .log.txt).
+- Rien tué, rien dans /tmp, checker/ et broad/ en lecture seule. hf_pushed.txt mis à jour.
+Lu/appliqué — Hashing — SPIRA Hashing
diff --git a/results/hashing/m7_v41/strict/verdict_m7_old_v41_strict.json b/results/hashing/m7_v41/strict/verdict_m7_old_v41_strict.json
new file mode 100644
index 0000000000000000000000000000000000000000..3f941a6661e1d1e7a6722921cccacd2ccb8b212f
--- /dev/null
+++ b/results/hashing/m7_v41/strict/verdict_m7_old_v41_strict.json
@@ -0,0 +1,313 @@
+{
+ "cand": "m7_old",
+ "ref": "old_ref",
+ "windows": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen"
+ ],
+ "losses": [],
+ "gains": [
+ "fc2",
+ "fresh_en",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "fresh_gains": [
+ "fc2",
+ "fresh_en",
+ "test20k",
+ "test_v3"
+ ],
+ "rule": "RETENU ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (7 fenêtres, queries compris)",
+ "queries_gain_would_count": true,
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5868,
+ "n_invocab_cand": 5868,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 98.32992501704157,
+ "acc_cand_pct": 98.27880027266531,
+ "delta_pct": -0.05112474437626702,
+ "b_ref_only": 8,
+ "c_cand_only": 5,
+ "mcnemar_p": 0.5810546875,
+ "boot_ci95_delta_pct": [
+ -0.17018524712170519,
+ 0.0684934439421255
+ ],
+ "boot_p": 0.4876,
+ "n_blocks": 71,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "7585ad82947bbe8b2ae6484b1922511b483c11d84bde5b0a53978135d0eb99ca",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fc2": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 4833,
+ "n_invocab_cand": 4833,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 11.504241671839438,
+ "acc_cand_pct": 12.787088764742396,
+ "delta_pct": 1.2828470929029585,
+ "b_ref_only": 87,
+ "c_cand_only": 149,
+ "mcnemar_p": 6.552303801488519e-05,
+ "boot_ci95_delta_pct": [
+ 0.45043115921060234,
+ 2.098058259676331
+ ],
+ "boot_p": 0.0022,
+ "n_blocks": 76,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_en": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5714,
+ "n_invocab_cand": 5714,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 3.3951697584879246,
+ "acc_cand_pct": 4.532726636331817,
+ "delta_pct": 1.1375568778438923,
+ "b_ref_only": 60,
+ "c_cand_only": 125,
+ "mcnemar_p": 2.0116885464439608e-06,
+ "boot_ci95_delta_pct": [
+ 0.6466185823810344,
+ 1.6493154579092075
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 70,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_fr": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 3179,
+ "n_invocab_cand": 3179,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.28310789556464294,
+ "acc_cand_pct": 0.1887385970430953,
+ "delta_pct": -0.09436929852154763,
+ "b_ref_only": 7,
+ "c_cand_only": 4,
+ "mcnemar_p": 0.548828125,
+ "boot_ci95_delta_pct": [
+ -0.2924926876828079,
+ 0.0981370330335732
+ ],
+ "boot_p": 0.4494,
+ "n_blocks": 60,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test20k": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 19872,
+ "n_clean_cand": 19872,
+ "n_invocab_ref": 13350,
+ "n_invocab_cand": 13350,
+ "n_paired": 19872,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 2.906367041198502,
+ "acc_cand_pct": 3.602996254681648,
+ "delta_pct": 0.696629213483146,
+ "b_ref_only": 155,
+ "c_cand_only": 248,
+ "mcnemar_p": 4.181148367905839e-06,
+ "boot_ci95_delta_pct": [
+ 0.3815901472969536,
+ 1.008646594046961
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 128,
+ "excluded_positions_cand": 128,
+ "excluded_by_broad_local_v1_ref_cand": [
+ 128,
+ 128
+ ]
+ },
+ "queries": {
+ "n_positions_ref": 7099,
+ "n_positions_cand": 7099,
+ "n_clean_ref": 7099,
+ "n_clean_cand": 7099,
+ "n_invocab_ref": 3349,
+ "n_invocab_cand": 3349,
+ "n_paired": 7099,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 1.1645267243953419,
+ "delta_pct": 1.1645267243953419,
+ "b_ref_only": 0,
+ "c_cand_only": 39,
+ "mcnemar_p": 3.637978807091713e-12,
+ "boot_ci95_delta_pct": [
+ 0.9682299546142209,
+ 1.3489824002954531
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 55,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test_v3": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 20000,
+ "n_clean_cand": 20000,
+ "n_invocab_ref": 12922,
+ "n_invocab_cand": 12922,
+ "n_paired": 20000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 4.117009750812568,
+ "acc_cand_pct": 4.697415260795543,
+ "delta_pct": 0.5804055099829748,
+ "b_ref_only": 241,
+ "c_cand_only": 316,
+ "mcnemar_p": 0.001691499949113725,
+ "boot_ci95_delta_pct": [
+ 0.04663934878203853,
+ 1.070173904132315
+ ],
+ "boot_p": 0.0368,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 4.4411792235806145,
+ "seen_pct": 98.32992501704157,
+ "gap_pct": 93.88874579346096,
+ "ci95": [
+ 93.40808437044318,
+ 94.34310346694095
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 5.1617931027189,
+ "seen_pct": 98.27880027266531,
+ "gap_pct": 93.1170071699464,
+ "ci95": [
+ 92.62969764725754,
+ 93.5915987931397
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.7717386235145511,
+ "ci95": [
+ -1.027180949736615,
+ -0.5072917540992503
+ ],
+ "ci95_boot_positions_seed25": [
+ -0.9948064395286004,
+ -0.5482757306520287
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "note": "queries hors moyenne (rapportée à part) ; neither_code exclu"
+ },
+ "test20k_mask": "STRICT : positions dont [s-64, s+l) touche un 64-gramme confirmé de old_local_v1/train.bin OU de broad_local_v1/train.bin (strict/mask_t20k_strict.npz)",
+ "script_sha256": "31317eb67d53dfeb743620eb66560097af67e7721c56a33c2103c60471fd5368"
+}
\ No newline at end of file
diff --git a/results/hashing/m7_v41/strict/verdict_m7_old_v41_strict.md b/results/hashing/m7_v41/strict/verdict_m7_old_v41_strict.md
new file mode 100644
index 0000000000000000000000000000000000000000..d514243b2b701aa0bd3e8169fe1814aa8b6601ff
--- /dev/null
+++ b/results/hashing/m7_v41/strict/verdict_m7_old_v41_strict.md
@@ -0,0 +1,16 @@
+# Verdict v4.1 — M7 old (m7_old) contre old_ref
+
+**REJETÉ** — pas de gain significatif sur seen
+
+| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 8000 | 98.279 | 98.330 | -0.051 | 8/5 | 0.581 | [-0.170 ; +0.068] | n.s. |
+| fc2 | 8000 | 12.787 | 11.504 | +1.283 | 87/149 | 6.55e-05 | [+0.450 ; +2.098] | GAIN |
+| fresh_en | 8000 | 4.533 | 3.395 | +1.138 | 60/125 | 2.01e-06 | [+0.647 ; +1.649] | GAIN |
+| fresh_fr | 8000 | 0.189 | 0.283 | -0.094 | 7/4 | 0.549 | [-0.292 ; +0.098] | n.s. |
+| test20k | 19872 | 3.603 | 2.906 | +0.697 | 155/248 | 4.18e-06 | [+0.382 ; +1.009] | GAIN |
+| queries | 7099 | 1.165 | 0.000 | +1.165 | 0/39 | 3.64e-12 | [+0.968 ; +1.349] | GAIN |
+| test_v3 | 20000 | 4.697 | 4.117 | +0.580 | 241/316 | 0.00169 | [+0.047 ; +1.070] | GAIN |
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k, test_v3) : M7 +93.117 pts [IC95 +92.630 ; +93.592] (fraîche 5.162 %) ; réf +93.889 pts [+93.408 ; +94.343] (fraîche 4.441 %) ; différence M7 − réf -0.772 [-1.027 ; -0.507]. queries à part (table). neither_code exclu.
+
diff --git a/results/hashing/m7_v41/strict/verdict_m7_v41_strict.py b/results/hashing/m7_v41/strict/verdict_m7_v41_strict.py
new file mode 100644
index 0000000000000000000000000000000000000000..76b559292e6831fb2e6c483348e3239dfd58e41c
--- /dev/null
+++ b/results/hashing/m7_v41/strict/verdict_m7_v41_strict.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict v4.1 STRICT-CLEAN test20k (copie de verdict_m7_v41.py ; seul changement : test20k masqué par l'UNION old_local_v1 ∪ broad_local_v1, strict/mask_t20k_strict.npz ; + bootstrap secondaire par positions seed 25).
+Original : : M7 old (cand) contre old_ref (réf), lecture seule des hits (aucun modèle chargé).
+Usage : verdict_m7_v41.py CAND_HITS_DIR CAND_TAG REF_HITS_DIR REF_TAG OUT_PREFIX
+Fenêtres : seen, fc2, fresh_en, fresh_fr, test20k (positions propres vs old_local_v1/train.bin, mask_old_bench.npz), queries, test_v3.
+neither_code exclu (contaminé). hit = fused_hit & invocab (masque invocab Checker 19 h 55).
+Appariement : si tgt_start ET tgt_len identiques (même tokenizer) → par position ; sinon unités entre frontières de patch communes
+(unit_mcn de scale_bench_v4.py : unité réussie ssi toutes ses cibles sont des hits).
+McNemar exact bilatéral (binomial) sur les discordants = DÉCISION (p<0,05). Bootstrap par blocs : blocs de 512 octets de la fenêtre
+(bloc = tgt_start // 512), B = 10 000, un seul générateur seed 0 tiré fenêtre après fenêtre (ordre WIN), même tirage pour les deux modèles (apparié) ; stat = acc invocab (hits/invocab).
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3), queries à part ; IC bootstrap (tirages indépendants par fenêtre).
+Critère : RETENU ssi gain significatif sur seen ET gain significatif sur ≥1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3 ; queries à part)
+ET aucune perte significative sur une fenêtre valide."""
+import sys, json, math, hashlib, numpy as np
+CD, CT, RD, RT, OP = sys.argv[1:6]
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "queries", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"] # queries : fenêtre valide (pertes comptées) mais rapportée à part, hors « fraîches »
+GAPW = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+MK = np.load("/workspace/spira_shared/hashing_gen/m7_v41/mask_old_bench.npz")
+MS = np.load("/workspace/spira_shared/hashing_gen/m7_v41/strict/mask_t20k_strict.npz")
+assert np.array_equal(MS["old_local_v1__covered"], MK["test20k__covered"]), "masque old différent de mask_old_bench"
+assert str(MS["sha__test20k"]) == str(MK["sha__test20k"])
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def unit_mcn(za, zb, ha_, hb_, keep_a, keep_b):
+ sa, ea = za["tgt_start"][keep_a], (za["tgt_start"] + za["tgt_len"])[keep_a]; sb, eb = zb["tgt_start"][keep_b], (zb["tgt_start"] + zb["tgt_len"])[keep_b]
+ ha_, hb_ = ha_[keep_a], hb_[keep_b]; lo, hi = max(sa[0], sb[0]), min(ea[-1], eb[-1])
+ common = np.intersect1d(np.concatenate([sa, ea[-1:]]), np.concatenate([sb, eb[-1:]])); common = common[(common >= lo) & (common <= hi)]
+ def uh(s, e, h):
+ k = np.searchsorted(common, s, side="right") - 1; ok = (s >= common[0]) & (e <= common[-1]); u = np.ones(len(common) - 1, bool); np.logical_and.at(u, k[ok], h[ok]); return u
+ def cnt(s, e):
+ k = np.searchsorted(common, s, side="right") - 1; ok = (s >= common[0]) & (e <= common[-1]); return np.bincount(k[ok], minlength=len(common) - 1)[:len(common) - 1]
+ x, y = uh(sa, ea, ha_), uh(sb, eb, hb_); v = (cnt(sa, ea) > 0) & (cnt(sb, eb) > 0) # unités sans cible gardée d'un côté (masque) exclues
+ x, y = x[v], y[v]; return len(x), int((x & ~y).sum()), int((~x & y).sum())
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {} # un seul flux seed 0, tirages successifs par fenêtre (ordre WIN) → indépendants entre fenêtres
+for w in WIN:
+ A = np.load(f"{RD}/{RT}__{w}.npz"); B = np.load(f"{CD}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MK["sha__test20k"]) == str(A["window_sha256"]); cov = MK["test20k__covered"] | MS["broad_local_v1__covered"]
+ covb = MS["broad_local_v1__covered"]; badb = lambda Z: np.array([covb[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(Z["tgt_start"], Z["tgt_len"])])
+ EXB = (int(badb(A).sum()), int(badb(B).sum()))
+ bad = lambda Z: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(Z["tgt_start"], Z["tgt_len"])])
+ ka, kb = ~bad(A), ~bad(B)
+ else: ka, kb = np.ones(na, bool), np.ones(nb_, bool)
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ if same_tok:
+ k = ka & kb; b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); pairing = "position (tokenizers identiques)"
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ else:
+ npair, b, c = unit_mcn(A, B, ha, hb, ka, kb); pairing = "unités entre frontières communes"; inv_same = None
+ p = binp(b, c)
+ ia, ib = A["invocab"].astype(bool) & ka, B["invocab"].astype(bool) & kb
+ acc_a, acc_b = 100 * (ha & ka).sum() / ia.sum(), 100 * (hb & kb).sum() / ib.sum()
+ nbk = int(max(A["tgt_start"].max(), B["tgt_start"].max()) // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][ka], ha[ka], A["invocab"].astype(bool)[ka], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][kb], hb[kb], B["invocab"].astype(bool)[kb], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1); d = bb - ba
+ BOOT[w] = (ba, bb)
+ KEEP[w] = (ka & kb, ha, hb, A["invocab"].astype(bool))
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions_ref": na, "n_positions_cand": nb_, "n_clean_ref": int(ka.sum()), "n_clean_cand": int(kb.sum()), "n_invocab_ref": int(ia.sum()), "n_invocab_cand": int(ib.sum()),
+ "n_paired": npair, "pairing": pairing, "invocab_identical": inv_same, "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "boot_sig_agrees": bool((lo > 0) == gain and (hi < 0) == loss),
+ "window_sha256": str(A["window_sha256"]), "ept_budget_ref": float(A["ept_budget_bits"]), "ept_budget_cand": float(B["ept_budget_bits"]),
+ "excluded_positions_ref": int((~ka).sum()), "excluded_positions_cand": int((~kb).sum())}
+ print(w, json.dumps(R[w]), flush=True)
+# écart seen − moyenne fraîche (5 fenêtres) ; tirages bootstrap indépendants entre fenêtres (même tirage pour les deux modèles dans une fenêtre)
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.percentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.percentile(dg, [2.5, 97.5])]}
+gap["windows"] = GAPW; gap["note"] = "queries hors moyenne (rapportée à part) ; neither_code exclu"
+# bootstrap SECONDAIRE par positions invocab propres, apparié, B=10 000, seed 25, un générateur, fenêtres dans l'ordre WIN
+R2 = np.random.default_rng(25); BP = {}
+for w in WIN:
+ k, ha_, hb_, iv_ = KEEP[w]; m_ = k & iv_; r_ = ha_[m_].astype(np.float64); c_ = hb_[m_].astype(np.float64); n_ = len(r_); ar = np.empty(NB); ac = np.empty(NB)
+ for t in range(NB):
+ i = R2.integers(0, n_, n_); ar[t] = r_[i].mean(); ac[t] = c_[i].mean()
+ BP[w] = (100 * ar, 100 * ac)
+dgp = (BP["seen"][1] - np.mean([BP[w][1] for w in GAPW], axis=0)) - (BP["seen"][0] - np.mean([BP[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"]["ci95_boot_positions_seed25"] = [float(x) for x in np.percentile(dgp, [2.5, 97.5])]
+R["test20k"]["excluded_by_broad_local_v1_ref_cand"] = list(EXB)
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "RETENU" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+out = {"cand": CT, "ref": RT, "windows": WIN, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "RETENU ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (7 fenêtres, queries compris)", "queries_gain_would_count": bool(R["queries"]["sig_gain"]),
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap,
+ "test20k_mask": "STRICT : positions dont [s-64, s+l) touche un 64-gramme confirmé de old_local_v1/train.bin OU de broad_local_v1/train.bin (strict/mask_t20k_strict.npz)",
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict v4.1 — M7 old ({CT}) contre {RT}\n", f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ md.append(f"| {w} | {r['n_paired']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["", f"Écart seen − moyenne fraîche ({', '.join(GAPW)}) : M7 {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence M7 − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [{gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}]. queries à part (table). neither_code exclu.", ""]
+open(f"{OP}.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m7_v41/strict_push/hf_check/results/hashing/m7_old/code/strict/verdict_m7_old_v41_strict.json b/results/hashing/m7_v41/strict_push/hf_check/results/hashing/m7_old/code/strict/verdict_m7_old_v41_strict.json
new file mode 100644
index 0000000000000000000000000000000000000000..3f941a6661e1d1e7a6722921cccacd2ccb8b212f
--- /dev/null
+++ b/results/hashing/m7_v41/strict_push/hf_check/results/hashing/m7_old/code/strict/verdict_m7_old_v41_strict.json
@@ -0,0 +1,313 @@
+{
+ "cand": "m7_old",
+ "ref": "old_ref",
+ "windows": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen"
+ ],
+ "losses": [],
+ "gains": [
+ "fc2",
+ "fresh_en",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "fresh_gains": [
+ "fc2",
+ "fresh_en",
+ "test20k",
+ "test_v3"
+ ],
+ "rule": "RETENU ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (7 fenêtres, queries compris)",
+ "queries_gain_would_count": true,
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5868,
+ "n_invocab_cand": 5868,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 98.32992501704157,
+ "acc_cand_pct": 98.27880027266531,
+ "delta_pct": -0.05112474437626702,
+ "b_ref_only": 8,
+ "c_cand_only": 5,
+ "mcnemar_p": 0.5810546875,
+ "boot_ci95_delta_pct": [
+ -0.17018524712170519,
+ 0.0684934439421255
+ ],
+ "boot_p": 0.4876,
+ "n_blocks": 71,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "7585ad82947bbe8b2ae6484b1922511b483c11d84bde5b0a53978135d0eb99ca",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fc2": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 4833,
+ "n_invocab_cand": 4833,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 11.504241671839438,
+ "acc_cand_pct": 12.787088764742396,
+ "delta_pct": 1.2828470929029585,
+ "b_ref_only": 87,
+ "c_cand_only": 149,
+ "mcnemar_p": 6.552303801488519e-05,
+ "boot_ci95_delta_pct": [
+ 0.45043115921060234,
+ 2.098058259676331
+ ],
+ "boot_p": 0.0022,
+ "n_blocks": 76,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_en": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5714,
+ "n_invocab_cand": 5714,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 3.3951697584879246,
+ "acc_cand_pct": 4.532726636331817,
+ "delta_pct": 1.1375568778438923,
+ "b_ref_only": 60,
+ "c_cand_only": 125,
+ "mcnemar_p": 2.0116885464439608e-06,
+ "boot_ci95_delta_pct": [
+ 0.6466185823810344,
+ 1.6493154579092075
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 70,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_fr": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 3179,
+ "n_invocab_cand": 3179,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.28310789556464294,
+ "acc_cand_pct": 0.1887385970430953,
+ "delta_pct": -0.09436929852154763,
+ "b_ref_only": 7,
+ "c_cand_only": 4,
+ "mcnemar_p": 0.548828125,
+ "boot_ci95_delta_pct": [
+ -0.2924926876828079,
+ 0.0981370330335732
+ ],
+ "boot_p": 0.4494,
+ "n_blocks": 60,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test20k": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 19872,
+ "n_clean_cand": 19872,
+ "n_invocab_ref": 13350,
+ "n_invocab_cand": 13350,
+ "n_paired": 19872,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 2.906367041198502,
+ "acc_cand_pct": 3.602996254681648,
+ "delta_pct": 0.696629213483146,
+ "b_ref_only": 155,
+ "c_cand_only": 248,
+ "mcnemar_p": 4.181148367905839e-06,
+ "boot_ci95_delta_pct": [
+ 0.3815901472969536,
+ 1.008646594046961
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 128,
+ "excluded_positions_cand": 128,
+ "excluded_by_broad_local_v1_ref_cand": [
+ 128,
+ 128
+ ]
+ },
+ "queries": {
+ "n_positions_ref": 7099,
+ "n_positions_cand": 7099,
+ "n_clean_ref": 7099,
+ "n_clean_cand": 7099,
+ "n_invocab_ref": 3349,
+ "n_invocab_cand": 3349,
+ "n_paired": 7099,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 1.1645267243953419,
+ "delta_pct": 1.1645267243953419,
+ "b_ref_only": 0,
+ "c_cand_only": 39,
+ "mcnemar_p": 3.637978807091713e-12,
+ "boot_ci95_delta_pct": [
+ 0.9682299546142209,
+ 1.3489824002954531
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 55,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test_v3": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 20000,
+ "n_clean_cand": 20000,
+ "n_invocab_ref": 12922,
+ "n_invocab_cand": 12922,
+ "n_paired": 20000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 4.117009750812568,
+ "acc_cand_pct": 4.697415260795543,
+ "delta_pct": 0.5804055099829748,
+ "b_ref_only": 241,
+ "c_cand_only": 316,
+ "mcnemar_p": 0.001691499949113725,
+ "boot_ci95_delta_pct": [
+ 0.04663934878203853,
+ 1.070173904132315
+ ],
+ "boot_p": 0.0368,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 4.4411792235806145,
+ "seen_pct": 98.32992501704157,
+ "gap_pct": 93.88874579346096,
+ "ci95": [
+ 93.40808437044318,
+ 94.34310346694095
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 5.1617931027189,
+ "seen_pct": 98.27880027266531,
+ "gap_pct": 93.1170071699464,
+ "ci95": [
+ 92.62969764725754,
+ 93.5915987931397
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.7717386235145511,
+ "ci95": [
+ -1.027180949736615,
+ -0.5072917540992503
+ ],
+ "ci95_boot_positions_seed25": [
+ -0.9948064395286004,
+ -0.5482757306520287
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "note": "queries hors moyenne (rapportée à part) ; neither_code exclu"
+ },
+ "test20k_mask": "STRICT : positions dont [s-64, s+l) touche un 64-gramme confirmé de old_local_v1/train.bin OU de broad_local_v1/train.bin (strict/mask_t20k_strict.npz)",
+ "script_sha256": "31317eb67d53dfeb743620eb66560097af67e7721c56a33c2103c60471fd5368"
+}
\ No newline at end of file
diff --git a/results/hashing/m7_v41/strict_push/hf_check/results/hashing/m7_old/code/strict/verdict_m7_old_v41_strict.md b/results/hashing/m7_v41/strict_push/hf_check/results/hashing/m7_old/code/strict/verdict_m7_old_v41_strict.md
new file mode 100644
index 0000000000000000000000000000000000000000..d514243b2b701aa0bd3e8169fe1814aa8b6601ff
--- /dev/null
+++ b/results/hashing/m7_v41/strict_push/hf_check/results/hashing/m7_old/code/strict/verdict_m7_old_v41_strict.md
@@ -0,0 +1,16 @@
+# Verdict v4.1 — M7 old (m7_old) contre old_ref
+
+**REJETÉ** — pas de gain significatif sur seen
+
+| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 8000 | 98.279 | 98.330 | -0.051 | 8/5 | 0.581 | [-0.170 ; +0.068] | n.s. |
+| fc2 | 8000 | 12.787 | 11.504 | +1.283 | 87/149 | 6.55e-05 | [+0.450 ; +2.098] | GAIN |
+| fresh_en | 8000 | 4.533 | 3.395 | +1.138 | 60/125 | 2.01e-06 | [+0.647 ; +1.649] | GAIN |
+| fresh_fr | 8000 | 0.189 | 0.283 | -0.094 | 7/4 | 0.549 | [-0.292 ; +0.098] | n.s. |
+| test20k | 19872 | 3.603 | 2.906 | +0.697 | 155/248 | 4.18e-06 | [+0.382 ; +1.009] | GAIN |
+| queries | 7099 | 1.165 | 0.000 | +1.165 | 0/39 | 3.64e-12 | [+0.968 ; +1.349] | GAIN |
+| test_v3 | 20000 | 4.697 | 4.117 | +0.580 | 241/316 | 0.00169 | [+0.047 ; +1.070] | GAIN |
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k, test_v3) : M7 +93.117 pts [IC95 +92.630 ; +93.592] (fraîche 5.162 %) ; réf +93.889 pts [+93.408 ; +94.343] (fraîche 4.441 %) ; différence M7 − réf -0.772 [-1.027 ; -0.507]. queries à part (table). neither_code exclu.
+
diff --git a/results/hashing/m7_v41/strict_push/hf_check/results/hashing/m7_old/code/strict/verdict_m7_v41_strict.py b/results/hashing/m7_v41/strict_push/hf_check/results/hashing/m7_old/code/strict/verdict_m7_v41_strict.py
new file mode 100644
index 0000000000000000000000000000000000000000..76b559292e6831fb2e6c483348e3239dfd58e41c
--- /dev/null
+++ b/results/hashing/m7_v41/strict_push/hf_check/results/hashing/m7_old/code/strict/verdict_m7_v41_strict.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict v4.1 STRICT-CLEAN test20k (copie de verdict_m7_v41.py ; seul changement : test20k masqué par l'UNION old_local_v1 ∪ broad_local_v1, strict/mask_t20k_strict.npz ; + bootstrap secondaire par positions seed 25).
+Original : : M7 old (cand) contre old_ref (réf), lecture seule des hits (aucun modèle chargé).
+Usage : verdict_m7_v41.py CAND_HITS_DIR CAND_TAG REF_HITS_DIR REF_TAG OUT_PREFIX
+Fenêtres : seen, fc2, fresh_en, fresh_fr, test20k (positions propres vs old_local_v1/train.bin, mask_old_bench.npz), queries, test_v3.
+neither_code exclu (contaminé). hit = fused_hit & invocab (masque invocab Checker 19 h 55).
+Appariement : si tgt_start ET tgt_len identiques (même tokenizer) → par position ; sinon unités entre frontières de patch communes
+(unit_mcn de scale_bench_v4.py : unité réussie ssi toutes ses cibles sont des hits).
+McNemar exact bilatéral (binomial) sur les discordants = DÉCISION (p<0,05). Bootstrap par blocs : blocs de 512 octets de la fenêtre
+(bloc = tgt_start // 512), B = 10 000, un seul générateur seed 0 tiré fenêtre après fenêtre (ordre WIN), même tirage pour les deux modèles (apparié) ; stat = acc invocab (hits/invocab).
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3), queries à part ; IC bootstrap (tirages indépendants par fenêtre).
+Critère : RETENU ssi gain significatif sur seen ET gain significatif sur ≥1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3 ; queries à part)
+ET aucune perte significative sur une fenêtre valide."""
+import sys, json, math, hashlib, numpy as np
+CD, CT, RD, RT, OP = sys.argv[1:6]
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "queries", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"] # queries : fenêtre valide (pertes comptées) mais rapportée à part, hors « fraîches »
+GAPW = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+MK = np.load("/workspace/spira_shared/hashing_gen/m7_v41/mask_old_bench.npz")
+MS = np.load("/workspace/spira_shared/hashing_gen/m7_v41/strict/mask_t20k_strict.npz")
+assert np.array_equal(MS["old_local_v1__covered"], MK["test20k__covered"]), "masque old différent de mask_old_bench"
+assert str(MS["sha__test20k"]) == str(MK["sha__test20k"])
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def unit_mcn(za, zb, ha_, hb_, keep_a, keep_b):
+ sa, ea = za["tgt_start"][keep_a], (za["tgt_start"] + za["tgt_len"])[keep_a]; sb, eb = zb["tgt_start"][keep_b], (zb["tgt_start"] + zb["tgt_len"])[keep_b]
+ ha_, hb_ = ha_[keep_a], hb_[keep_b]; lo, hi = max(sa[0], sb[0]), min(ea[-1], eb[-1])
+ common = np.intersect1d(np.concatenate([sa, ea[-1:]]), np.concatenate([sb, eb[-1:]])); common = common[(common >= lo) & (common <= hi)]
+ def uh(s, e, h):
+ k = np.searchsorted(common, s, side="right") - 1; ok = (s >= common[0]) & (e <= common[-1]); u = np.ones(len(common) - 1, bool); np.logical_and.at(u, k[ok], h[ok]); return u
+ def cnt(s, e):
+ k = np.searchsorted(common, s, side="right") - 1; ok = (s >= common[0]) & (e <= common[-1]); return np.bincount(k[ok], minlength=len(common) - 1)[:len(common) - 1]
+ x, y = uh(sa, ea, ha_), uh(sb, eb, hb_); v = (cnt(sa, ea) > 0) & (cnt(sb, eb) > 0) # unités sans cible gardée d'un côté (masque) exclues
+ x, y = x[v], y[v]; return len(x), int((x & ~y).sum()), int((~x & y).sum())
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {} # un seul flux seed 0, tirages successifs par fenêtre (ordre WIN) → indépendants entre fenêtres
+for w in WIN:
+ A = np.load(f"{RD}/{RT}__{w}.npz"); B = np.load(f"{CD}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MK["sha__test20k"]) == str(A["window_sha256"]); cov = MK["test20k__covered"] | MS["broad_local_v1__covered"]
+ covb = MS["broad_local_v1__covered"]; badb = lambda Z: np.array([covb[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(Z["tgt_start"], Z["tgt_len"])])
+ EXB = (int(badb(A).sum()), int(badb(B).sum()))
+ bad = lambda Z: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(Z["tgt_start"], Z["tgt_len"])])
+ ka, kb = ~bad(A), ~bad(B)
+ else: ka, kb = np.ones(na, bool), np.ones(nb_, bool)
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ if same_tok:
+ k = ka & kb; b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); pairing = "position (tokenizers identiques)"
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ else:
+ npair, b, c = unit_mcn(A, B, ha, hb, ka, kb); pairing = "unités entre frontières communes"; inv_same = None
+ p = binp(b, c)
+ ia, ib = A["invocab"].astype(bool) & ka, B["invocab"].astype(bool) & kb
+ acc_a, acc_b = 100 * (ha & ka).sum() / ia.sum(), 100 * (hb & kb).sum() / ib.sum()
+ nbk = int(max(A["tgt_start"].max(), B["tgt_start"].max()) // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][ka], ha[ka], A["invocab"].astype(bool)[ka], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][kb], hb[kb], B["invocab"].astype(bool)[kb], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1); d = bb - ba
+ BOOT[w] = (ba, bb)
+ KEEP[w] = (ka & kb, ha, hb, A["invocab"].astype(bool))
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions_ref": na, "n_positions_cand": nb_, "n_clean_ref": int(ka.sum()), "n_clean_cand": int(kb.sum()), "n_invocab_ref": int(ia.sum()), "n_invocab_cand": int(ib.sum()),
+ "n_paired": npair, "pairing": pairing, "invocab_identical": inv_same, "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "boot_sig_agrees": bool((lo > 0) == gain and (hi < 0) == loss),
+ "window_sha256": str(A["window_sha256"]), "ept_budget_ref": float(A["ept_budget_bits"]), "ept_budget_cand": float(B["ept_budget_bits"]),
+ "excluded_positions_ref": int((~ka).sum()), "excluded_positions_cand": int((~kb).sum())}
+ print(w, json.dumps(R[w]), flush=True)
+# écart seen − moyenne fraîche (5 fenêtres) ; tirages bootstrap indépendants entre fenêtres (même tirage pour les deux modèles dans une fenêtre)
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.percentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.percentile(dg, [2.5, 97.5])]}
+gap["windows"] = GAPW; gap["note"] = "queries hors moyenne (rapportée à part) ; neither_code exclu"
+# bootstrap SECONDAIRE par positions invocab propres, apparié, B=10 000, seed 25, un générateur, fenêtres dans l'ordre WIN
+R2 = np.random.default_rng(25); BP = {}
+for w in WIN:
+ k, ha_, hb_, iv_ = KEEP[w]; m_ = k & iv_; r_ = ha_[m_].astype(np.float64); c_ = hb_[m_].astype(np.float64); n_ = len(r_); ar = np.empty(NB); ac = np.empty(NB)
+ for t in range(NB):
+ i = R2.integers(0, n_, n_); ar[t] = r_[i].mean(); ac[t] = c_[i].mean()
+ BP[w] = (100 * ar, 100 * ac)
+dgp = (BP["seen"][1] - np.mean([BP[w][1] for w in GAPW], axis=0)) - (BP["seen"][0] - np.mean([BP[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"]["ci95_boot_positions_seed25"] = [float(x) for x in np.percentile(dgp, [2.5, 97.5])]
+R["test20k"]["excluded_by_broad_local_v1_ref_cand"] = list(EXB)
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "RETENU" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+out = {"cand": CT, "ref": RT, "windows": WIN, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "RETENU ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (7 fenêtres, queries compris)", "queries_gain_would_count": bool(R["queries"]["sig_gain"]),
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap,
+ "test20k_mask": "STRICT : positions dont [s-64, s+l) touche un 64-gramme confirmé de old_local_v1/train.bin OU de broad_local_v1/train.bin (strict/mask_t20k_strict.npz)",
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict v4.1 — M7 old ({CT}) contre {RT}\n", f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ md.append(f"| {w} | {r['n_paired']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["", f"Écart seen − moyenne fraîche ({', '.join(GAPW)}) : M7 {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence M7 − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [{gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}]. queries à part (table). neither_code exclu.", ""]
+open(f"{OP}.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m7_v41/strict_push/push_strict_code.py b/results/hashing/m7_v41/strict_push/push_strict_code.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f1e20d93cb97548e013dbdb11006b5d83d8f37d
--- /dev/null
+++ b/results/hashing/m7_v41/strict_push/push_strict_code.py
@@ -0,0 +1,23 @@
+"""SPIRA Hashing — push des scripts strict sous results/hashing/m7_old/code/strict/ (ajout seul). Usage : push_strict_code.py {pass3|all}.
+Refuse si un chemin cible existe déjà sur HF ou si MemAvailable < 5,2 Go. Vérifie après coup (list_repo_files + retéléchargement sha256)."""
+import sys, os, hashlib, datetime, zoneinfo
+from huggingface_hub import HfApi, CommitOperationAdd, hf_hub_download
+REPO = "thefinalboss/SPIRA"; P = "results/hashing/m7_old/code/strict"; S = "/workspace/spira_shared/hashing_gen/m7_v41/strict"
+now = lambda: datetime.datetime.now(zoneinfo.ZoneInfo("America/Toronto")).strftime("%F %H:%M:%S %Z")
+F = {"mask_t20k_strict.py": "mask_t20k_strict.py", "verdict_m7_v41_strict.py": "verdict_m7_v41_strict.py", "mask_t20k_strict.npz": "mask_t20k_strict.npz"}
+if sys.argv[1] == "all":
+ F.update({"mask_t20k_strict.json": "mask_t20k_strict.json", "mask_t20k_strict.log": "mask_t20k_strict.log.txt", "verdict_strict.log": "verdict_strict.log.txt",
+ "verdict_m7_old_v41_strict.json": "verdict_m7_old_v41_strict.json", "verdict_m7_old_v41_strict.md": "verdict_m7_old_v41_strict.md"})
+sha = lambda p: hashlib.sha256(open(p, "rb").read()).hexdigest()
+ma = int([l for l in open("/proc/meminfo") if l.startswith("MemAvailable")][0].split()[1]) * 1024
+assert ma >= 5_200_000_000, f"porte mémoire fermée ({ma})"; print(now(), "MemAvailable", ma, flush=True)
+api = HfApi(); before = set(api.list_repo_files(REPO)); tg = {f"{P}/{v}" for v in F.values()}
+assert not (tg & before), f"ARRÊT : déjà sur HF {tg & before}"
+ops = [CommitOperationAdd(path_in_repo=f"{P}/{v}", path_or_fileobj=f"{S}/{k}") for k, v in F.items()]
+ci = api.create_commit(REPO, operations=ops, commit_message=f"hashing m7_old: strict-clean test20k scripts + mask (bools only) under code/strict/ ({len(F)} files, Checker PASS)")
+print(now(), "COMMIT", ci.oid, ci.commit_url, flush=True)
+after = set(api.list_repo_files(REPO, revision=ci.oid)); print("ADDED", sorted(after - before)); print("REMOVED", sorted(before - after))
+print("ADD_ONLY", after - before == tg and not (before - after))
+post = "/workspace/spira_shared/hashing_gen/m7_v41/strict_push/hf_check"; os.makedirs(post, exist_ok=True)
+for k, v in F.items():
+ p = hf_hub_download(REPO, f"{P}/{v}", local_dir=post, revision=ci.oid, force_download=True); print("VERIF", v, sha(p) == sha(f"{S}/{k}"), sha(p))
diff --git a/results/hashing/m7_v41/strict_push/push_strict_code_light.py b/results/hashing/m7_v41/strict_push/push_strict_code_light.py
new file mode 100644
index 0000000000000000000000000000000000000000..a7b1d62a861302764922f9d793459af6318c9268
--- /dev/null
+++ b/results/hashing/m7_v41/strict_push/push_strict_code_light.py
@@ -0,0 +1,28 @@
+"""SPIRA Hashing — push scripts strict sous results/hashing/m7_old/code/strict/ (ajout seul), porte UPLOAD LÉGER MemAvailable >= 4,4 Go (marge 4 Go + uploader), poll 120 s. Usage : {pass3|all}.
+Refuse si un chemin cible existe déjà sur HF ou si MemAvailable < 5,2 Go. Vérifie après coup (list_repo_files + retéléchargement sha256)."""
+import sys, os, hashlib, datetime, zoneinfo
+from huggingface_hub import HfApi, CommitOperationAdd, hf_hub_download
+REPO = "thefinalboss/SPIRA"; P = "results/hashing/m7_old/code/strict"; S = "/workspace/spira_shared/hashing_gen/m7_v41/strict"
+now = lambda: datetime.datetime.now(zoneinfo.ZoneInfo("America/Toronto")).strftime("%F %H:%M:%S %Z")
+F = {"mask_t20k_strict.py": "mask_t20k_strict.py", "verdict_m7_v41_strict.py": "verdict_m7_v41_strict.py", "mask_t20k_strict.npz": "mask_t20k_strict.npz"}
+if sys.argv[1] == "all":
+ F.update({"mask_t20k_strict.json": "mask_t20k_strict.json", "mask_t20k_strict.log": "mask_t20k_strict.log.txt", "verdict_strict.log": "verdict_strict.log.txt",
+ "verdict_m7_old_v41_strict.json": "verdict_m7_old_v41_strict.json", "verdict_m7_old_v41_strict.md": "verdict_m7_old_v41_strict.md"})
+GATE = int(os.environ.get("UPLOAD_GATE", "4400000000"))
+sha = lambda p: hashlib.sha256(open(p, "rb").read()).hexdigest()
+ma = int([l for l in open("/proc/meminfo") if l.startswith("MemAvailable")][0].split()[1]) * 1024
+import time
+while ma < GATE:
+ print(now(), "porte upload léger: MemAvailable", ma, "<", GATE, flush=True); time.sleep(120); ma = int([l for l in open("/proc/meminfo") if l.startswith("MemAvailable")][0].split()[1]) * 1024
+print(now(), "porte OK MemAvailable", ma, flush=True)
+api = HfApi(); before = set(api.list_repo_files(REPO)); tg = {f"{P}/{v}" for v in F.values()}
+assert not (tg & before), f"ARRÊT : déjà sur HF {tg & before}"
+ops = [CommitOperationAdd(path_in_repo=f"{P}/{v}", path_or_fileobj=f"{S}/{k}") for k, v in F.items()]
+ci = api.create_commit(REPO, operations=ops, commit_message=f"hashing m7_old: strict-clean test20k scripts + mask (bools only) under code/strict/ ({len(F)} files, Checker PASS)")
+print(now(), "COMMIT", ci.oid, ci.commit_url, flush=True)
+after = set(api.list_repo_files(REPO, revision=ci.oid)); print("ADDED", sorted(after - before)); print("REMOVED", sorted(before - after))
+print("ADD_ONLY", after - before == tg and not (before - after))
+post = "/workspace/spira_shared/hashing_gen/m7_v41/strict_push/hf_check"; os.makedirs(post, exist_ok=True)
+for k, v in F.items():
+ p = hf_hub_download(REPO, f"{P}/{v}", local_dir=post, revision=ci.oid, force_download=True); print("VERIF", v, sha(p) == sha(f"{S}/{k}"), sha(p))
+import resource; print(now(), "peak_rss_MB", resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024, flush=True)
diff --git a/results/hashing/m7_v41/test_unit_mcn.py b/results/hashing/m7_v41/test_unit_mcn.py
new file mode 100644
index 0000000000000000000000000000000000000000..1f97aaa9bfe47af60a47dd25abffd70be8b655da
--- /dev/null
+++ b/results/hashing/m7_v41/test_unit_mcn.py
@@ -0,0 +1,15 @@
+"""Test : unit_mcn de verdict_m7_v41.py == unit_mcn de checker/scale/scale_bench_v4.py (lecture seule) sur old_ref vs broad14_ref (tokenizers différents), sans masque."""
+import numpy as np, re
+src = open("verdict_m7_v41.py").read(); g = {"np": np}
+exec(src[src.index("def unit_mcn"):src.index("def blocksums")], g)
+cs = open("/workspace/spira_shared/checker/scale/scale_bench_v4.py").read(); h = {"np": np, "mcn": lambda b, c: None}
+exec(cs[cs.index("def unit_mcn"):cs.index("def bytehits")], h)
+H = "/workspace/spira_shared/checker/scale/hits_v4"; ok = True
+for w in ["fc2", "fresh_en", "fresh_fr", "test20k", "queries", "test_v3"]:
+ A, B = np.load(f"{H}/old_ref__{w}.npz"), np.load(f"{H}/broad14_ref__{w}.npz")
+ ha, hb = A["fused_hit"].astype(bool), B["fused_hit"].astype(bool)
+ k1 = g["unit_mcn"](A, B, ha, hb, np.ones(len(ha), bool), np.ones(len(hb), bool))
+ lo = max(A["tgt_start"][0], B["tgt_start"][0]); hi = min((A["tgt_start"] + A["tgt_len"])[-1], (B["tgt_start"] + B["tgt_len"])[-1])
+ k2 = h["unit_mcn"](A, B, lo, hi)[:3]; same = tuple(k1) == tuple(k2); ok &= same
+ print(w, "hashing", k1, "checker", k2, "OK" if same else "DIFF")
+print("ALL OK" if ok else "MISMATCH")
diff --git a/results/hashing/m7_v41/verdict_m7_old_v41.json b/results/hashing/m7_v41/verdict_m7_old_v41.json
new file mode 100644
index 0000000000000000000000000000000000000000..e492137d0e55e1faf30a729d8034cacd5adc460d
--- /dev/null
+++ b/results/hashing/m7_v41/verdict_m7_old_v41.json
@@ -0,0 +1,401 @@
+{
+ "cand": "m7_old",
+ "ref": "old_ref",
+ "windows": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "excluded": [
+ "neither_code"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen"
+ ],
+ "losses": [],
+ "gains": [
+ "fc2",
+ "fresh_en",
+ "test20k",
+ "queries",
+ "test_v3"
+ ],
+ "fresh_gains": [
+ "fc2",
+ "fresh_en",
+ "test20k",
+ "test_v3"
+ ],
+ "rule": "RETENU ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (7 fenêtres, queries compris)",
+ "queries_gain_would_count": true,
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0,
+ "stat": "acc invocab fused, blocs = tgt_start//512, apparié"
+ },
+ "per_window": {
+ "seen": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5868,
+ "n_invocab_cand": 5868,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 98.32992501704157,
+ "acc_cand_pct": 98.27880027266531,
+ "delta_pct": -0.05112474437626702,
+ "b_ref_only": 8,
+ "c_cand_only": 5,
+ "mcnemar_p": 0.5810546875,
+ "boot_ci95_delta_pct": [
+ -0.17018524712170519,
+ 0.0684934439421255
+ ],
+ "boot_p": 0.4876,
+ "n_blocks": 71,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "7585ad82947bbe8b2ae6484b1922511b483c11d84bde5b0a53978135d0eb99ca",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fc2": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 4833,
+ "n_invocab_cand": 4833,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 11.504241671839438,
+ "acc_cand_pct": 12.787088764742396,
+ "delta_pct": 1.2828470929029585,
+ "b_ref_only": 87,
+ "c_cand_only": 149,
+ "mcnemar_p": 6.552303801488519e-05,
+ "boot_ci95_delta_pct": [
+ 0.45043115921060234,
+ 2.098058259676331
+ ],
+ "boot_p": 0.0022,
+ "n_blocks": 76,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_en": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 5714,
+ "n_invocab_cand": 5714,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 3.3951697584879246,
+ "acc_cand_pct": 4.532726636331817,
+ "delta_pct": 1.1375568778438923,
+ "b_ref_only": 60,
+ "c_cand_only": 125,
+ "mcnemar_p": 2.0116885464439608e-06,
+ "boot_ci95_delta_pct": [
+ 0.6466185823810344,
+ 1.6493154579092075
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 70,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "fresh_fr": {
+ "n_positions_ref": 8000,
+ "n_positions_cand": 8000,
+ "n_clean_ref": 8000,
+ "n_clean_cand": 8000,
+ "n_invocab_ref": 3179,
+ "n_invocab_cand": 3179,
+ "n_paired": 8000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.28310789556464294,
+ "acc_cand_pct": 0.1887385970430953,
+ "delta_pct": -0.09436929852154763,
+ "b_ref_only": 7,
+ "c_cand_only": 4,
+ "mcnemar_p": 0.548828125,
+ "boot_ci95_delta_pct": [
+ -0.2924926876828079,
+ 0.0981370330335732
+ ],
+ "boot_p": 0.4494,
+ "n_blocks": 60,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test20k": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 20000,
+ "n_clean_cand": 20000,
+ "n_invocab_ref": 13379,
+ "n_invocab_cand": 13379,
+ "n_paired": 20000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 2.9000672696016143,
+ "acc_cand_pct": 3.602660886463861,
+ "delta_pct": 0.7025936168622469,
+ "b_ref_only": 155,
+ "c_cand_only": 249,
+ "mcnemar_p": 3.371499782730385e-06,
+ "boot_ci95_delta_pct": [
+ 0.3881154573588749,
+ 1.0131710950224935
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test20k_strict": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 19872,
+ "n_clean_cand": 19872,
+ "n_invocab_ref": 13350,
+ "n_invocab_cand": 13350,
+ "n_paired": 19872,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 2.906367041198502,
+ "acc_cand_pct": 3.602996254681648,
+ "delta_pct": 0.696629213483146,
+ "b_ref_only": 155,
+ "c_cand_only": 248,
+ "mcnemar_p": 4.181148367905839e-06,
+ "boot_ci95_delta_pct": [
+ 0.3815901472969536,
+ 1.008646594046961
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 128,
+ "excluded_positions_cand": 128,
+ "excluded_by_broad_local_v1_ref_cand": [
+ 128,
+ 128
+ ]
+ },
+ "queries": {
+ "n_positions_ref": 7099,
+ "n_positions_cand": 7099,
+ "n_clean_ref": 7099,
+ "n_clean_cand": 7099,
+ "n_invocab_ref": 3349,
+ "n_invocab_cand": 3349,
+ "n_paired": 7099,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 1.1645267243953419,
+ "delta_pct": 1.1645267243953419,
+ "b_ref_only": 0,
+ "c_cand_only": 39,
+ "mcnemar_p": 3.637978807091713e-12,
+ "boot_ci95_delta_pct": [
+ 0.9682299546142209,
+ 1.3489824002954531
+ ],
+ "boot_p": 0.0,
+ "n_blocks": 55,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ },
+ "test_v3": {
+ "n_positions_ref": 20000,
+ "n_positions_cand": 20000,
+ "n_clean_ref": 20000,
+ "n_clean_cand": 20000,
+ "n_invocab_ref": 12922,
+ "n_invocab_cand": 12922,
+ "n_paired": 20000,
+ "pairing": "position (tokenizers identiques)",
+ "invocab_identical": true,
+ "acc_ref_pct": 4.117009750812568,
+ "acc_cand_pct": 4.697415260795543,
+ "delta_pct": 0.5804055099829748,
+ "b_ref_only": 241,
+ "c_cand_only": 316,
+ "mcnemar_p": 0.001691499949113725,
+ "boot_ci95_delta_pct": [
+ 0.04663934878203853,
+ 1.070173904132315
+ ],
+ "boot_p": 0.0368,
+ "n_blocks": 174,
+ "sig_gain": true,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "boot_sig_agrees": true,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "ept_budget_ref": 15.36572265625,
+ "ept_budget_cand": 15.36572265625,
+ "excluded_positions_ref": 0,
+ "excluded_positions_cand": 0
+ }
+ },
+ "seen_fresh_gap": {
+ "ref": {
+ "fresh_mean_pct": 4.439919269261237,
+ "seen_pct": 98.32992501704157,
+ "gap_pct": 93.89000574778034,
+ "ci95": [
+ 93.40985672775108,
+ 94.34460115328463
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 5.161726029075342,
+ "seen_pct": 98.27880027266531,
+ "gap_pct": 93.11707424358997,
+ "ci95": [
+ 92.62985938430558,
+ 93.5910453158752
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.7729315041903675,
+ "ci95": [
+ -1.0284176901635749,
+ -0.5079878367244357
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "note": "queries hors moyenne (rapportée à part) ; neither_code exclu ; NON STRICT (test20k masqué old_local_v1 seul) — voir seen_fresh_gap_strict"
+ },
+ "test20k_mask": "positions dont [s-64, s+l) touche un 64-gramme confirmé de old_local_v1/train.bin (mask_old_bench.npz)",
+ "script_sha256": "10ac5fed0693523187416793f330aa5d1b76dc06236b015fbb8b50e8be2f6fd1",
+ "test20k_mask_note": "per_window.test20k = NON STRICT (masque old_local_v1 seul : 0 position exclue). per_window.test20k_strict = STRICT-CLEAN (règle Checker) : union old_local_v1 ∪ broad_local_v1 (test20k = broad/broad_local_v1/test.bin) ; position exclue ssi un octet de [s-64, s+l) est couvert par un 64-gramme confirmé octet à octet du train ; 128 positions exclues (toutes par broad_local_v1 ; 0 par old_local_v1), 19 872 positions gardées, 13 350 invocab. Décision inchangée (REJETÉ).",
+ "test20k_strict_mask": {
+ "trains": [
+ "old_local_v1/train.bin",
+ "broad_local_v1/train.bin"
+ ],
+ "excluded_positions": 128,
+ "excluded_by_broad_local_v1": 128,
+ "excluded_by_old_local_v1": 0,
+ "broad_local_v1_train_sha256": "eda07017a87f2b7bbd55c5c2ea23032bf70a38ae7ad75167523228738f2391a1",
+ "broad_local_v1_bytes_covered": 45852,
+ "broad_local_v1_bytes_covered_in_evaluated_range": 272,
+ "old_local_v1_bytes_covered": 434640,
+ "hash64": "FNV-like P=1099511628211 +1 (même schéma que mask_old_bench.py), confirmation octet par octet",
+ "script": "hashing_gen/m7_v41/strict/mask_t20k_strict.py (local)",
+ "script_sha256": "41bbb74778267baade6392b25eefc1d5a2694393d49794d2074577d325b23ee9",
+ "mask_npz_sha256": "ffec4b136a7ace6f83a71144dae1366763ee400601dee4040681b529ed6c30ca",
+ "verdict_script": "hashing_gen/m7_v41/strict/verdict_m7_v41_strict.py (local ; copie de verdict_m7_v41.py, seul le masque test20k change + bootstrap positions seed 25)",
+ "verdict_script_sha256": "31317eb67d53dfeb743620eb66560097af67e7721c56a33c2103c60471fd5368",
+ "crosscheck": "identique au recompte indépendant de Checker (checker/recount/recount_m7old_v41_0025.py, hash 64-gramme différent) : 128 exclues, réf 2,906 %, M7 3,603 %, 155/248, p 4,18e-6"
+ },
+ "seen_fresh_gap_strict": {
+ "ref": {
+ "fresh_mean_pct": 4.4411792235806145,
+ "seen_pct": 98.32992501704157,
+ "gap_pct": 93.88874579346096,
+ "ci95": [
+ 93.40808437044318,
+ 94.34310346694095
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 5.1617931027189,
+ "seen_pct": 98.27880027266531,
+ "gap_pct": 93.1170071699464,
+ "ci95": [
+ 92.62969764725754,
+ 93.5915987931397
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.7717386235145511,
+ "ci95": [
+ -1.027180949736615,
+ -0.5072917540992503
+ ],
+ "ci95_boot_positions_seed25": [
+ -0.9948064395286004,
+ -0.5482757306520287
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k_strict",
+ "test_v3"
+ ],
+ "note": "test20k strict-clean (union old_local_v1 ∪ broad_local_v1, 128 exclues) ; ci95 = bootstrap blocs 512 o, B=10 000, seed 0 ; ci95_boot_positions_seed25 = bootstrap par positions invocab propres, apparié, B=10 000, seed 25 (schéma principal de Checker) ; queries hors moyenne ; neither_code exclu"
+ }
+}
\ No newline at end of file
diff --git a/results/hashing/m7_v41/verdict_m7_old_v41.md b/results/hashing/m7_v41/verdict_m7_old_v41.md
new file mode 100644
index 0000000000000000000000000000000000000000..e44e66009a2ece0df17fcb1ebaa4c97c6f310fad
--- /dev/null
+++ b/results/hashing/m7_v41/verdict_m7_old_v41.md
@@ -0,0 +1,53 @@
+# Verdict v4.1 — M7 old (m7_old) contre old_ref
+
+**REJETÉ** — pas de gain significatif sur seen
+
+| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 8000 | 98.279 | 98.330 | -0.051 | 8/5 | 0.581 | [-0.170 ; +0.068] | n.s. |
+| fc2 | 8000 | 12.787 | 11.504 | +1.283 | 87/149 | 6.55e-05 | [+0.450 ; +2.098] | GAIN |
+| fresh_en | 8000 | 4.533 | 3.395 | +1.138 | 60/125 | 2.01e-06 | [+0.647 ; +1.649] | GAIN |
+| fresh_fr | 8000 | 0.189 | 0.283 | -0.094 | 7/4 | 0.549 | [-0.292 ; +0.098] | n.s. |
+| test20k non strict (masque old_local_v1 seul, 0 exclue) | 20000 | 3.603 | 2.900 | +0.703 | 155/249 | 3.37e-06 | [+0.388 ; +1.013] | GAIN |
+| **test20k strict-clean** (old_local_v1 ∪ broad_local_v1, 128 exclues) | 19872 | 3.603 | 2.906 | +0.697 | 155/248 | 4.18e-06 | [+0.382 ; +1.009] | GAIN |
+| queries | 7099 | 1.165 | 0.000 | +1.165 | 0/39 | 3.64e-12 | [+0.968 ; +1.349] | GAIN |
+| test_v3 | 20000 | 4.697 | 4.117 | +0.580 | 241/316 | 0.00169 | [+0.047 ; +1.070] | GAIN |
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, **test20k strict-clean**, test_v3) : M7 +93.117 pts [IC95 +92.630 ; +93.592] (fraîche 5.162 %) ; réf +93.889 pts [+93.408 ; +94.343] (fraîche 4.441 %) ; différence M7 − réf **-0.772** [-1.027 ; -0.507] (bootstrap blocs 512 o, B=10 000, seed 0) ; [-0.995 ; -0.548] (bootstrap positions apparié, B=10 000, seed 25). Non strict (test20k masqué old_local_v1 seul) : M7 +93.117 [+92.630 ; +93.591] ; réf +93.890 [+93.410 ; +94.345] (fraîche 4.440 %) ; différence -0.773 [-1.028 ; -0.508]. queries à part (table). neither_code exclu.
+
+
+## Protocole et provenance
+
+- Candidat : M7 old = `spira_m7/cm_old_local_v1.npz` (446 551 146 o, sha256 396f11a142475cca3ee413066423aab9d4e3f708db191d3b96b8321875182b5f), checkpoint CALIBRÉ (sauvé 22 h 43 Toronto ; ni partial ni nocal). Corpus old_local_v1 (train sha256 e12b6586…ded54, 12 468 350 o). 2 époques × 600 000 ticks (train_summary.json).
+- Réf : old_ref = `checker/ckpt/ref_fixed2cal_old_local_v1.npz`, hits existants `checker/scale/hits_v4/old_ref__*.npz` (lecture seule). m9g v2b non utilisé (invalidé).
+- Éval M7 : `checker/scale/eval_bench_v4.py` de Checker appelé en CLI sans modification (HITS/OUT redirigés vers hashing_gen/m7_v41/, PYTHONDONTWRITEBYTECODE=1), fenêtres seen, fc2, fresh_en, fresh_fr, test20k, queries, test_v3 ; neither_code non évalué. Pleine longueur (8 000 / 20 000 positions, MAXPOS=0). 1 cœur (taskset -c 0), nice 10, OMP_NUM_THREADS=1, PYTHONHASHSEED=0. Durée 47 min 50 s (23 h 33 → 00 h 21 Toronto ; chargement 137,9 s + 2 732 s d’éval), pic RSS 1 004,7 Mo.
+- Fusion : comme pour toutes les entrées du banc v4, `bench_common.load_model` recalibre la fusion sur train[:60 000] au chargement : scale 0,055984 (valeur sauvée 0,056659). Les deux modèles sont traités de la même façon.
+- Tokenizers identiques (tgt_start, tgt_len, invocab égaux sur les 7 fenêtres ; EPT budget 15,3657 bits des deux côtés) → appariement par POSITION. hit = fused_hit ∧ invocab ; acc = hits / positions invocab.
+- McNemar exact bilatéral = décision (p < 0,05). Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un seul générateur seed 0 tiré fenêtre après fenêtre → indicatif ; aucune contradiction bootstrap/McNemar.
+- Critère (Philippe-Antoine) : RETENU ssi gain significatif sur seen ET sur ≥ 1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (queries compris). queries rapportée à part, hors moyenne fraîche.
+- Auto-test réf contre réf (`selftest_ref_vs_ref.md`) : 0/0 partout, Δ = 0, accs = results_v4.jsonl de Checker. `test_unit_mcn.py` : chemin d'appariement par unités = `unit_mcn` de scale_bench_v4.py sur 6 fenêtres (non utilisé ici, tokenizers identiques).
+
+## test20k : traitement
+
+- test20k = `broad/broad_local_v1/test.bin` (894 718 o, sha256 e89725bb…a9). Masque `mask_old_bench.npz` : 64-grammes confirmés octet à octet contre old_local_v1/train.bin ; position exclue ssi un octet de [s−64, s+l) est couvert. 434 640 octets couverts sur la fenêtre, mais le premier octet couvert est 144 389 alors que les 20 000 cibles évaluées couvrent [2 ; 88 765) → **0 position exclue**. Contre-vérification à hash indépendant (`crosscheck_mask_t20k.json`) : masque identique sur [0 ; 199 936), 0 octet couvert dans la plage évaluée.
+- **Strict-clean (correctif Hashing, 24 oct. ~00 h 55 Toronto, réserve Checker 00 h 48)** : masque recalculé par Hashing (`strict/mask_t20k_strict.py`, même schéma que mask_old_bench.py) contre broad_local_v1/train.bin (sha256 eda07017…91a1) et old_local_v1/train.bin ; règle : position exclue ssi un octet de [s−64, s+l) est couvert. broad_local_v1 couvre 45 852 octets de test20k, dont 272 dans la plage évaluée → **128 positions exclues** (toutes par broad_local_v1 ; 0 par old_local_v1), 19 872 gardées, 13 350 invocab. Résultat (`strict/verdict_m7_v41_strict.py`, verdict_m7_v41.py avec ce seul masque changé) : réf 2,906 %, M7 3,603 %, Δ +0,697, b/c 155/248, McNemar exact p = 4,18e-6, IC95 bootstrap [+0,382 ; +1,009] → GAIN ; décision REJETÉ inchangée. Identique au recompte indépendant de Checker (relais 00 h 30 / 00 h 45). JSON : `per_window.test20k_strict`, `test20k_strict_mask`, `seen_fresh_gap_strict` (entrées non strictes conservées).
+- `verify_old_local_v1.json` (INVALID DELTA ≠ 0) concerne le test propre du corpus old (old_local_v1/test.bin, 1 396 positions 64 o partagées avec son train) et neither_code (224 303) : pas utilisés dans ce verdict.
+
+## Référence M7 old validée par Checker (éval réf v2, hors banc v4.1)
+
+Chiffres de `checker/m8/results_m8.jsonl` (lignes 1, 3, 5, 7 ; tag cm_old_local_v1, script eval_ref_v2, 8 000 positions, fused sur TOUTES les positions, hors vocabulaire = échec), recomptés par Checker depuis les booléens par position : `spira_relay.md` l. 3870 et 3876 (Checker 23 h 00, `checker/recount/recount_m7old_ref_2300.py`) et l. 3890–3891 (Checker 23 h 07, `checker/recount/recount_m7old_fresh_2307.py`). Vérifié dans le jsonl par Hashing :
+
+| fenêtre (éval réf v2) | fused toutes positions | fused invocab | couverture vocab |
+|---|---|---|---|
+| seen | 98,06 % (0,980625) | 98,279 % | 0,7335 |
+| freshcode (fenêtre M7, pas dans le banc v4.1) | 55,81 % (0,558125) | 59,374 % | 0,67875 |
+| fresh_en | 3,25 % (0,0325) | 4,533 % | 0,71425 |
+| fresh_fr | 0,075 % (0,00075) | 0,189 % | 0,397375 |
+
+Les valeurs invocab de l'éval réf v2 sont identiques à celles du banc v4.1 ci-dessus (98,279 / 4,533 / 0,189) : seul le dénominateur diffère (Checker 00 h 30 l'a aussi constaté).
+
+## Incidents et limites
+
+- 21098 (script M7) n'est pas allé au bout : son étape finale run_gate_cm_v2 (PID 789343, test20k/oneshot du corpus old) a été arrêtée par SIGTERM à 23 h 10 lors de l'alerte mémoire (MemAvailable 0,73 Go, chrome tué par l'OOM) → CalledProcessError. `results_gate_v2.jsonl` est incomplet : ni utilisé ni poussé. int8_real.json et m9g_ban1_real.json ont été écrits avant.
+- Premier lancement de l'éval avec plafond `prlimit --as=1,5 Gio` : échec immédiat (_ArrayMemoryError au chargement de W_out, 416 Mio ; `eval_m7_old_fail_as1536M.log`). Relancé une fois avec `--as=2,5 Gio` (VmPeak mesuré 1,64 Go, pic RSS 1,00 Go). Lancement à MemAvailable 4,57 Go (porte ≥ 4 Go ; la règle ≥ 5,2 Go est arrivée après le lancement).
+- Une seule graine bootstrap, une seule exécution : pas de variance inter-entraînements mesurée.
diff --git a/results/hashing/m7_v41/verdict_m7_old_v41.script_output.md b/results/hashing/m7_v41/verdict_m7_old_v41.script_output.md
new file mode 100644
index 0000000000000000000000000000000000000000..52a2074b9635f15fde5e17cea438647ec0cb65d3
--- /dev/null
+++ b/results/hashing/m7_v41/verdict_m7_old_v41.script_output.md
@@ -0,0 +1,16 @@
+# Verdict v4.1 — M7 old (m7_old) contre old_ref
+
+**REJETÉ** — pas de gain significatif sur seen
+
+| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|
+| seen | 8000 | 98.279 | 98.330 | -0.051 | 8/5 | 0.581 | [-0.170 ; +0.068] | n.s. |
+| fc2 | 8000 | 12.787 | 11.504 | +1.283 | 87/149 | 6.55e-05 | [+0.450 ; +2.098] | GAIN |
+| fresh_en | 8000 | 4.533 | 3.395 | +1.138 | 60/125 | 2.01e-06 | [+0.647 ; +1.649] | GAIN |
+| fresh_fr | 8000 | 0.189 | 0.283 | -0.094 | 7/4 | 0.549 | [-0.292 ; +0.098] | n.s. |
+| test20k | 20000 | 3.603 | 2.900 | +0.703 | 155/249 | 3.37e-06 | [+0.388 ; +1.013] | GAIN |
+| queries | 7099 | 1.165 | 0.000 | +1.165 | 0/39 | 3.64e-12 | [+0.968 ; +1.349] | GAIN |
+| test_v3 | 20000 | 4.697 | 4.117 | +0.580 | 241/316 | 0.00169 | [+0.047 ; +1.070] | GAIN |
+
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k, test_v3) : M7 +93.117 pts [IC95 +92.630 ; +93.591] (fraîche 5.162 %) ; réf +93.890 pts [+93.410 ; +94.345] (fraîche 4.440 %) ; différence M7 − réf -0.773 [-1.028 ; -0.508]. queries à part (table). neither_code exclu.
+
diff --git a/results/hashing/m7_v41/verdict_m7_v41.py b/results/hashing/m7_v41/verdict_m7_v41.py
new file mode 100644
index 0000000000000000000000000000000000000000..1102b01cf22018e2eeae164f8837f610b8871596
--- /dev/null
+++ b/results/hashing/m7_v41/verdict_m7_v41.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict v4.1 : M7 old (cand) contre old_ref (réf), lecture seule des hits (aucun modèle chargé).
+Usage : verdict_m7_v41.py CAND_HITS_DIR CAND_TAG REF_HITS_DIR REF_TAG OUT_PREFIX
+Fenêtres : seen, fc2, fresh_en, fresh_fr, test20k (positions propres vs old_local_v1/train.bin, mask_old_bench.npz), queries, test_v3.
+neither_code exclu (contaminé). hit = fused_hit & invocab (masque invocab Checker 19 h 55).
+Appariement : si tgt_start ET tgt_len identiques (même tokenizer) → par position ; sinon unités entre frontières de patch communes
+(unit_mcn de scale_bench_v4.py : unité réussie ssi toutes ses cibles sont des hits).
+McNemar exact bilatéral (binomial) sur les discordants = DÉCISION (p<0,05). Bootstrap par blocs : blocs de 512 octets de la fenêtre
+(bloc = tgt_start // 512), B = 10 000, un seul générateur seed 0 tiré fenêtre après fenêtre (ordre WIN), même tirage pour les deux modèles (apparié) ; stat = acc invocab (hits/invocab).
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3), queries à part ; IC bootstrap (tirages indépendants par fenêtre).
+Critère : RETENU ssi gain significatif sur seen ET gain significatif sur ≥1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3 ; queries à part)
+ET aucune perte significative sur une fenêtre valide."""
+import sys, json, math, hashlib, numpy as np
+CD, CT, RD, RT, OP = sys.argv[1:6]
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "queries", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"] # queries : fenêtre valide (pertes comptées) mais rapportée à part, hors « fraîches »
+GAPW = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+MK = np.load("/workspace/spira_shared/hashing_gen/m7_v41/mask_old_bench.npz")
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def unit_mcn(za, zb, ha_, hb_, keep_a, keep_b):
+ sa, ea = za["tgt_start"][keep_a], (za["tgt_start"] + za["tgt_len"])[keep_a]; sb, eb = zb["tgt_start"][keep_b], (zb["tgt_start"] + zb["tgt_len"])[keep_b]
+ ha_, hb_ = ha_[keep_a], hb_[keep_b]; lo, hi = max(sa[0], sb[0]), min(ea[-1], eb[-1])
+ common = np.intersect1d(np.concatenate([sa, ea[-1:]]), np.concatenate([sb, eb[-1:]])); common = common[(common >= lo) & (common <= hi)]
+ def uh(s, e, h):
+ k = np.searchsorted(common, s, side="right") - 1; ok = (s >= common[0]) & (e <= common[-1]); u = np.ones(len(common) - 1, bool); np.logical_and.at(u, k[ok], h[ok]); return u
+ def cnt(s, e):
+ k = np.searchsorted(common, s, side="right") - 1; ok = (s >= common[0]) & (e <= common[-1]); return np.bincount(k[ok], minlength=len(common) - 1)[:len(common) - 1]
+ x, y = uh(sa, ea, ha_), uh(sb, eb, hb_); v = (cnt(sa, ea) > 0) & (cnt(sb, eb) > 0) # unités sans cible gardée d'un côté (masque) exclues
+ x, y = x[v], y[v]; return len(x), int((x & ~y).sum()), int((~x & y).sum())
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {} # un seul flux seed 0, tirages successifs par fenêtre (ordre WIN) → indépendants entre fenêtres
+for w in WIN:
+ A = np.load(f"{RD}/{RT}__{w}.npz"); B = np.load(f"{CD}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MK["sha__test20k"]) == str(A["window_sha256"]); cov = MK["test20k__covered"]
+ bad = lambda Z: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(Z["tgt_start"], Z["tgt_len"])])
+ ka, kb = ~bad(A), ~bad(B)
+ else: ka, kb = np.ones(na, bool), np.ones(nb_, bool)
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ if same_tok:
+ k = ka & kb; b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); pairing = "position (tokenizers identiques)"
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ else:
+ npair, b, c = unit_mcn(A, B, ha, hb, ka, kb); pairing = "unités entre frontières communes"; inv_same = None
+ p = binp(b, c)
+ ia, ib = A["invocab"].astype(bool) & ka, B["invocab"].astype(bool) & kb
+ acc_a, acc_b = 100 * (ha & ka).sum() / ia.sum(), 100 * (hb & kb).sum() / ib.sum()
+ nbk = int(max(A["tgt_start"].max(), B["tgt_start"].max()) // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][ka], ha[ka], A["invocab"].astype(bool)[ka], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][kb], hb[kb], B["invocab"].astype(bool)[kb], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1); d = bb - ba
+ BOOT[w] = (ba, bb)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions_ref": na, "n_positions_cand": nb_, "n_clean_ref": int(ka.sum()), "n_clean_cand": int(kb.sum()), "n_invocab_ref": int(ia.sum()), "n_invocab_cand": int(ib.sum()),
+ "n_paired": npair, "pairing": pairing, "invocab_identical": inv_same, "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "boot_sig_agrees": bool((lo > 0) == gain and (hi < 0) == loss),
+ "window_sha256": str(A["window_sha256"]), "ept_budget_ref": float(A["ept_budget_bits"]), "ept_budget_cand": float(B["ept_budget_bits"]),
+ "excluded_positions_ref": int((~ka).sum()), "excluded_positions_cand": int((~kb).sum())}
+ print(w, json.dumps(R[w]), flush=True)
+# écart seen − moyenne fraîche (5 fenêtres) ; tirages bootstrap indépendants entre fenêtres (même tirage pour les deux modèles dans une fenêtre)
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.percentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.percentile(dg, [2.5, 97.5])]}
+gap["windows"] = GAPW; gap["note"] = "queries hors moyenne (rapportée à part) ; neither_code exclu"
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "RETENU" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+out = {"cand": CT, "ref": RT, "windows": WIN, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "RETENU ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k propre, test_v3) ET aucune perte significative sur une fenêtre valide (7 fenêtres, queries compris)", "queries_gain_would_count": bool(R["queries"]["sig_gain"]),
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap,
+ "test20k_mask": "positions dont [s-64, s+l) touche un 64-gramme confirmé de old_local_v1/train.bin (mask_old_bench.npz)",
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict v4.1 — M7 old ({CT}) contre {RT}\n", f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "| fenêtre | n apparié | M7 % | réf % | Δ pts | b (réf seule) / c (M7 seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ md.append(f"| {w} | {r['n_paired']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["", f"Écart seen − moyenne fraîche ({', '.join(GAPW)}) : M7 {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence M7 − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [{gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}]. queries à part (table). neither_code exclu.", ""]
+open(f"{OP}.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m7_v41/verify_old_local_v1.json b/results/hashing/m7_v41/verify_old_local_v1.json
new file mode 100644
index 0000000000000000000000000000000000000000..05076804237cc7770b9c8dd1720dae9ee5d73fc3
--- /dev/null
+++ b/results/hashing/m7_v41/verify_old_local_v1.json
@@ -0,0 +1,69 @@
+{
+ "corpus": "/workspace/spira_shared/broad/old_local_v1",
+ "method": "verify_v3 semantics, train streamed in 4M-position chunks",
+ "files": {
+ "train": {
+ "bytes": 12468350,
+ "sha256": "e12b658625da3b7bacf84c68f82a7dbc53e196ccfdda0c7fc1d4ad46285ded54"
+ },
+ "test": {
+ "bytes": 319940,
+ "sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "oneshot": {
+ "bytes": 119763,
+ "sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "overlap64": {
+ "fresh_en": {
+ "window_bytes": 119763,
+ "n_64grams": 119700,
+ "hash_hits": 0,
+ "confirmed_positions": 0
+ },
+ "fresh_fr": {
+ "window_bytes": 1088688,
+ "n_64grams": 1088625,
+ "hash_hits": 0,
+ "confirmed_positions": 0
+ },
+ "neither_code": {
+ "window_bytes": 546036,
+ "n_64grams": 545973,
+ "hash_hits": 224303,
+ "confirmed_positions": 224303
+ },
+ "test20k": {
+ "window_bytes": 319940,
+ "n_64grams": 319877,
+ "hash_hits": 1396,
+ "confirmed_positions": 1396
+ },
+ "queries": {
+ "window_bytes": 27800,
+ "n_64grams": 27737,
+ "hash_hits": 0,
+ "confirmed_positions": 0
+ },
+ "fc2": {
+ "window_bytes": 199792,
+ "n_64grams": 199729,
+ "hash_hits": 0,
+ "confirmed_positions": 0
+ },
+ "corpus_test": {
+ "window_bytes": 319940,
+ "n_64grams": 319877,
+ "hash_hits": 1396,
+ "confirmed_positions": 1396
+ },
+ "corpus_oneshot": {
+ "window_bytes": 119763,
+ "n_64grams": 119700,
+ "hash_hits": 0,
+ "confirmed_positions": 0
+ }
+ },
+ "valid_zero_overlap": false
+}
\ No newline at end of file
diff --git a/results/hashing/m8_ml1/PREDECL_M8ml1.md b/results/hashing/m8_ml1/PREDECL_M8ml1.md
new file mode 100644
index 0000000000000000000000000000000000000000..3eb103a4d4d0b80839e5bc1646c5c3f4b1d947a0
--- /dev/null
+++ b/results/hashing/m8_ml1/PREDECL_M8ml1.md
@@ -0,0 +1,53 @@
+# PRÉ-DÉCLARATION — M8 ml1 (cm vs ctl) sur échantillon déterministe de multi_lang_v1 — SPIRA Hashing — **BROUILLON (DRAFT), en attente d'audit Checker**
+
+Rédigée le 2026-10-24 vers 16 h 25 (Toronto), AVANT tout run M8 ml1. Aucun bras lancé, aucun smoke lancé, **porte NON armée** (consigne parent 16 h 22 Toronto : ne pas armer ; Philippe-Antoine armera lui-même s'il le décide).
+Modèle : hashing_gen/m8_v1b/ (PREDECL.md, gate_m8v1b.sh, code/train_m8v1b.py b2b12c8c…, code/verdict_M8v1b.py r3B b3db0875…, code/make_sample_v1b.py b9a72c14…, code/run_guarded.sh).
+Aucun résultat M8 v1b ni CS1 ouvert pour écrire ce texte (seuls des journaux de progression et des manifestes de données ont été lus).
+
+## 0. Constat préalable (étape 1) — multi_lang_v1 est DÉJÀ contenu dans v1b et presque entièrement dans code_scale_v1
+Mesuré par code/overlap_step1.py (8f8e63a3…), sortie step1/overlap_step1.json (ed27a978…), lecture seule, pic RSS 293 Mo, 2,3 s :
+- multi_lang_v1/train.bin : 239 327 199 o, sha256 feef51d5f72cfa4345867005f0a044c852e3453ad9b7cb3bd015729d02ee2363 (attendu : OK), 36 910 fichiers, 0 doublon interne.
+- **corpus_diverse_v1b** (ddf67ffb…) : son segment multi_lang_v1 [281 458 684 ; 520 785 883) a le sha feef51d5… et est **égal octet à octet** à multi_lang_v1/train.bin ⇒ **100 % de multi_lang_v1 est dans v1b** (= 45,96 % des octets de v1b ; manifest v1b : v1_bytes = v1b_bytes = 239 327 199, rien retiré).
+- **code_scale_v1/train.bin** (ec957b71…) : 34 285 / 36 910 fichiers de multi_lang_v1 (92,9 %) et 218 904 510 / 238 773 564 o de contenu (**91,7 %**) y sont à l'identique (sha256 par fichier vs files_index.tsv). Le reste (8,3 %) = surtout dépôts exclus par la politique de licences de CS1 (django, curl, zlib, jq, terraform, akka, redis, AutoMapper) et sous-dossiers exclus — non mesuré fichier par fichier.
+- **code_scale_v1/train_delta.bin** (36f69c2f…) : **0** fichier de multi_lang_v1 (par construction).
+- Échantillon ml1 (§1) vs échantillon v1b : 2 542 des 2 543 documents github de v1b_sample.bin sont aussi dans ml1_sample.bin (16 114 751 o = 99,9999 % du github de v1b_sample ; **46,0 % des octets de ml1_sample**). Vs cs1_mix_sample.bin : ses 1 512 documents github (part v1b) sont tous dans ml1_sample (10 140 018 o = 28,9 % de ml1_sample). Documents entiers de ml1_sample identiques à un fichier de code_scale_v1/train.bin : 5 011, 32 000 919 o (**91,3 %**).
+- **Conséquence** : M8 ml1 n'apporte AUCUNE donnée nouvelle par rapport à M8 v1b (sous-ensemble strict de v1b) ni presque aucune par rapport à CS1. Il ne mesure qu'un **changement de composition** : 100 % code (15 langages) contre ≈ 46 % code + 54 % prose (v1b) ; préfixe SNN de v1b déjà ≈ 48,7 % github.
+- **Différence de question avec CS1** : CS1 = « ajouter du code NOUVEAU (train_delta, 0 % de recouvrement fichier avec v1b) à v1b améliore-t-il les fenêtres fraîches ? » (deux échantillons de même taille, mix vs v1b, classe ctl seule). M8 ml1 = « la comparaison cm vs ctl (M8 v1b) change-t-elle quand l'échantillon est 100 % code (même code que v1b) ? » + mesure seen/fresh. Les fenêtres fraîches de la règle sont surtout de la prose (fresh_en, fresh_fr, test20k, test_v3) sauf fc2 (code). **Avis Hashing : run largement redondant sur les données ; informatif seulement comme mesure de composition (code seul), et peu prioritaire.** La décision de le lancer revient à Philippe-Antoine.
+
+## 1. Échantillon
+- **sample/ml1_sample.bin — 35 128 951 o (= v1b_sample.bin), sha256 a7ffb34f099f32430a011872bda22b8eb0167db57ace02961383e739b422a678**, 5 438 documents. Re-tirage : sha identique (sample/rerun_check_sha.txt). Pic RSS 274 Mo, 0,5 s, nice 10.
+- Générateur : code/make_sample_ml1.py (sha256 75c237d285db800a807db6420fe5aa3a09f95c483b15261b1efc21b3aa9238c0) = règle de make_sample_v1b.py restreinte à la source multi_lang_v1 (documents = fichiers « \n<|endoffile|>\n », dépôts par files_kept cumulés de build_stage1.json, langue = intended_language, strates github/ ×15, T_s = round(35 128 951 × part d'octets), seed de strate 20261024 XOR sha256(nom)[:16], prise si rapproche le cumul, sortie entrelacée, séparateurs natifs) + ajustement de taille exacte repris de make_sample_cs1.py : 56 documents de fin retirés entiers (excès naturel 163 955 o), puis tête de 12 954 o d'un document non pris (github/C++, protocolbuffers/protobuf, doc 16035, 28 117 o) — seul document non entier, en fin de fichier.
+- Manifeste : sample/ml1_sample_manifest.json (57e0d9a3…) ; index : sample/ml1_sample_docs.json (4ec9c638…).
+- Composition (préfixes, octets de documents) : seen [0, 200 000) : Java 17,8 %, Scala 14,7 %, C# 8,1 %, Rust 8,0 %, JS 7,2 %, Kotlin 7,0 %, C++ 6,6 %, PHP 6,5 %, TS 5,9 %, Go 5,8 %, C 5,2 %, Ruby 3,9 %, Python 3,3 % (pas de Shell ni Swift) ; [0, 2 800 000) ≈ préfixe SNN : 15 langages, Java 11,5 %, C++ 10,1 %, TS 9,1 %, Scala 8,4 %, … Shell 0,4 %. Bornes exactes des préfixes SNN/AM en patches : **à mesurer** (tokenisation de train_m8v1b.py) — non mesurées (smoke non lancé, §5).
+- **Recompte 64 o de l'échantillon : NON FAIT.** multi_lang_v1 a dédup-64 o PASS (Checker, checker/manifest/multi_lang_v1/MANIFEST.md, 16 h 15 Toronto : 0 position confirmée sur toutes les fenêtres) mais les 64-grammes à cheval sur les nouvelles jonctions de documents ne sont pas couverts. Job lourd (≈ 856 Mo pour v1b) : à faire quand un créneau < 4 lourds existe, ou par Checker. Requis avant GO.
+
+## 2. Bras, budgets, seeds (identiques à M8 v1b)
+- **ctl d'abord** : SPIRA.build ; puis **cm** : CMSPIRA.build_cm (code/countmin.py de v1b, caab5040…). Même design que v1b (cm vs ctl, seule différence la classe) ⇒ le bras cm est maintenu.
+- SPIRAConfig(vocab_size=16384, d_in=1024, snn_tokens=600 000, am_tokens=1 200 000, epochs=2), seed modèle 20261022, seed d'échantillonnage 20261024, maxpos 4000 par fenêtre.
+- Script : hashing_gen/m8_v1b/code/train_m8v1b.py (b2b12c8c6beb4b76954b6da99b0f273ca5eefad11268355786b8c3d420719e3c), **inchangé, lu en place** ; seuls --data et --outdir changent :
+ `train_m8v1b.py --arm {ctl|cm} --data m8_ml1/sample/ml1_sample.bin --outdir m8_ml1/runs --snn-tokens 600000 --am-tokens 1200000 --epochs 2 --maxpos 4000 --windows seen,fc2,fresh_en,fresh_fr,test20k,test_v3,queries`. Pas de --smoke-ticks.
+- Fenêtres : seen = ml1_sample[0, 200 000) (100 % code) ; fc2 (b052096b), fresh_en (67ff20b2), fresh_fr (875f0906), test20k = spira_m7/windows/test20k.bin (ce0526c6, strict via mask_oldtest_strict.npz comme v1b), test_v3 (a6730bbe), queries (5aab38d6, à part).
+
+## 3. Hypothèse et règle (pré-déclarées)
+- Hypothèse H1 : sur un échantillon 100 % code, cm (M8) bat ctl à budget égal sur ≥ 1 fenêtre fraîche propre sans perte significative. H0 : pas de différence.
+- **Règle B, reprise de v1b r3B** (b3db0875…) : **ADOPTÉ** ssi gain significatif (McNemar exact p < 0,05 ET c > b ET IC95 bootstrap > 0) sur ≥ 1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre), ET aucune perte significative (p < 0,05 ET b > c) sur une fenêtre valide, **seen inclus** (égalité sur seen saturé admise). Sinon **REJETÉ**. **NON MESURABLE** : budgets inégaux, passe SNN incomplète (ticks × 1 ≠ snn_tokens), seen non comparable (trained_frac < 0,99), fusion.scale d'un bras hors [0,03 ; 0,11] (plage provisoire de r3B, inchangée).
+- Positions propres, appariement, McNemar, bootstrap blocs 512 o B = 10 000 seed 0 : identiques à v1b §6.
+- **Script de verdict : verdict_M8ml1.py NON ÉCRIT.** verdict_M8v1b.py code en dur B8 = m8_v1b, SAMPLE_SHA = 9ea562e4… et le recompte v1b ; il faudra une copie ne changeant que ces constantes (B8, SAMPLE, SAMPLE_SHA, RC_SAMPLE), diff publié, audit Checker. Sans ce script audité la porte ne lance pas de verdict.
+
+## 4. Écart seen − fresh PAR FENÊTRE (mesure, hors règle)
+- Appel en LECTURE SEULE de **checker/scale/gap_bg1d/gap_seen_fresh.py (sha256 1de88829aca248c756d1b0adfd3d30ad3f20f4348089ca0eb4ed54e284848d51, vérifié 16 h 22 Toronto), non modifié**, pour chaque bras :
+ `TAG={ctl|cm} HITS=m8_ml1/runs RESULTS=m8_ml1/runs/results.jsonl CKPT=m8_ml1/runs/{arm}.npz OUTDIR=m8_ml1/gap python gap_seen_fresh.py {arm}` (OUTDIR forcé hors de checker/ ; défaut = checker/scale/gap_bg1d/out, interdit).
+- Rapport : écart par fenêtre (seen − fc2, fresh_en, fresh_fr, test20k, test_v3) + moyenne propre, IC95 bootstrap ; **NON COMPARABLE si trained_frac < 0,99**.
+- Références Checker (fournies par la consigne, non recalculées ici) : **m8_v3 86,17 pts IC95 [84,95 ; 87,37]**, **m8_broad14 85,96 pts IC95 [84,78 ; 87,15]** (scale_bench_v4.md l. 11 et 13).
+- **Limites constatées à la lecture du script (à trancher par Checker) :**
+ (a) trained_frac exige .cov.json ou une entrée du tag dans checker/scale/seen_audit_v4.json ; train_m8v1b.py ne produit ni l'un ni l'autre ⇒ sans action de Checker, sortie attendue **NON COMPARABLE (rc 3)**, aucun écart publié.
+ (b) Le masque strict du script attend test20k = e89725bb (broad_local_v1/test, banc v4) ; train_m8v1b.py évalue test20k = ce0526c6 (old_local_v1/test) ⇒ contrôle « mask_window_sha_test20k » en échec attendu.
+ (c) Les références 86,17 / 85,96 viennent du banc v4 (fenêtres et seen différents ; seen ml1 = 100 % code) : comparaison indicative seulement, fenêtres communes fc2, fresh_en, fresh_fr, test_v3, queries (mêmes sha).
+ Rien n'est contourné : les sorties du script seront publiées telles quelles.
+
+## 5. Ressources / smoke
+- **Smoke NON lancé** (16 h 22-16 h 30 Toronto) : 4 jobs python lourds (RSS ≥ 500 Mo) sur la box — 15953, 15242, 16884 (Checker/cov) et 298936 (M8 v1b ctl) — donc porte fermée (< 4 exigé). MemAvailable 7,1-7,5 Go.
+- Pics de réservation repris de v1b (NON mesurés sur ml1) : ctl 1,6 Go, cm 2,5 Go (smoke v1b ru_maxrss 1,26 / 2,14 Go). Durées v1b (estimations, pas des mesures ml1) : ctl ≈ 4,3-4,8 h, cm ≈ 13,3 h.
+- Porte : gate_m8ml1.sh (sha au relais), **non armée**. Priorité absolue au bras cm de M8 v1b.
+
+— SPIRA Hashing, 2026-10-24 ~16 h 25 EDT (Toronto) — BROUILLON, en attente d'audit Checker
diff --git a/results/hashing/m8_ml1/code/make_sample_ml1.py b/results/hashing/m8_ml1/code/make_sample_ml1.py
new file mode 100644
index 0000000000000000000000000000000000000000..56f957df8a21fbcf26c46a9f6a0a666b67dd6c9f
--- /dev/null
+++ b/results/hashing/m8_ml1/code/make_sample_ml1.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — M8 ml1 : échantillon déterministe de multi_lang_v1/train.bin, MÊME méthode que m8_v1b/code/make_sample_v1b.py (b9a72c14…)
+restreinte à la seule source multi_lang_v1, + ajustement de taille exacte repris de code_scale_v1/code/make_sample_cs1.py (3b363767…).
+Règle :
+ 1. Documents : fichiers séparés par b"\\n<|endoffile|>\\n" ; dépôt = cumul de files_kept (multi_lang_v1/build_stage1.json) ; langue =
+ intended_language du dépôt (identique à make_sample_v1b.py). Strates github/.
+ 2. TARGET = 35 128 951 (= taille de m8_v1b/sample/v1b_sample.bin) ; T_s = round(TARGET * octets(strate) / octets(total documents)).
+ 3. Dans chaque strate : permutation seedée numpy PCG64, seed = 20261024 ^ int(sha256(nom de strate)[:16 hex]) ; document pris ssi
+ |cum+len-T_s| < |cum-T_s| (documents entiers).
+ 4. Sortie entrelacée : clé = (cumul_avant + len/2) / total_pris de la strate ; tri (clé, rang seedé PCG64(20261024)). Séparateur natif entre documents.
+ 5. Taille exacte (comme CS1) : on retire des documents ENTIERS en fin d'ordre de sortie jusqu'à pos < TARGET avec un manque > len(sép) ;
+ puis séparateur + TÊTE d'un document non pris (strate au plus grand déficit T_s - pris, premier de sa permutation assez long).
+Pas de décontamination itérative : multi_lang_v1 a déjà dédup-64 o PASS (Checker) ; les 64-grammes à cheval sur des jonctions nouvelles
+NE SONT PAS revérifiés ici (recompte de l'échantillon à faire, job lourd, en attente d'un créneau).
+Usage : make_sample_ml1.py OUTDIR"""
+import sys, os, json, hashlib, resource, time, numpy as np
+S = "/workspace/spira_shared"; ML = f"{S}/multi_lang_v1/train.bin"; ML_SHA = "feef51d5f72cfa4345867005f0a044c852e3453ad9b7cb3bd015729d02ee2363"
+SEED = 20261024; TARGET = 35_128_951; SEP = b"\n<|endoffile|>\n"; OUT = sys.argv[1]; os.makedirs(OUT, exist_ok=True); t0 = time.time()
+assert os.path.getsize(ML) == 239327199
+buf = open(ML, "rb").read(); ssrc = hashlib.sha256(buf).hexdigest(); assert ssrc == ML_SHA, ssrc
+st1p = f"{S}/multi_lang_v1/build_stage1.json"; st1 = json.load(open(st1p)); reps = [(r["repo"], r["intended_language"], r["files_kept"]) for r in st1["repos"]]
+cuts = []; k = buf.find(SEP)
+while k >= 0: cuts.append(k); k = buf.find(SEP, k + 1)
+starts = [0] + [c + len(SEP) for c in cuts]; ends = cuts + [len(buf)]
+assert len(starts) == sum(r[2] for r in reps), (len(starts), sum(r[2] for r in reps))
+docs = []; i = 0
+for repo, lang, nf in reps:
+ for _ in range(nf): docs.append((f"github/{lang}", repo, lang, starts[i], ends[i])); i += 1
+tot = sum(d[4] - d[3] for d in docs); strata = sorted({d[0] for d in docs}); byS = {s: [i for i, d in enumerate(docs) if d[0] == s] for s in strata}
+sel = []; ST = {}; fill = {}
+for s in strata:
+ D = byS[s]; Bs = sum(docs[i][4] - docs[i][3] for i in D); T = round(TARGET * Bs / tot)
+ sseed = SEED ^ int(hashlib.sha256(s.encode()).hexdigest()[:16], 16); rng = np.random.default_rng(sseed); perm = rng.permutation(len(D))
+ cum = 0; take = []; rest = []
+ for j in perm:
+ i = D[j]; L = docs[i][4] - docs[i][3]
+ if abs(cum + L - T) < abs(cum - T): take.append(i); cum += L
+ else: rest.append(i)
+ c2 = 0
+ for i in take:
+ L = docs[i][4] - docs[i][3]; sel.append(((c2 + L / 2) / max(cum, 1), i)); c2 += L
+ fill[s] = rest
+ ST[s] = {"pool_doc_bytes": Bs, "pool_docs": len(D), "target_bytes": T, "taken_bytes": cum, "taken_docs": len(take), "share_pool": Bs / tot, "stratum_seed": sseed}
+orng = np.random.default_rng(SEED); tie = orng.permutation(len(sel)); order = sorted(range(len(sel)), key=lambda q: (sel[q][0], int(tie[q])))
+DOCS = []; pos = 0 # [strate, dépôt, langue, src_a, src_b, out_a, out_b, doc_id, statut]
+for n, q in enumerate(order):
+ i = sel[q][1]; d = docs[i]
+ if n: pos += len(SEP)
+ L = d[4] - d[3]; DOCS.append([d[0], d[1], d[2], d[3], d[4], pos, pos + L, i, "entier"]); pos += L
+natural = pos; adj = {"natural_bytes": natural, "excess_bytes": natural - TARGET, "dropped_whole_docs_at_end": 0, "filler": None}
+while pos > TARGET or (0 < TARGET - pos <= len(SEP)):
+ x = DOCS.pop(); pos = x[5] - len(SEP); adj["dropped_whole_docs_at_end"] += 1; ST[x[0]]["taken_bytes"] -= x[6] - x[5]; ST[x[0]]["taken_docs"] -= 1
+if pos < TARGET:
+ L = TARGET - pos - len(SEP); assert L > 0
+ s_ = max(strata, key=lambda z: (ST[z]["target_bytes"] - ST[z]["taken_bytes"], z))
+ i = next(i for i in fill[s_] if docs[i][4] - docs[i][3] >= L); d = docs[i]; pos += len(SEP)
+ DOCS.append([d[0], d[1], d[2], d[3], d[3] + L, pos, pos + L, i, f"tete_{L}_de_{d[4]-d[3]}"]); pos += L
+ adj["filler"] = {"stratum": s_, "doc_id": i, "repo": d[1], "head_bytes": L, "doc_bytes": d[4] - d[3]}
+assert pos == TARGET
+outp = f"{OUT}/ml1_sample.bin"; sha = hashlib.sha256()
+with open(outp + ".partial", "wb") as w:
+ for n, x in enumerate(DOCS):
+ if n: w.write(SEP); sha.update(SEP)
+ b = buf[x[3]:x[4]]; w.write(b); sha.update(b)
+os.replace(outp + ".partial", outp); assert os.path.getsize(outp) == TARGET
+def comp(n):
+ c = {}
+ for x in DOCS:
+ if x[5] >= n: break
+ c[x[0]] = c.get(x[0], 0) + min(x[6], n) - x[5]
+ t = sum(c.values()); return {k: round(v / t, 4) for k, v in sorted(c.items())}
+res = {"author": "SPIRA Hashing", "script": os.path.abspath(__file__), "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "method_ref": {"make_sample_v1b.py": "b9a72c14958e82db7585d50aa7e1c0de5e927e9171b3bc64482157fe003db595", "make_sample_cs1.py (taille exacte)": "3b3637679042898896eec10bc3363f9ca801434ad9bd35a056fa591d33bb55d0"},
+ "source": {"path": ML, "bytes": len(buf), "sha256": ssrc, "build_stage1_sha256": hashlib.sha256(open(st1p, "rb").read()).hexdigest(), "files": len(docs), "doc_bytes": tot},
+ "seed": SEED, "target_bytes": TARGET, "adjust": adj,
+ "sample": {"path": outp, "bytes": TARGET, "sha256": sha.hexdigest(), "n_docs": len(DOCS)}, "strata": ST,
+ "prefix_composition": {str(n): comp(n) for n in (60_000, 200_000, 2_000_000, 2_400_000, 2_800_000, 5_600_000, TARGET)},
+ "docs_file": f"{OUT}/ml1_sample_docs.json", "peak_rss_MB": resource.getrusage(resource.RUSAGE_SELF).ru_maxrss // 1024, "elapsed_s": round(time.time() - t0, 1)}
+json.dump(DOCS, open(f"{OUT}/ml1_sample_docs.json", "w"))
+json.dump(res, open(f"{OUT}/ml1_sample_manifest.json", "w"), indent=1, ensure_ascii=False)
+print(json.dumps({k: res[k] for k in ("sample", "adjust", "peak_rss_MB", "elapsed_s")}), flush=True)
diff --git a/results/hashing/m8_ml1/code/overlap_step1.py b/results/hashing/m8_ml1/code/overlap_step1.py
new file mode 100644
index 0000000000000000000000000000000000000000..9005edec964291f7bba92882b5c2a26a0b61568e
--- /dev/null
+++ b/results/hashing/m8_ml1/code/overlap_step1.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — M8 ml1 étape 1 : multi_lang_v1 est-il contenu dans corpus_diverse_v1b et code_scale_v1 ?
+Lecture seule. (a) sha de multi_lang_v1/train.bin et du segment multi_lang_v1 de v1b (plage du manifest v1b) + égalité octet à octet ;
+(b) découpe de multi_lang_v1 en fichiers (sép. b"\\n<|endoffile|>\\n"), sha256 par fichier, comparaison aux sha de code_scale_v1/files_index.tsv
+(train.bin entier, et sous-ensemble delta offset_delta>=0)."""
+import hashlib, json, resource, time, sys
+S="/workspace/spira_shared"; t0=time.time(); SEP=b"\n<|endoffile|>\n"
+ML=f"{S}/multi_lang_v1/train.bin"; V1B=f"{S}/hashing_gen/corpus_v1b/train.bin"; IDX=f"{S}/hashing_gen/code_scale_v1/files_index.tsv"
+man=json.load(open(f"{S}/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json")); a,b=[(x,y) for n,x,y in man["segments_v1b"] if n=="multi_lang_v1"][0]
+ml=open(ML,"rb").read(); sha_ml=hashlib.sha256(ml).hexdigest()
+h=hashlib.sha256(); eq=True; f=open(V1B,"rb"); f.seek(a); p=0
+while p=0: delta[r[2]]=int(r[3])
+nf=0; inf=0; inb=0; ind=0; indb=0; tot=0; pos=0; seen=set(); dupf=0
+while True:
+ j=ml.find(SEP,pos); e=len(ml) if j<0 else j; d=hashlib.sha256(memoryview(ml)[pos:e]).hexdigest(); L=e-pos
+ nf+=1; tot+=L
+ if d in seen: dupf+=1
+ seen.add(d)
+ if d in full: inf+=1; inb+=L
+ if d in delta: ind+=1; indb+=L
+ if j<0: break
+ pos=j+len(SEP)
+res={"multi_lang_v1":{"bytes":len(ml),"sha256":sha_ml,"files":nf,"content_bytes":tot,"dup_files_within":dupf},
+ "v1b_segment":{"range":[a,b],"sha256":seg_sha,"byte_equal_to_multi_lang_v1":bool(eq and b-a==len(ml)),"share_of_v1b_bytes":(b-a)/520785883},
+ "code_scale_v1_train":{"files_index_rows":len(full),"ml1_files_identical":inf,"ml1_bytes_identical":inb,"share_files":inf/nf,"share_bytes":inb/tot},
+ "code_scale_v1_delta":{"files":len(delta),"ml1_files_identical":ind,"ml1_bytes_identical":indb},
+ "peak_rss_MB":resource.getrusage(resource.RUSAGE_SELF).ru_maxrss//1024,"elapsed_s":round(time.time()-t0,1)}
+json.dump(res,open(sys.argv[1],"w"),indent=1); print(json.dumps(res,indent=1))
diff --git a/results/hashing/m8_ml1/code/run_guarded_ml1.sh b/results/hashing/m8_ml1/code/run_guarded_ml1.sh
new file mode 100644
index 0000000000000000000000000000000000000000..6636ec3fcc89e7f56f6c958fd50ab3ddce53b2ce
--- /dev/null
+++ b/results/hashing/m8_ml1/code/run_guarded_ml1.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# SPIRA Hashing — M8 ml1 : lanceur garde pour UN bras. Copie de m8_v1b/code/run_guarded.sh SANS kill (consigne : ne jamais tuer).
+# Usage : run_guarded_ml1.sh NAME PEAK_BYTES LOG -- CMD... Porte : MemAvailable >= 5,2 Go + PEAK, lourds (python RSS>=500 Mo) < 4. Sinon sortie 3.
+# Surveillance mémoire : JOURNAL seulement (alerte si MemAvailable < 4 Go) ; aucun signal envoyé à aucun process.
+export TZ=America/Toronto OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0 TMPDIR=/workspace/spira_shared/hashing_gen/m8_ml1/tmp
+D=/workspace/spira_shared/hashing_gen/m8_ml1; NAME=$1; PEAK=$2; LOG=$3; shift 4; R=$D/logs/guarded.log; WARN=4000000000
+log(){ echo "$(date '+%F %H:%M:%S %Z') [$NAME] $*" >> $R; }
+mem(){ awk '/MemAvailable/{print $2*1024}' /proc/meminfo; }
+heavy(){ ps -eo pid,rss,comm | awk '$3 ~ /^python/ && $2>=500000 {print $1}' | tr '\n' ' '; }
+m=$(mem); h=$(heavy); nh=$(echo $h | wc -w); need=$(( 5200000000 + PEAK ))
+if [ $m -lt $need ] || [ $nh -ge 4 ]; then log "GATE CLOSED MemAvailable=${m}B need=${need}B heavy=$nh [$h]"; exit 3; fi
+log "GATE OK MemAvailable=${m}B need=${need}B heavy=$nh [$h] cmd=$*"
+setsid nice -n 10 "$@" > $LOG 2>&1 & P=$!; log "START pid=$P"
+minm=$m; maxr=0
+while kill -0 $P 2>/dev/null; do # kill -0 = test d'existence, aucun signal
+ m=$(mem); [ $m -lt $minm ] && minm=$m
+ r=$(ps -o rss= -g $P 2>/dev/null | awk '{s+=$1}END{print s+0}'); [ $r -gt $maxr ] && maxr=$r
+ echo "$(date +%s) $m $r" >> $LOG.mem
+ [ $m -lt $WARN ] && log "ALERTE MemAvailable=${m}B < 4 Go (aucune action : consigne ne jamais tuer)"
+ sleep 5
+done
+wait $P; e=$?; log "EXIT $e min_MemAvailable=${minm}B max_groupRSS=${maxr}kB"; exit $e
diff --git a/results/hashing/m8_ml1/gate_m8ml1.sh b/results/hashing/m8_ml1/gate_m8ml1.sh
new file mode 100644
index 0000000000000000000000000000000000000000..bb445a3055c5d996b7e8b60bcd578eb4e0422385
--- /dev/null
+++ b/results/hashing/m8_ml1/gate_m8ml1.sh
@@ -0,0 +1,76 @@
+#!/bin/bash
+# SPIRA Hashing — porte M8 ml1 (modèle : m8_v1b/gate_m8v1b.sh). Bras ctl PUIS cm de train_m8v1b.py (inchangé, b2b12c8c…) sur sample/ml1_sample.bin.
+# Conditions (TOUTES) avant chaque lancement :
+# (a) drapeau m8_ml1/GO_CHECKER_PASS présent — posé À LA MAIN par SPIRA Hashing après PASS d'audit Checker ; ce script ne le crée JAMAIS ;
+# (b) priorité M8 v1b cm : refus tant que m8_v1b/STATUS montre cm=pending, ou tant que la porte v1b 218845 vit et que cm n'est pas running
+# (=> on ne prend jamais le créneau dont v1b cm a besoin) ;
+# (c) lourds (python RSS >= 500 Mo, toute la box) < 4 ;
+# (d) MemAvailable >= 5,2 Go + pic du bras + marge restante du bras ml1 déjà en cours ;
+# (e) sha de l'échantillon et du script d'entraînement = valeurs pré-déclarées.
+# Lancement via code/run_guarded_ml1.sh : setsid, nice 10, OMP_NUM_THREADS=1, PYTHONHASHSEED=0. Ce script et le lanceur ne tuent RIEN.
+# ctl d'abord : cm n'est envisagé qu'après le lancement de ctl. Reprise <= 3 essais (train_m8v1b.py reprend à la dernière époque complète).
+# Verdict : seulement si code/verdict_M8ml1.py existe et que son sha = code/verdict_M8ml1.sha256 (audité Checker) ; sinon attente.
+# Écart seen/fresh : checker/scale/gap_bg1d/gap_seen_fresh.py appelé en lecture seule (sha 1de88829… vérifié), OUTDIR = m8_ml1/gap.
+export TZ=America/Toronto OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0 TMPDIR=/workspace/spira_shared/hashing_gen/m8_ml1/tmp
+S=/workspace/spira_shared; D=$S/hashing_gen/m8_ml1; V=$S/hashing_gen/m8_v1b; PY=/workspace/SPIRA-venv/bin/python; G=$D/code/run_guarded_ml1.sh
+TRAIN=$V/code/train_m8v1b.py; TRAIN_SHA=b2b12c8c6beb4b76954b6da99b0f273ca5eefad11268355786b8c3d420719e3c
+DATA=$D/sample/ml1_sample.bin; DATA_SHA=a7ffb34f099f32430a011872bda22b8eb0167db57ace02961383e739b422a678
+GAP=$S/checker/scale/gap_bg1d/gap_seen_fresh.py; GAP_SHA=1de88829aca248c756d1b0adfd3d30ad3f20f4348089ca0eb4ed54e284848d51
+VGATE=218845; FLAG=$D/GO_CHECKER_PASS; ST=$D/STATUS; GL=$D/logs/gate_m8ml1.log
+declare -A PEAK=( [ctl]=1600000000 [cm]=2500000000 ) # réservations reprises de v1b (smoke v1b 1,26 / 2,14 Go) — non mesurées sur ml1
+declare -A S_=( [ctl]=pending [cm]=pending ); declare -A TRY=( [ctl]=0 [cm]=0 )
+mkdir -p $D/runs $D/logs $D/gap $D/tmp
+log(){ echo "$(date '+%F %H:%M:%S %Z') $*" >> $GL; }
+status(){ echo "$(date '+%F %H:%M:%S %Z') $* | ctl=${S_[ctl]}(try ${TRY[ctl]}) cm=${S_[cm]}(try ${TRY[cm]}) | gate pid $$" > $ST; }
+mem(){ awk '/MemAvailable/{print $2*1024}' /proc/meminfo; }
+nheavy(){ ps -eo rss,comm | awk '$2 ~ /^python/ && $1>=500000' | wc -l; }
+armrss(){ pgrep -f "train_m8v1b.py --arm $1 --data $DATA" | xargs -r ps -o rss= -p 2>/dev/null | awk '{s+=$1}END{print s*1024+0}'; }
+v1b_cm(){ grep -o 'cm=[a-z]*' $V/STATUS 2>/dev/null | head -1 | cut -d= -f2; }
+v1b_ok(){ c=$(v1b_cm); [ -z "$c" ] && { echo "v1b STATUS illisible"; return 1; }
+ [ "$c" = pending ] && { echo "v1b cm=pending (priorité v1b)"; return 1; }
+ if [ -d /proc/$VGATE ] && [ "$c" != running ]; then echo "porte v1b $VGATE vivante et cm=$c"; return 1; fi; return 0; }
+log "ARMÉ pid=$$ ; drapeau attendu $FLAG (non créé par ce script) ; pics ctl=${PEAK[ctl]} cm=${PEAK[cm]}"
+while :; do
+ for arm in ctl cm; do
+ if [ "${S_[$arm]}" = running ] && [ -e $D/logs/arm_$arm.exit ]; then
+ e=$(cat $D/logs/arm_$arm.exit); rm -f $D/logs/arm_$arm.exit; log "bras $arm fin code $e"
+ if [ "$e" = 0 ]; then S_[$arm]=done
+ if [ "$(sha256sum $GAP | cut -d' ' -f1)" = $GAP_SHA ]; then
+ TAG=$arm HITS=$D/runs RESULTS=$D/runs/results.jsonl CKPT=$D/runs/$arm.npz OUTDIR=$D/gap nice -n 10 $PY -u $GAP $arm > $D/logs/gap_$arm.log 2>&1
+ log "gap_seen_fresh $arm code $? (0 OK, 3 NON COMPARABLE, 2 EN ATTENTE)"
+ else log "gap_seen_fresh.py sha différent de $GAP_SHA : NON appelé"; fi
+ elif [ "$e" = 3 ]; then S_[$arm]=pending; TRY[$arm]=$((TRY[$arm]-1))
+ elif [ ${TRY[$arm]} -ge 3 ]; then S_[$arm]=failed; else S_[$arm]=pending; fi
+ fi
+ done
+ if [ "${S_[ctl]}" = done ] && [ "${S_[cm]}" = done ]; then
+ VS=$D/code/verdict_M8ml1.py
+ if [ -e $VS ] && [ -e $VS.sha256 ] && [ "$(sha256sum $VS | cut -d' ' -f1)" = "$(cut -d' ' -f1 $VS.sha256)" ]; then
+ status "VERDICT en cours"; nice -n 10 $PY -u $VS --runs $D/runs --outdir $D/verdict > $D/logs/verdict_M8ml1_run.log 2>&1; e=$?
+ log "verdict code $e"; status "FINI verdict code $e"; exit $e
+ fi
+ status "BRAS FINIS — verdict EN ATTENTE (verdict_M8ml1.py absent ou non audité)"; sleep 300; continue
+ fi
+ if [ "${S_[ctl]}" = failed ] || [ "${S_[cm]}" = failed ]; then
+ if [ "${S_[ctl]}" != running ] && [ "${S_[cm]}" != running ]; then status "ÉCHEC (3 essais) — voir $GL"; log "ÉCHEC"; exit 1; fi
+ fi
+ if [ ! -e $FLAG ]; then status "ATTENTE drapeau GO_CHECKER_PASS (posé par Hashing après PASS Checker)"; sleep 60; continue; fi
+ for arm in ctl cm; do
+ [ "${S_[$arm]}" = pending ] || continue
+ [ $arm = cm ] && [ "${S_[ctl]}" = pending ] && continue # ctl d'abord
+ why=$(v1b_ok) || { status "ATTENTE priorité v1b : $why"; continue; }
+ [ "$(sha256sum $DATA | cut -d' ' -f1)" = $DATA_SHA ] && [ "$(sha256sum $TRAIN | cut -d' ' -f1)" = $TRAIN_SHA ] || { status "BLOQUÉ sha échantillon/script"; log "sha échantillon ou script différent"; continue; }
+ m=$(mem); nh=$(nheavy); extra=0
+ for o in ctl cm; do [ "${S_[$o]}" = running ] && { r=$(armrss $o); x=$(( PEAK[$o] - r )); [ $x -gt 0 ] && extra=$((extra + x)); }; done
+ need=$(( 5200000000 + PEAK[$arm] + extra ))
+ if [ $nh -lt 4 ] && [ $m -ge $need ]; then
+ TRY[$arm]=$((TRY[$arm]+1)); S_[$arm]=running
+ log "LANCE $arm essai ${TRY[$arm]} MemAvailable=$m need=$need lourds=$nh v1b_cm=$(v1b_cm)"
+ ( $G m8ml1_$arm ${PEAK[$arm]} $D/logs/arm_${arm}_try${TRY[$arm]}.log -- $PY -u $TRAIN --arm $arm --data $DATA \
+ --outdir $D/runs --snn-tokens 600000 --am-tokens 1200000 --epochs 2 --maxpos 4000 --windows seen,fc2,fresh_en,fresh_fr,test20k,test_v3,queries
+ echo $? > $D/logs/arm_$arm.exit ) &
+ sleep 120
+ else status "ATTENTE ressources pour $arm : MemAvailable=$m need=$need lourds=$nh"; fi
+ done
+ { [ "${S_[ctl]}" = running ] || [ "${S_[cm]}" = running ]; } && status "EN COURS"; sleep 60
+done
diff --git a/results/hashing/m8_ml1/sample/ml1_sample_docs.json b/results/hashing/m8_ml1/sample/ml1_sample_docs.json
new file mode 100644
index 0000000000000000000000000000000000000000..2753664e01b5db2fdf4626a10621e8b60d34bea6
--- /dev/null
+++ b/results/hashing/m8_ml1/sample/ml1_sample_docs.json
@@ -0,0 +1 @@
+[["github/Scala", "sbt/sbt", "Scala", 238354409, 238354430, 0, 21, 36150, "entier"], ["github/PHP", "laravel/framework", "PHP", 185578044, 185578229, 36, 221, 25637, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65025204, 65025485, 236, 517, 10022, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177286230, 177286400, 532, 702, 23929, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159501170, 159501459, 717, 1006, 21142, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 122504213, 122505420, 1021, 2228, 15874, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206297875, 206298655, 2243, 3023, 29909, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11441693, 11443368, 3038, 4713, 1813, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164798525, 164799378, 4728, 5581, 22002, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21883974, 21886019, 5596, 7641, 3002, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37894044, 37896463, 7656, 10075, 4921, "entier"], ["github/Go", "gohugoio/hugo", "Go", 87804226, 87806200, 10090, 12064, 12206, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194443745, 194446057, 12079, 14391, 27355, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209133859, 209134450, 14406, 14997, 30578, "entier"], ["github/Python", "psf/requests", "Python", 212051, 212280, 15012, 15241, 28, "entier"], ["github/Java", "google/guava", "Java", 133846226, 133851950, 15256, 20980, 17129, "entier"], ["github/C++", "nlohmann/json", "C++", 104146281, 104149600, 20995, 24314, 14423, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169213593, 169215062, 24329, 25798, 22750, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238898412, 238904328, 25813, 31729, 36817, "entier"], ["github/C", "curl/curl", "C", 91644104, 91647989, 31744, 35629, 12842, "entier"], ["github/PHP", "laravel/framework", "PHP", 182558478, 182559470, 35644, 36636, 25027, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162158328, 162159087, 36651, 37410, 21465, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198359165, 198360036, 37425, 38296, 28169, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136442175, 136443778, 38311, 39914, 17549, "entier"], ["github/Python", "django/django", "Python", 5597455, 5602055, 39929, 44529, 967, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78271417, 78275915, 44544, 49042, 11389, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137665391, 137667083, 49057, 50749, 17979, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44210640, 44217430, 50764, 57554, 6249, "entier"], ["github/Scala", "scala/scala", "Scala", 224226346, 224227016, 57569, 58239, 32968, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192362002, 192364642, 58254, 60894, 26967, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 73940511, 73951618, 60909, 72016, 11010, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141974869, 141975768, 72031, 72930, 18687, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169217108, 169221069, 72945, 76906, 22752, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 179949269, 179956014, 76921, 83666, 24380, "entier"], ["github/C++", "opencv/opencv", "C++", 113101561, 113110263, 83681, 92383, 15126, "entier"], ["github/PHP", "laravel/framework", "PHP", 186601119, 186601492, 92398, 92771, 25921, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35168843, 35179494, 92786, 103437, 4512, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196068707, 196070532, 103452, 105277, 27708, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88006941, 88009278, 105292, 107629, 12236, "entier"], ["github/PHP", "laravel/framework", "PHP", 182521093, 182521308, 107644, 107859, 24986, "entier"], ["github/PHP", "laravel/framework", "PHP", 186508429, 186508808, 107874, 108253, 25890, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43638438, 43641005, 108268, 110835, 6013, "entier"], ["github/C", "curl/curl", "C", 94675676, 94682168, 110850, 117342, 13096, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191015073, 191017324, 117357, 119608, 26780, "entier"], ["github/Go", "gohugoio/hugo", "Go", 91090426, 91092191, 119623, 121388, 12689, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196610133, 196611050, 121403, 122320, 27833, "entier"], ["github/Go", "prometheus/prometheus", "Go", 79717204, 79718127, 122335, 123258, 11518, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175608434, 175608617, 123273, 123456, 23692, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 36025688, 36027420, 123471, 125203, 4650, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 67682599, 67687135, 125218, 129754, 10389, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 180826896, 180827531, 129769, 130404, 24579, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157943757, 157952557, 130419, 139219, 20860, "entier"], ["github/Java", "apache/commons-lang", "Java", 149844083, 149869693, 139234, 164844, 20021, "entier"], ["github/Scala", "scala/scala", "Scala", 222976745, 222999325, 164859, 187439, 32732, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203275805, 203298019, 187454, 209668, 28926, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174918529, 174920368, 209683, 211522, 23613, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 65893509, 65895162, 211537, 213190, 10211, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66237596, 66237791, 213205, 213400, 10252, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65398615, 65398755, 213415, 213555, 10098, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26796462, 26803286, 213570, 220394, 3481, "entier"], ["github/C", "libuv/libuv", "C", 100846538, 100851781, 220409, 225652, 13808, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85675070, 85685967, 225667, 236564, 11997, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178208632, 178210571, 236579, 238518, 24136, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195466003, 195479619, 238533, 252149, 27637, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 122698699, 122725072, 252164, 278537, 15893, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28348785, 28350306, 278552, 280073, 3877, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174842984, 174844494, 280088, 281598, 23568, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136185321, 136186569, 281613, 282861, 17372, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161801386, 161807688, 282876, 289178, 21421, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 23543687, 23547605, 289193, 293111, 3129, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173472766, 173473474, 293126, 293834, 23406, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238398896, 238398983, 293849, 293936, 36304, "entier"], ["github/C", "libuv/libuv", "C", 102117574, 102122094, 293951, 298471, 13992, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 40221788, 40255635, 298486, 332333, 5182, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140983265, 140992989, 332348, 342072, 18502, "entier"], ["github/PHP", "laravel/framework", "PHP", 181778644, 181780121, 342087, 343564, 24801, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235584354, 235588881, 343579, 348106, 35441, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 215058420, 215067180, 348121, 356881, 31889, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18646964, 18649776, 356896, 359708, 2320, "entier"], ["github/Go", "gohugoio/hugo", "Go", 86245562, 86250672, 359723, 364833, 12066, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 17175797, 17220844, 364848, 409895, 2122, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236175571, 236176261, 409910, 410600, 35538, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142238752, 142239218, 410615, 411081, 18803, "entier"], ["github/C", "curl/curl", "C", 92442619, 92444078, 411096, 412555, 12904, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34310367, 34313719, 412570, 415922, 4393, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230223709, 230226085, 415937, 418313, 34088, "entier"], ["github/C++", "opencv/opencv", "C++", 116493033, 116495150, 418328, 420445, 15301, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139460648, 139466601, 420460, 426413, 18339, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172660985, 172668393, 426428, 433836, 23283, "entier"], ["github/Go", "prometheus/prometheus", "Go", 77636940, 77639322, 433851, 436233, 11322, "entier"], ["github/Scala", "scala/scala", "Scala", 224215426, 224216094, 436248, 436916, 32952, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19049451, 19051901, 436931, 439381, 2549, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136515938, 136517108, 439396, 440566, 17614, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234288602, 234292989, 440581, 444968, 35159, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198228655, 198242888, 444983, 459216, 28144, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213175601, 213183361, 459231, 466991, 31533, "entier"], ["github/Java", "apache/commons-lang", "Java", 149526296, 149528082, 467006, 468792, 20008, "entier"], ["github/Scala", "scala/scala", "Scala", 219219852, 219228458, 468807, 477413, 32394, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143776379, 143778726, 477428, 479775, 19112, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136407235, 136408366, 479790, 480921, 17526, "entier"], ["github/Go", "prometheus/prometheus", "Go", 83589982, 83597313, 480936, 488267, 11713, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159529307, 159549018, 488282, 507993, 21149, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175683091, 175683488, 508008, 508405, 23709, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121952986, 121972158, 508420, 527592, 15833, "entier"], ["github/Java", "google/guava", "Java", 132180985, 132185854, 527607, 532476, 16912, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205202849, 205204315, 532491, 533957, 29560, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172066805, 172067922, 533972, 535089, 23177, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 74368728, 74414961, 535104, 581337, 11038, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171937836, 171937957, 581352, 581473, 23124, "entier"], ["github/PHP", "laravel/framework", "PHP", 184707012, 184707701, 581488, 582177, 25409, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51497605, 51499643, 582192, 584230, 7531, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171975770, 171977055, 584245, 585530, 23156, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231419535, 231427303, 585545, 593313, 34489, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42732220, 42734023, 593328, 595131, 5592, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178909185, 178909818, 595146, 595779, 24231, "entier"], ["github/PHP", "laravel/framework", "PHP", 185888036, 185894255, 595794, 602013, 25713, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50983635, 50984181, 602028, 602574, 7235, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50986202, 50986691, 602589, 603078, 7239, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51783035, 51783251, 603093, 603309, 7654, "entier"], ["github/C", "curl/curl", "C", 94826949, 94849481, 603324, 625856, 13108, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44620447, 44622483, 625871, 627907, 6361, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174875050, 174877814, 627922, 630686, 23578, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205256969, 205267836, 630701, 641568, 29572, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88463396, 88475488, 641583, 653675, 12320, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 49203847, 49204586, 653690, 654429, 7127, "entier"], ["github/PHP", "laravel/framework", "PHP", 185767134, 185767711, 654444, 655021, 25681, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56047489, 56049107, 655036, 656654, 8681, "entier"], ["github/C++", "opencv/opencv", "C++", 112994403, 113006944, 656669, 669210, 15120, "entier"], ["github/Java", "google/guava", "Java", 133645361, 133679575, 669225, 703439, 17112, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171567247, 171570072, 703454, 706279, 22962, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194599677, 194610162, 706294, 716779, 27418, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14529319, 14535053, 716794, 722528, 2011, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164134092, 164141529, 722543, 729980, 21860, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206937753, 206938733, 729995, 730975, 30034, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89579669, 89581523, 730990, 732844, 12501, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210363514, 210363701, 732859, 733046, 30946, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 122643710, 122644623, 733061, 733974, 15886, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46902919, 46916515, 733989, 747585, 6923, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 127386517, 127389538, 747600, 750621, 16263, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171677531, 171680699, 750636, 753804, 22993, "entier"], ["github/Python", "encode/httpx", "Python", 18012180, 18014119, 753819, 755758, 2172, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120532267, 120533868, 755773, 757374, 15650, "entier"], ["github/Python", "django/django", "Python", 5005817, 5006091, 757389, 757663, 866, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172037705, 172037869, 757678, 757842, 23164, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237595157, 237629710, 757857, 792410, 35722, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175601109, 175601585, 792425, 792901, 23684, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159329531, 159333976, 792916, 797361, 21114, "entier"], ["github/PHP", "laravel/framework", "PHP", 184927106, 184934255, 797376, 804525, 25447, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19592635, 19649611, 804540, 861516, 2757, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56182162, 56183448, 861531, 862817, 8724, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177462477, 177463472, 862832, 863827, 23991, "entier"], ["github/Java", "apache/commons-lang", "Java", 151640056, 151643698, 863842, 867484, 20203, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52161674, 52161707, 867499, 867532, 7791, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59109280, 59110486, 867547, 868753, 9348, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51317370, 51317930, 868768, 869328, 7429, "entier"], ["github/C++", "opencv/opencv", "C++", 112866992, 112877278, 869343, 879629, 15111, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43625399, 43626342, 879644, 880587, 6001, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65378588, 65379837, 880602, 881851, 10041, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139201510, 139203654, 881866, 884010, 18285, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63503599, 63504211, 884025, 884637, 9858, "entier"], ["github/Java", "google/guava", "Java", 135489116, 135490922, 884652, 886458, 17277, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172889430, 172892225, 886473, 889268, 23325, "entier"], ["github/Python", "django/django", "Python", 8452730, 8467848, 889283, 904401, 1344, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159240988, 159245536, 904416, 908964, 21097, "entier"], ["github/Java", "apache/commons-lang", "Java", 154603637, 154608710, 908979, 914052, 20419, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90686073, 90707504, 914067, 935498, 12640, "entier"], ["github/C++", "google/leveldb", "C++", 110672546, 110675610, 935513, 938577, 14858, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 64770508, 64777666, 938592, 945750, 9986, "entier"], ["github/C", "curl/curl", "C", 97132267, 97142360, 945765, 955858, 13232, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120310376, 120311575, 955873, 957072, 15628, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178308391, 178310113, 957087, 958809, 24147, "entier"], ["github/Java", "google/guava", "Java", 130504517, 130506039, 958824, 960346, 16725, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163531474, 163533173, 960361, 962060, 21730, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136818577, 136819444, 962075, 962942, 17774, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121494620, 121496984, 962957, 965321, 15740, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139045875, 139047136, 965336, 966597, 18262, "entier"], ["github/C++", "opencv/opencv", "C++", 116509822, 116511670, 966612, 968460, 15309, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168199517, 168201466, 968475, 970424, 22412, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 181308255, 181310073, 970439, 972257, 24673, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168672948, 168674490, 972272, 973814, 22663, "entier"], ["github/Python", "django/django", "Python", 2651445, 2654613, 973829, 976997, 549, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238344618, 238344838, 977012, 977232, 36104, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120907952, 120914454, 977247, 983749, 15678, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173545777, 173547104, 983764, 985091, 23423, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165521510, 165524622, 985106, 988218, 22059, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199700230, 199727814, 988233, 1015817, 28248, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176164033, 176165357, 1015832, 1017156, 23790, "entier"], ["github/C", "curl/curl", "C", 97881708, 97885071, 1017171, 1020534, 13329, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 127135181, 127137662, 1020549, 1023030, 16226, "entier"], ["github/Java", "google/guava", "Java", 131278735, 131305797, 1023045, 1050107, 16843, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216968278, 216976497, 1050122, 1058341, 32177, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 62486554, 62504413, 1058356, 1076215, 9708, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 166007183, 166010722, 1076230, 1079769, 22211, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228767351, 228783035, 1079784, 1095468, 33688, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157875011, 157876807, 1095483, 1097279, 20843, "entier"], ["github/C++", "opencv/opencv", "C++", 112894599, 112910108, 1097294, 1112803, 15113, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233904116, 233906770, 1112818, 1115472, 34963, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238426019, 238426044, 1115487, 1115512, 36539, "entier"], ["github/Java", "google/guava", "Java", 133359558, 133361093, 1115527, 1117062, 17093, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69262469, 69262794, 1117077, 1117402, 10486, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141508737, 141511571, 1117417, 1120251, 18560, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35732889, 35735083, 1120266, 1122460, 4609, "entier"], ["github/Scala", "playframework/playframework", "Scala", 225916687, 225923014, 1122475, 1128802, 33216, "entier"], ["github/C", "curl/curl", "C", 92760476, 92775977, 1128817, 1144318, 12973, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 27067888, 27067947, 1144333, 1144392, 3563, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27296860, 27296892, 1144407, 1144439, 3616, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141850966, 141853798, 1144454, 1147286, 18623, "entier"], ["github/Python", "django/django", "Python", 8496039, 8527562, 1147301, 1178824, 1351, "entier"], ["github/C++", "opencv/opencv", "C++", 111039661, 111042492, 1178839, 1181670, 14978, "entier"], ["github/PHP", "laravel/framework", "PHP", 187668010, 187672916, 1181685, 1186591, 26167, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58968750, 58977053, 1186606, 1194909, 9324, "entier"], ["github/C++", "opencv/opencv", "C++", 111270899, 111275474, 1194924, 1199499, 14988, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238579661, 238583202, 1199514, 1203055, 36733, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199900092, 199901088, 1203070, 1204066, 28267, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34420569, 34432469, 1204081, 1215981, 4415, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193435305, 193436787, 1215996, 1217478, 27220, "entier"], ["github/C++", "google/leveldb", "C++", 110664072, 110667185, 1217493, 1220606, 14856, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161162932, 161185091, 1220621, 1242780, 21362, "entier"], ["github/Scala", "scala/scala", "Scala", 224978918, 224982870, 1242795, 1246747, 33118, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58687970, 58690595, 1246762, 1249387, 9261, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190729545, 190731622, 1249402, 1251479, 26699, "entier"], ["github/C++", "google/leveldb", "C++", 110614235, 110617256, 1251494, 1254515, 14842, "entier"], ["github/C++", "nlohmann/json", "C++", 104049634, 104050575, 1254530, 1255471, 14300, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61695501, 61700480, 1255486, 1260465, 9636, "entier"], ["github/C++", "opencv/opencv", "C++", 112280919, 112282150, 1260480, 1261711, 15050, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230723497, 230730296, 1261726, 1268525, 34328, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18976102, 18976162, 1268540, 1268600, 2370, "entier"], ["github/C++", "opencv/opencv", "C++", 116667446, 116667810, 1268615, 1268979, 15330, "entier"], ["github/C++", "nlohmann/json", "C++", 104175696, 104176093, 1268994, 1269391, 14462, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27641335, 27642223, 1269406, 1270294, 3722, "entier"], ["github/Go", "gohugoio/hugo", "Go", 86886826, 86931804, 1270309, 1315287, 12127, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141126205, 141164188, 1315302, 1353285, 18512, "entier"], ["github/C", "curl/curl", "C", 98622548, 98626277, 1353300, 1357029, 13522, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120292658, 120295529, 1357044, 1359915, 15621, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21611363, 21613081, 1359930, 1361648, 2928, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198697558, 198709045, 1361663, 1373150, 28204, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19080011, 19080091, 1373165, 1373245, 2610, "entier"], ["github/C++", "nlohmann/json", "C++", 104002009, 104002387, 1373260, 1373638, 14243, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18138890, 18141934, 1373653, 1376697, 2227, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231038668, 231042145, 1376712, 1380189, 34416, "entier"], ["github/Python", "django/django", "Python", 7674117, 7676152, 1380204, 1382239, 1280, "entier"], ["github/Scala", "scala/scala", "Scala", 218594897, 218596269, 1382254, 1383626, 32345, "entier"], ["github/Python", "django/django", "Python", 9187978, 9188416, 1383641, 1384079, 1431, "entier"], ["github/C", "libuv/libuv", "C", 99661788, 99665729, 1384094, 1388035, 13721, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14462737, 14463454, 1388050, 1388767, 1998, "entier"], ["github/Python", "django/django", "Python", 2149133, 2150139, 1388782, 1389788, 417, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189927207, 189928355, 1389803, 1390951, 26549, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 215516604, 215518704, 1390966, 1393066, 31917, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168624935, 168626254, 1393081, 1394400, 22636, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235078274, 235083818, 1394415, 1399959, 35312, "entier"], ["github/PHP", "laravel/framework", "PHP", 182533748, 182534458, 1399974, 1400684, 24999, "entier"], ["github/PHP", "laravel/framework", "PHP", 183317849, 183319494, 1400699, 1402344, 25232, "entier"], ["github/PHP", "laravel/framework", "PHP", 182122641, 182123328, 1402359, 1403046, 24830, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229966488, 229967573, 1403061, 1404146, 33982, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159757919, 159762954, 1404161, 1409196, 21165, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66715934, 66738777, 1409211, 1432054, 10333, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190513430, 190515315, 1432069, 1433954, 26643, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33903388, 33918717, 1433969, 1449298, 4358, "entier"], ["github/PHP", "laravel/framework", "PHP", 187014505, 187014801, 1449313, 1449609, 26032, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143548439, 143551517, 1449624, 1452702, 19050, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233651361, 233652766, 1452717, 1454122, 34880, "entier"], ["github/C", "curl/curl", "C", 93874439, 93881785, 1454137, 1461483, 13048, "entier"], ["github/Python", "django/django", "Python", 1460427, 1473429, 1461498, 1474500, 253, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190354858, 190357105, 1474515, 1476762, 26614, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235343335, 235352077, 1476777, 1485519, 35385, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170380200, 170381900, 1485534, 1487234, 22827, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168388781, 168390369, 1487249, 1488837, 22502, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215976152, 215977283, 1488852, 1489983, 32005, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136763009, 136777103, 1489998, 1504092, 17769, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231340493, 231341470, 1504107, 1505084, 34470, "entier"], ["github/Scala", "playframework/playframework", "Scala", 232753622, 232754023, 1505099, 1505500, 34697, "entier"], ["github/C", "curl/curl", "C", 98566261, 98567958, 1505515, 1507212, 13502, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164267867, 164270268, 1507227, 1509628, 21879, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 23865864, 23868050, 1509643, 1511829, 3145, "entier"], ["github/C++", "nlohmann/json", "C++", 107589444, 107643286, 1511844, 1565686, 14649, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157231170, 157232380, 1565701, 1566911, 20678, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18113005, 18115268, 1566926, 1569189, 2206, "entier"], ["github/C", "curl/curl", "C", 91382376, 91384594, 1569204, 1571422, 12763, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235635472, 235642718, 1571437, 1578683, 35458, "entier"], ["github/Java", "square/okhttp", "Java", 146691892, 146693012, 1578698, 1579818, 19703, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 64596978, 64597772, 1579833, 1580627, 9975, "entier"], ["github/Python", "django/django", "Python", 6145860, 6152234, 1580642, 1587016, 1058, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19010528, 19010577, 1587031, 1587080, 2455, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136140347, 136141279, 1587095, 1588027, 17335, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162584642, 162586353, 1588042, 1589753, 21562, "entier"], ["github/PHP", "laravel/framework", "PHP", 186317703, 186335794, 1589768, 1607859, 25835, "entier"], ["github/Go", "prometheus/prometheus", "Go", 83986603, 83987361, 1607874, 1608632, 11732, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234119564, 234119768, 1608647, 1608851, 35091, "entier"], ["github/Java", "google/guava", "Java", 130987825, 130993142, 1608866, 1614183, 16807, "entier"], ["github/Scala", "scala/scala", "Scala", 224244802, 224245476, 1614198, 1614872, 32995, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157122787, 157126332, 1614887, 1618432, 20656, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144156313, 144159241, 1618447, 1621375, 19183, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228755142, 228758943, 1621390, 1625191, 33685, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9516287, 9521838, 1625206, 1630757, 1508, "entier"], ["github/Java", "square/okhttp", "Java", 144753760, 144754306, 1630772, 1631318, 19361, "entier"], ["github/C", "curl/curl", "C", 91179644, 91187915, 1631333, 1639604, 12719, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159482419, 159484170, 1639619, 1641370, 21127, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142617453, 142619612, 1641385, 1643544, 18880, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172474343, 172536147, 1643559, 1705363, 23259, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69463591, 69477683, 1705378, 1719470, 10516, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139126248, 139127982, 1719485, 1721219, 18274, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238563632, 238567564, 1721234, 1725166, 36731, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140501811, 140504948, 1725181, 1728318, 18484, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192210215, 192211300, 1728333, 1729418, 26939, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226762786, 226762996, 1729433, 1729643, 33356, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238411613, 238412125, 1729658, 1730170, 36366, "entier"], ["github/PHP", "laravel/framework", "PHP", 187020107, 187020472, 1730185, 1730550, 26038, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207186822, 207321808, 1730565, 1865551, 30115, "entier"], ["github/Java", "apache/commons-lang", "Java", 150104989, 150106259, 1865566, 1866836, 20037, "entier"], ["github/Scala", "playframework/playframework", "Scala", 232756547, 232757769, 1866851, 1868073, 34700, "entier"], ["github/PHP", "laravel/framework", "PHP", 185012348, 185014014, 1868088, 1869754, 25468, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11405313, 11411596, 1869769, 1876052, 1809, "entier"], ["github/Java", "apache/commons-lang", "Java", 150815239, 150817132, 1876067, 1877960, 20152, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234147496, 234148692, 1877975, 1879171, 35115, "entier"], ["github/C", "madler/zlib", "C", 102193367, 102194321, 1879186, 1880140, 14008, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71619870, 71619923, 1880155, 1880208, 10870, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140230050, 140235336, 1880223, 1885509, 18463, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215770856, 215776299, 1885524, 1890967, 31954, "entier"], ["github/Python", "django/django", "Python", 2320947, 2321161, 1890982, 1891196, 471, "entier"], ["github/Python", "django/django", "Python", 7442961, 7443115, 1891211, 1891365, 1233, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229875179, 229887269, 1891380, 1903470, 33973, "entier"], ["github/Java", "google/guava", "Java", 129622425, 129626917, 1903485, 1907977, 16633, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 50474203, 50657570, 1907992, 2091359, 7165, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158311831, 158332064, 2091374, 2111607, 20947, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61069698, 61083305, 2111622, 2125229, 9566, "entier"], ["github/C++", "nlohmann/json", "C++", 104882963, 104891153, 2125244, 2133434, 14492, "entier"], ["github/Java", "google/guava", "Java", 133212785, 133224921, 2133449, 2145585, 17066, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192945021, 192966990, 2145600, 2167569, 27061, "entier"], ["github/C", "curl/curl", "C", 94571911, 94588324, 2167584, 2183997, 13093, "entier"], ["github/C++", "opencv/opencv", "C++", 117008252, 117011319, 2184012, 2187079, 15410, "entier"], ["github/Java", "square/okhttp", "Java", 148411044, 148412514, 2187094, 2188564, 19853, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234183412, 234184066, 2188579, 2189233, 35137, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71384022, 71384768, 2189248, 2189994, 10676, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142831938, 142833926, 2190009, 2191997, 18924, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136205454, 136206710, 2192012, 2193268, 17389, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138869418, 138872504, 2193283, 2196369, 18230, "entier"], ["github/C++", "opencv/opencv", "C++", 110936753, 110946687, 2196384, 2206318, 14915, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143510796, 143514955, 2206333, 2210492, 19042, "entier"], ["github/Scala", "scala/scala", "Scala", 219503599, 219529255, 2210507, 2236163, 32420, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163438816, 163442623, 2236178, 2239985, 21707, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136619912, 136620883, 2240000, 2240971, 17688, "entier"], ["github/Java", "google/guava", "Java", 135039233, 135040304, 2240986, 2242057, 17220, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191087812, 191092937, 2242072, 2247197, 26799, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168724005, 168725285, 2247212, 2248492, 22691, "entier"], ["github/C", "curl/curl", "C", 97770157, 97771564, 2248507, 2249914, 13307, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233973046, 233974005, 2249929, 2250888, 34997, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 214514263, 214516702, 2250903, 2253342, 31848, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11780050, 11829247, 2253357, 2302554, 1831, "entier"], ["github/C", "curl/curl", "C", 93083974, 93085682, 2302569, 2304277, 12998, "entier"], ["github/Java", "google/guava", "Java", 128896575, 128914628, 2304292, 2322345, 16548, "entier"], ["github/C", "curl/curl", "C", 92674547, 92675906, 2322360, 2323719, 12954, "entier"], ["github/PHP", "laravel/framework", "PHP", 186476457, 186486224, 2323734, 2333501, 25886, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234882424, 234883321, 2333516, 2334413, 35262, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19753214, 19847288, 2334428, 2428502, 2767, "entier"], ["github/C", "curl/curl", "C", 98355861, 98360558, 2428517, 2433214, 13424, "entier"], ["github/Java", "square/okhttp", "Java", 144646489, 144648614, 2433229, 2435354, 19322, "entier"], ["github/Scala", "scala/scala", "Scala", 221328028, 221336672, 2435369, 2444013, 32536, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78504363, 78590095, 2444028, 2529760, 11434, "entier"], ["github/Java", "google/guava", "Java", 132735740, 132740324, 2529775, 2534359, 17004, "entier"], ["github/C", "libuv/libuv", "C", 99546808, 99547319, 2534374, 2534885, 13679, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 167877811, 167898724, 2534900, 2555813, 22330, "entier"], ["github/Java", "google/guava", "Java", 133816613, 133819482, 2555828, 2558697, 17126, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198455380, 198463723, 2558712, 2567055, 28176, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233971756, 233972459, 2567070, 2567773, 34995, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230833098, 230834164, 2567788, 2568854, 34371, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143591927, 143592218, 2568869, 2569160, 19064, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 67762008, 67813790, 2569175, 2620957, 10402, "entier"], ["github/C", "curl/curl", "C", 94349745, 94353558, 2620972, 2624785, 13073, "entier"], ["github/Java", "google/guava", "Java", 129633662, 129636183, 2624800, 2627321, 16637, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238162729, 238165632, 2627336, 2630239, 35821, "entier"], ["github/Java", "google/guava", "Java", 135730182, 135735239, 2630254, 2635311, 17305, "entier"], ["github/PHP", "laravel/framework", "PHP", 185343972, 185344214, 2635326, 2635568, 25565, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226588073, 226589522, 2635583, 2637032, 33321, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192445841, 192446551, 2637047, 2637757, 26991, "entier"], ["github/Scala", "scala/scala", "Scala", 223472590, 223473698, 2637772, 2638880, 32771, "entier"], ["github/C", "curl/curl", "C", 98485239, 98487543, 2638895, 2641199, 13474, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136536050, 136536833, 2641214, 2641997, 17632, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138461517, 138463620, 2642012, 2644115, 18162, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237591911, 237595142, 2644130, 2647361, 35721, "entier"], ["github/C++", "opencv/opencv", "C++", 117522161, 117587053, 2647376, 2712268, 15472, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141999998, 142000120, 2712283, 2712405, 18712, "entier"], ["github/Java", "apache/commons-lang", "Java", 150655750, 150657707, 2712420, 2714377, 20099, "entier"], ["github/C", "curl/curl", "C", 96901577, 96903237, 2714392, 2716052, 13220, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231688147, 231688689, 2716067, 2716609, 34540, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238424067, 238424112, 2716624, 2716669, 36506, "entier"], ["github/Java", "apache/commons-lang", "Java", 154667976, 154669291, 2716684, 2717999, 20427, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142923619, 142925705, 2718014, 2720100, 18941, "entier"], ["github/PHP", "laravel/framework", "PHP", 183437046, 183447924, 2720115, 2730993, 25247, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177285192, 177285384, 2731008, 2731200, 23924, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236413569, 236418762, 2731215, 2736408, 35580, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136369132, 136370779, 2736423, 2738070, 17500, "entier"], ["github/C", "libuv/libuv", "C", 100826812, 100830088, 2738085, 2741361, 13805, "entier"], ["github/Python", "django/django", "Python", 3505145, 3505355, 2741376, 2741586, 642, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11059947, 11062436, 2741601, 2744090, 1778, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159921417, 159926418, 2744105, 2749106, 21174, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174276725, 174281240, 2749121, 2753636, 23485, "entier"], ["github/Java", "apache/commons-lang", "Java", 152818047, 152831300, 2753651, 2766904, 20278, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237552676, 237558621, 2766919, 2772864, 35706, "entier"], ["github/C", "curl/curl", "C", 94890057, 94893243, 2772879, 2776065, 13114, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168459283, 168460745, 2776080, 2777542, 22543, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157781658, 157782085, 2777557, 2777984, 20811, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229310140, 229311066, 2777999, 2778925, 33789, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229733499, 229733738, 2778940, 2779179, 33942, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228064443, 228064798, 2779194, 2779549, 33562, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238321752, 238321945, 2779564, 2779757, 36047, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195724935, 195734401, 2779772, 2789238, 27660, "entier"], ["github/Python", "django/django", "Python", 7683629, 7693999, 2789253, 2799623, 1283, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230139223, 230139777, 2799638, 2800192, 34016, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171792755, 171793737, 2800207, 2801189, 23038, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237989363, 237991278, 2801204, 2803119, 35785, "entier"], ["github/C", "curl/curl", "C", 97299763, 97304049, 2803134, 2807420, 13262, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173207941, 173209801, 2807435, 2809295, 23364, "entier"], ["github/Java", "apache/commons-lang", "Java", 154549950, 154561803, 2809310, 2821163, 20412, "entier"], ["github/Python", "django/django", "Python", 992575, 993886, 2821178, 2822489, 189, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172328008, 172329961, 2822504, 2824457, 23239, "entier"], ["github/C", "libuv/libuv", "C", 101756833, 101759289, 2824472, 2826928, 13929, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71527205, 71528233, 2826943, 2827971, 10758, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65388360, 65388853, 2827986, 2828479, 10063, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65388868, 65389337, 2828494, 2828963, 10064, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233991225, 233994191, 2828978, 2831944, 35006, "entier"], ["github/PHP", "laravel/framework", "PHP", 188016096, 188028002, 2831959, 2843865, 26211, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164012321, 164032511, 2843880, 2864070, 21846, "entier"], ["github/Scala", "scala/scala", "Scala", 223176748, 223198183, 2864085, 2885520, 32741, "entier"], ["github/C++", "nlohmann/json", "C++", 105660392, 105661121, 2885535, 2886264, 14552, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121928378, 121929318, 2886279, 2887219, 15830, "entier"], ["github/C++", "nlohmann/json", "C++", 104154018, 104154894, 2887234, 2888110, 14427, "entier"], ["github/C", "curl/curl", "C", 92703590, 92711592, 2888125, 2896127, 12961, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 73871076, 73884575, 2896142, 2909641, 10999, "entier"], ["github/Python", "django/django", "Python", 3361820, 3380564, 2909656, 2928400, 630, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141289438, 141320992, 2928415, 2959969, 18531, "entier"], ["github/PHP", "laravel/framework", "PHP", 185609051, 185612126, 2959984, 2963059, 25654, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19462494, 19462843, 2963074, 2963423, 2730, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 28050324, 28051041, 2963438, 2964155, 3819, "entier"], ["github/Scala", "playframework/playframework", "Scala", 232619491, 232621605, 2964170, 2966284, 34673, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18991381, 18991930, 2966299, 2966848, 2402, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71508584, 71508948, 2966863, 2967227, 10738, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25656380, 25656989, 2967242, 2967851, 3362, "entier"], ["github/PHP", "laravel/framework", "PHP", 183718811, 183725124, 2967866, 2974179, 25303, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209734610, 209734919, 2974194, 2974503, 30708, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 56964153, 56966277, 2974518, 2976642, 9093, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168150971, 168152436, 2976657, 2978122, 22380, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163739944, 163740363, 2978137, 2978556, 21779, "entier"], ["github/Python", "django/django", "Python", 6624979, 6626827, 2978571, 2980419, 1154, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26622317, 26630430, 2980434, 2988547, 3454, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89552337, 89555687, 2988562, 2991912, 12496, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229123190, 229133145, 2991927, 3001882, 33744, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175974944, 175995285, 3001897, 3022238, 23766, "entier"], ["github/PHP", "laravel/framework", "PHP", 184363499, 184366903, 3022253, 3025657, 25353, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209708355, 209715635, 3025672, 3032952, 30705, "entier"], ["github/PHP", "laravel/framework", "PHP", 182226256, 182226609, 3032967, 3033320, 24869, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85347309, 85348733, 3033335, 3034759, 11928, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54994390, 54995049, 3034774, 3035433, 8455, "entier"], ["github/PHP", "laravel/framework", "PHP", 185212630, 185213751, 3035448, 3036569, 25528, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85588521, 85588547, 3036584, 3036610, 11972, "entier"], ["github/Python", "django/django", "Python", 8747609, 8754483, 3036625, 3043499, 1374, "entier"], ["github/Go", "prometheus/prometheus", "Go", 83989937, 83990938, 3043514, 3044515, 11735, "entier"], ["github/Go", "prometheus/prometheus", "Go", 84021846, 84023282, 3044530, 3045966, 11749, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213325437, 213325932, 3045981, 3046476, 31561, "entier"], ["github/Java", "google/guava", "Java", 132325401, 132341247, 3046491, 3062337, 16940, "entier"], ["github/PHP", "laravel/framework", "PHP", 188113917, 188120018, 3062352, 3068453, 26234, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21507992, 21514126, 3068468, 3074602, 2916, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233632340, 233632721, 3074617, 3074998, 34869, "entier"], ["github/Python", "django/django", "Python", 958181, 958910, 3075013, 3075742, 165, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 167464059, 167481042, 3075757, 3092740, 22311, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10810005, 10812075, 3092755, 3094825, 1733, "entier"], ["github/PHP", "laravel/framework", "PHP", 187689257, 187692669, 3094840, 3098252, 26170, "entier"], ["github/Python", "django/django", "Python", 1011736, 1015666, 3098267, 3102197, 206, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89568154, 89579654, 3102212, 3113712, 12500, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 40441710, 40462656, 3113727, 3134673, 5194, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198339182, 198339700, 3134688, 3135206, 28159, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213995495, 214007471, 3135221, 3147197, 31735, "entier"], ["github/Java", "square/okhttp", "Java", 148774186, 148782614, 3147212, 3155640, 19880, "entier"], ["github/PHP", "laravel/framework", "PHP", 184389003, 184389879, 3155655, 3156531, 25360, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233698533, 233699032, 3156546, 3157045, 34908, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196841239, 196841939, 3157060, 3157760, 27861, "entier"], ["github/C++", "opencv/opencv", "C++", 111136907, 111209459, 3157775, 3230327, 14986, "entier"], ["github/Python", "django/django", "Python", 3558764, 3560035, 3230342, 3231613, 646, "entier"], ["github/PHP", "laravel/framework", "PHP", 186465707, 186466128, 3231628, 3232049, 25871, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 214593774, 214615068, 3232064, 3253358, 31858, "entier"], ["github/PHP", "laravel/framework", "PHP", 186208466, 186210954, 3253373, 3255861, 25792, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136691207, 136692727, 3255876, 3257396, 17741, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9596069, 9598827, 3257411, 3260169, 1533, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14349800, 14351156, 3260184, 3261540, 1976, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196509738, 196513380, 3261555, 3265197, 27815, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69550073, 69596031, 3265212, 3311170, 10526, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85704286, 85708042, 3311185, 3314941, 12003, "entier"], ["github/Java", "square/okhttp", "Java", 146469536, 146482008, 3314956, 3327428, 19677, "entier"], ["github/Scala", "scala/scala", "Scala", 219286430, 219327786, 3327443, 3368799, 32407, "entier"], ["github/PHP", "laravel/framework", "PHP", 189259414, 189262378, 3368814, 3371778, 26436, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233913885, 233914460, 3371793, 3372368, 34965, "entier"], ["github/Go", "prometheus/prometheus", "Go", 79701742, 79702496, 3372383, 3373137, 11506, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180513323, 180518840, 3373152, 3378669, 24504, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38961475, 38965463, 3378684, 3382672, 5048, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89344384, 89345506, 3382687, 3383809, 12461, "entier"], ["github/Java", "square/okhttp", "Java", 145519783, 145519864, 3383824, 3383905, 19538, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 32358013, 32389233, 3383920, 3415140, 4190, "entier"], ["github/Java", "apache/commons-lang", "Java", 151596626, 151598625, 3415155, 3417154, 20197, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56469353, 56469698, 3417169, 3417514, 9036, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51313475, 51314019, 3417529, 3418073, 7419, "entier"], ["github/Go", "prometheus/prometheus", "Go", 84446124, 84448709, 3418088, 3420673, 11762, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136898761, 136899773, 3420688, 3421700, 17811, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46832570, 46833283, 3421715, 3422428, 6898, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11044881, 11059932, 3422443, 3437494, 1777, "entier"], ["github/Java", "square/okhttp", "Java", 145128351, 145128887, 3437509, 3438045, 19451, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205528192, 205539393, 3438060, 3449261, 29653, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90551230, 90552657, 3449276, 3450703, 12610, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233683635, 233683916, 3450718, 3450999, 34899, "entier"], ["github/Go", "prometheus/prometheus", "Go", 79698714, 79699465, 3451014, 3451765, 11502, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139083763, 139093009, 3451780, 3461026, 18267, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 42370563, 42382399, 3461041, 3472877, 5429, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141506031, 141508722, 3472892, 3475583, 18559, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180206293, 180213202, 3475598, 3482507, 24440, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138903650, 138903830, 3482522, 3482702, 18235, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136349492, 136350595, 3482717, 3483820, 17484, "entier"], ["github/Java", "apache/commons-lang", "Java", 154781326, 154783092, 3483835, 3485601, 20471, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138133391, 138134676, 3485616, 3486901, 18087, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206299733, 206304189, 3486916, 3491372, 29911, "entier"], ["github/Python", "django/django", "Python", 1836967, 1844267, 3491387, 3498687, 355, "entier"], ["github/Go", "gohugoio/hugo", "Go", 87358474, 87372689, 3498702, 3512917, 12172, "entier"], ["github/Java", "apache/commons-lang", "Java", 154934570, 154937126, 3512932, 3515488, 20486, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41932473, 41933797, 3515503, 3516827, 5355, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38239379, 38240141, 3516842, 3517604, 4970, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144105791, 144107062, 3517619, 3518890, 19166, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56009789, 56010190, 3518905, 3519306, 8658, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238442042, 238442204, 3519321, 3519483, 36619, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55991114, 55991508, 3519498, 3519892, 8643, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19115645, 19115695, 3519907, 3519957, 2654, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141592597, 141594301, 3519972, 3521676, 18579, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56269451, 56269750, 3521691, 3521990, 8809, "entier"], ["github/Scala", "playframework/playframework", "Scala", 233325290, 233327837, 3522005, 3524552, 34773, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52993569, 52996112, 3524567, 3527110, 8093, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18479416, 18482952, 3527125, 3530661, 2286, "entier"], ["github/C++", "nlohmann/json", "C++", 103975510, 103976365, 3530676, 3531531, 14210, "entier"], ["github/Java", "google/guava", "Java", 133075328, 133079438, 3531546, 3535656, 17048, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200001990, 200005230, 3535671, 3538911, 28307, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10191425, 10193514, 3538926, 3541015, 1636, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51167215, 51167570, 3541030, 3541385, 7289, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50862112, 50862809, 3541400, 3542097, 7181, "entier"], ["github/Python", "django/django", "Python", 907612, 908513, 3542112, 3543013, 119, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191289766, 191332064, 3543028, 3585326, 26819, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207920438, 207920787, 3585341, 3585690, 30274, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233493741, 233495471, 3585705, 3587435, 34806, "entier"], ["github/Java", "apache/commons-lang", "Java", 154727204, 154730652, 3587450, 3590898, 20450, "entier"], ["github/Python", "django/django", "Python", 5503195, 5503471, 3590913, 3591189, 949, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25147464, 25149911, 3591204, 3593651, 3268, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204826400, 204826912, 3593666, 3594178, 29360, "entier"], ["github/Python", "django/django", "Python", 1623775, 1624621, 3594193, 3595039, 285, "entier"], ["github/Python", "django/django", "Python", 6325803, 6326089, 3595054, 3595340, 1078, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211425350, 211426583, 3595355, 3596588, 31216, "entier"], ["github/C++", "opencv/opencv", "C++", 114393986, 114404160, 3596603, 3606777, 15187, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141822393, 141824954, 3606792, 3609353, 18616, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33642046, 33643211, 3609368, 3610533, 4319, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44011606, 44019713, 3610548, 3618655, 6195, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136356545, 136357474, 3618670, 3619599, 17490, "entier"], ["github/Python", "django/django", "Python", 4348661, 4352528, 3619614, 3623481, 760, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21908821, 21910547, 3623496, 3625222, 3018, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88306452, 88310508, 3625237, 3629293, 12292, "entier"], ["github/Java", "apache/commons-lang", "Java", 154006906, 154009638, 3629308, 3632040, 20337, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 74317894, 74330719, 3632055, 3644880, 11033, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18125306, 18125421, 3644895, 3645010, 2214, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137369967, 137371461, 3645025, 3646519, 17909, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179332772, 179343035, 3646534, 3656797, 24277, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56278404, 56280173, 3656812, 3658581, 8818, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209432260, 209440828, 3658596, 3667164, 30627, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51284190, 51284603, 3667179, 3667592, 7354, "entier"], ["github/C", "curl/curl", "C", 94588339, 94673948, 3667607, 3753216, 13094, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43535217, 43536416, 3753231, 3754430, 5899, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139241318, 139251264, 3754445, 3764391, 18294, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51302049, 51302441, 3764406, 3764798, 7391, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52797111, 52797653, 3764813, 3765355, 8021, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56333845, 56335198, 3765370, 3766723, 8896, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 199955757, 199958241, 3766738, 3769222, 28284, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47654219, 47664745, 3769237, 3779763, 7020, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 201181865, 201184805, 3779778, 3782718, 28659, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 72058083, 72074153, 3782733, 3798803, 10916, "entier"], ["github/Scala", "scala/scala", "Scala", 218645332, 218697042, 3798818, 3850528, 32351, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78883200, 78907866, 3850543, 3875209, 11444, "entier"], ["github/PHP", "laravel/framework", "PHP", 188544195, 188544765, 3875224, 3875794, 26309, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234013757, 234014742, 3875809, 3876794, 35018, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172046272, 172052875, 3876809, 3883412, 23171, "entier"], ["github/Java", "google/guava", "Java", 132025527, 132056252, 3883427, 3914152, 16892, "entier"], ["github/PHP", "laravel/framework", "PHP", 188562921, 188565128, 3914167, 3916374, 26329, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53246123, 53249519, 3916389, 3919785, 8182, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 31571164, 31608531, 3919800, 3957167, 4146, "entier"], ["github/PHP", "laravel/framework", "PHP", 182802956, 182804450, 3957182, 3958676, 25139, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193085393, 193085815, 3958691, 3959113, 27127, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65404899, 65405028, 3959128, 3959257, 10136, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61449247, 61450473, 3959272, 3960498, 9603, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195188934, 195195402, 3960513, 3966981, 27566, "entier"], ["github/Python", "django/django", "Python", 4752388, 4804286, 3966996, 4018894, 822, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160076069, 160171970, 4018909, 4114810, 21183, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136577885, 136579278, 4114825, 4116218, 17660, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233937725, 233938225, 4116233, 4116733, 34976, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 62923167, 62937344, 4116748, 4130925, 9742, "entier"], ["github/C++", "nlohmann/json", "C++", 104901961, 104979527, 4130940, 4208506, 14497, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175857404, 175867447, 4208521, 4218564, 23751, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233695055, 233695251, 4218579, 4218775, 34904, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211934497, 211969461, 4218790, 4253754, 31360, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59740496, 59740555, 4253769, 4253828, 9442, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238435902, 238436510, 4253843, 4254451, 36602, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66432434, 66434414, 4254466, 4256446, 10292, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190767516, 190791437, 4256461, 4280382, 26705, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236107587, 236108819, 4280397, 4281629, 35521, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71389515, 71390470, 4281644, 4282599, 10682, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35287556, 35295151, 4282614, 4290209, 4522, "entier"], ["github/Java", "google/guava", "Java", 131833124, 131872979, 4290224, 4330079, 16870, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59564211, 59565521, 4330094, 4331404, 9405, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238250554, 238254637, 4331419, 4335502, 35851, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61866256, 61867224, 4335517, 4336485, 9653, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71545773, 71546460, 4336500, 4337187, 10777, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58879263, 58881622, 4337202, 4339561, 9314, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39024095, 39078754, 4339576, 4394235, 5054, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216058216, 216061973, 4394250, 4398007, 32013, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231309956, 231316398, 4398022, 4404464, 34462, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230834179, 230835604, 4404479, 4405904, 34372, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 64580885, 64589161, 4405919, 4414195, 9969, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174602659, 174613303, 4414210, 4424854, 23510, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25963567, 25978199, 4424869, 4439501, 3384, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141996488, 141997343, 4439516, 4440371, 18708, "entier"], ["github/Python", "django/django", "Python", 6565129, 6566896, 4440386, 4442153, 1128, "entier"], ["github/Go", "prometheus/prometheus", "Go", 76216763, 76261615, 4442168, 4487020, 11216, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14507031, 14507530, 4487035, 4487534, 2007, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9492631, 9492758, 4487549, 4487676, 1498, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59351988, 59356282, 4487691, 4491985, 9377, "entier"], ["github/PHP", "laravel/framework", "PHP", 182271927, 182285096, 4492000, 4505169, 24887, "entier"], ["github/Scala", "scala/scala", "Scala", 219081941, 219099351, 4505184, 4522594, 32371, "entier"], ["github/Python", "django/django", "Python", 975782, 979709, 4522609, 4526536, 178, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214039987, 214040387, 4526551, 4526951, 31742, "entier"], ["github/Python", "django/django", "Python", 1329354, 1330929, 4526966, 4528541, 232, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 199967456, 199968855, 4528556, 4529955, 28288, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126844232, 126845791, 4529970, 4531529, 16207, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180320111, 180323012, 4531544, 4534445, 24478, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196222714, 196223895, 4534460, 4535641, 27735, "entier"], ["github/Python", "django/django", "Python", 4629615, 4635641, 4535656, 4541682, 801, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33025085, 33035623, 4541697, 4552235, 4229, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126565257, 126577468, 4552250, 4564461, 16155, "entier"], ["github/C", "libuv/libuv", "C", 99537150, 99539369, 4564476, 4566695, 13669, "entier"], ["github/Scala", "scala/scala", "Scala", 224580451, 224586964, 4566710, 4573223, 33045, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138797169, 138841059, 4573238, 4617128, 18224, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213056412, 213067547, 4617143, 4628278, 31511, "entier"], ["github/PHP", "laravel/framework", "PHP", 185174197, 185184595, 4628293, 4638691, 25506, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19054509, 19054795, 4638706, 4638992, 2556, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180262300, 180266425, 4639007, 4643132, 24454, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238422661, 238422703, 4643147, 4643189, 36485, "entier"], ["github/C", "libuv/libuv", "C", 99909650, 99913220, 4643204, 4646774, 13747, "entier"], ["github/C++", "nlohmann/json", "C++", 104131168, 104132522, 4646789, 4648143, 14405, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42707560, 42711689, 4648158, 4652287, 5580, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 36095788, 36100538, 4652302, 4657052, 4658, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59666445, 59695393, 4657067, 4686015, 9419, "entier"], ["github/Scala", "playframework/playframework", "Scala", 232889922, 232895309, 4686030, 4691417, 34722, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43629938, 43630118, 4691432, 4691612, 6004, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171719030, 171719321, 4691627, 4691918, 23015, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216115798, 216121310, 4691933, 4697445, 32024, "entier"], ["github/PHP", "laravel/framework", "PHP", 183694574, 183695117, 4697460, 4698003, 25283, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47821796, 47825301, 4698018, 4701523, 7046, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179617972, 179621222, 4701538, 4704788, 24340, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193148369, 193152367, 4704803, 4708801, 27142, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55651550, 55652251, 4708816, 4709517, 8562, "entier"], ["github/C", "libuv/libuv", "C", 101009547, 101014624, 4709532, 4714609, 13844, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212425071, 212429220, 4714624, 4718773, 31418, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55561841, 55565047, 4718788, 4721994, 8544, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28881730, 28893488, 4722009, 4733767, 3948, "entier"], ["github/C++", "nlohmann/json", "C++", 107186870, 107209122, 4733782, 4756034, 14628, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235104626, 235117984, 4756049, 4769407, 35321, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10256704, 10284600, 4769422, 4797318, 1647, "entier"], ["github/Go", "gohugoio/hugo", "Go", 84938970, 84942531, 4797333, 4800894, 11841, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192708341, 192712931, 4800909, 4805499, 27041, "entier"], ["github/Java", "google/guava", "Java", 129690510, 129693247, 4805514, 4808251, 16654, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53968021, 53973246, 4808266, 4813491, 8273, "entier"], ["github/C", "libuv/libuv", "C", 101913851, 101916738, 4813506, 4816393, 13965, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213025062, 213028627, 4816408, 4819973, 31504, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85073485, 85074357, 4819988, 4820860, 11874, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195088306, 195088731, 4820875, 4821300, 27537, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 179973538, 179977794, 4821315, 4825571, 24384, "entier"], ["github/PHP", "laravel/framework", "PHP", 186012590, 186014403, 4825586, 4827399, 25765, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51306470, 51306495, 4827414, 4827439, 7400, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43663161, 43663236, 4827454, 4827529, 6031, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44554600, 44556069, 4827544, 4829013, 6342, "entier"], ["github/PHP", "laravel/framework", "PHP", 182575921, 182576661, 4829028, 4829768, 25044, "entier"], ["github/Go", "prometheus/prometheus", "Go", 82292704, 82296193, 4829783, 4833272, 11653, "entier"], ["github/C", "curl/curl", "C", 92664336, 92666040, 4833287, 4834991, 12949, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24074429, 24075716, 4835006, 4836293, 3168, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56165630, 56165852, 4836308, 4836530, 8699, "entier"], ["github/Scala", "scala/scala", "Scala", 217353402, 217353985, 4836545, 4837128, 32209, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194480535, 194481460, 4837143, 4838068, 27387, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210458024, 210460909, 4838083, 4840968, 30990, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238443472, 238443523, 4840983, 4841034, 36627, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43339379, 43340544, 4841049, 4842214, 5774, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195258786, 195259968, 4842229, 4843411, 27586, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138104937, 138119964, 4843426, 4858453, 18076, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18266781, 18269626, 4858468, 4861313, 2261, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90626906, 90628117, 4861328, 4862539, 12628, "entier"], ["github/PHP", "laravel/framework", "PHP", 185444929, 185447122, 4862554, 4864747, 25592, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202751794, 202753366, 4864762, 4866334, 28887, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 74497172, 74504186, 4866349, 4873363, 11048, "entier"], ["github/Go", "gin-gonic/gin", "Go", 74991817, 74993285, 4873378, 4874846, 11093, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204187774, 204188045, 4874861, 4875132, 29162, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169938578, 169948238, 4875147, 4884807, 22782, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230637170, 230646900, 4884822, 4894552, 34315, "entier"], ["github/Go", "prometheus/prometheus", "Go", 76924668, 76925658, 4894567, 4895557, 11262, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55854484, 55863548, 4895572, 4904636, 8609, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192569995, 192573110, 4904651, 4907766, 27020, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207810172, 207812140, 4907781, 4909749, 30254, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 20942802, 20947469, 4909764, 4914431, 2839, "entier"], ["github/Go", "prometheus/prometheus", "Go", 76620223, 76621280, 4914446, 4915503, 11247, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141918746, 141920289, 4915518, 4917061, 18650, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71547818, 71548508, 4917076, 4917766, 10780, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89200893, 89202114, 4917781, 4919002, 12437, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207950561, 207952205, 4919017, 4920661, 30296, "entier"], ["github/C++", "opencv/opencv", "C++", 114175557, 114191870, 4920676, 4936989, 15169, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71730759, 71732482, 4937004, 4938727, 10893, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205967964, 205968039, 4938742, 4938817, 29766, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 29227301, 29229856, 4938832, 4941387, 3970, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231785314, 231786741, 4941402, 4942829, 34554, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45213583, 45214500, 4942844, 4943761, 6684, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193206887, 193212890, 4943776, 4949779, 27154, "entier"], ["github/Java", "apache/commons-lang", "Java", 153493200, 153500811, 4949794, 4957405, 20312, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51286646, 51286807, 4957420, 4957581, 7360, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43528024, 43528577, 4957596, 4958149, 5889, "entier"], ["github/Scala", "scala/scala", "Scala", 224118154, 224121259, 4958164, 4961269, 32877, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33253778, 33255856, 4961284, 4963362, 4251, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53564702, 53566057, 4963377, 4964732, 8231, "entier"], ["github/Python", "django/django", "Python", 2309054, 2316005, 4964747, 4971698, 468, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178868214, 178880106, 4971713, 4983605, 24210, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136301752, 136302703, 4983620, 4984571, 17453, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238412868, 238412929, 4984586, 4984647, 36379, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195127670, 195128549, 4984662, 4985541, 27550, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230568445, 230569746, 4985556, 4986857, 34294, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34672713, 34674545, 4986872, 4988704, 4452, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210716448, 210724177, 4988719, 4996448, 31068, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236402580, 236403287, 4996463, 4997170, 35575, "entier"], ["github/PHP", "laravel/framework", "PHP", 184597522, 184598805, 4997185, 4998468, 25384, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41951473, 41957071, 4998483, 5004081, 5358, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143956919, 143963171, 5004096, 5010348, 19147, "entier"], ["github/Scala", "scala/scala", "Scala", 221342412, 221344050, 5010363, 5012001, 32539, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21016600, 21018707, 5012016, 5014123, 2860, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238305474, 238305528, 5014138, 5014192, 35968, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226391329, 226392765, 5014207, 5015643, 33303, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136599896, 136600669, 5015658, 5016431, 17673, "entier"], ["github/Java", "google/guava", "Java", 128705028, 128707073, 5016446, 5018491, 16500, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191107499, 191114247, 5018506, 5025254, 26807, "entier"], ["github/Python", "django/django", "Python", 6090651, 6097287, 5025269, 5031905, 1052, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206067962, 206068401, 5031920, 5032359, 29811, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39462457, 39466719, 5032374, 5036636, 5106, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161085915, 161100690, 5036651, 5051426, 21351, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85501129, 85523484, 5051441, 5073796, 11958, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21709345, 21717648, 5073811, 5082114, 2943, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50965235, 50966142, 5082129, 5083036, 7211, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69596046, 69621460, 5083051, 5108465, 10527, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56281134, 56281368, 5108480, 5108714, 8822, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56391340, 56391396, 5108729, 5108785, 8970, "entier"], ["github/C", "curl/curl", "C", 93085697, 93116067, 5108800, 5139170, 12999, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206207053, 206212166, 5139185, 5144298, 29876, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43750045, 43751003, 5144313, 5145271, 6139, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180319253, 180319381, 5145286, 5145414, 24474, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137499979, 137515618, 5145429, 5161068, 17940, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 215077822, 215083639, 5161083, 5166900, 31894, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41968126, 41971110, 5166915, 5169899, 5363, "entier"], ["github/PHP", "symfony/symfony", "PHP", 198094398, 198100572, 5169914, 5176088, 28122, "entier"], ["github/Python", "django/django", "Python", 3822988, 3830962, 5176103, 5184077, 678, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178911018, 178914080, 5184092, 5187154, 24234, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56424497, 56424758, 5187169, 5187430, 8997, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206099659, 206100610, 5187445, 5188396, 29832, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51662325, 51664015, 5188411, 5190101, 7594, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136470255, 136470998, 5190116, 5190859, 17573, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24417143, 24428234, 5190874, 5201965, 3202, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170476423, 170479804, 5201980, 5205361, 22840, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 122270068, 122313147, 5205376, 5248455, 15863, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211800287, 211806725, 5248470, 5254908, 31342, "entier"], ["github/PHP", "laravel/framework", "PHP", 188130940, 188138928, 5254923, 5262911, 26240, "entier"], ["github/Python", "django/django", "Python", 7670234, 7674102, 5262926, 5266794, 1279, "entier"], ["github/Java", "apache/commons-lang", "Java", 154079408, 154089543, 5266809, 5276944, 20344, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170378117, 170380185, 5276959, 5279027, 22826, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78322475, 78323475, 5279042, 5280042, 11400, "entier"], ["github/Go", "gohugoio/hugo", "Go", 84618889, 84619611, 5280057, 5280779, 11784, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71562770, 71563295, 5280794, 5281319, 10809, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65399674, 65399792, 5281334, 5281452, 10105, "entier"], ["github/Python", "django/django", "Python", 5380920, 5383991, 5281467, 5284538, 912, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51521853, 51540138, 5284553, 5302838, 7546, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214333396, 214335721, 5302853, 5305178, 31820, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88922848, 88926002, 5305193, 5308347, 12389, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21164206, 21171707, 5308362, 5315863, 2883, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59055318, 59066455, 5315878, 5327015, 9339, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158194108, 158204119, 5327030, 5337041, 20929, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208691746, 208697325, 5337056, 5342635, 30454, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9446409, 9457656, 5342650, 5353897, 1489, "entier"], ["github/PHP", "laravel/framework", "PHP", 189216357, 189231338, 5353912, 5368893, 26429, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42715905, 42716535, 5368908, 5369538, 5586, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43563234, 43564855, 5369553, 5371174, 5939, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58516148, 58517157, 5371189, 5372198, 9211, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52833644, 52835713, 5372213, 5374282, 8044, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160845675, 160847782, 5374297, 5376404, 21270, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212794160, 212799566, 5376419, 5381825, 31472, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37634996, 37635689, 5381840, 5382533, 4824, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 42056057, 42056238, 5382548, 5382729, 5391, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174325679, 174347960, 5382744, 5405025, 23490, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14166090, 14168162, 5405040, 5407112, 1947, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18533301, 18546413, 5407127, 5420239, 2305, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162901471, 162902040, 5420254, 5420823, 21637, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43055111, 43056761, 5420838, 5422488, 5712, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143333134, 143379216, 5422503, 5468585, 19015, "entier"], ["github/PHP", "laravel/framework", "PHP", 182646715, 182647285, 5468600, 5469170, 25111, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59379149, 59386283, 5469185, 5476319, 9383, "entier"], ["github/Python", "django/django", "Python", 908528, 909615, 5476334, 5477421, 120, "entier"], ["github/PHP", "laravel/framework", "PHP", 188561246, 188561983, 5477436, 5478173, 26326, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165563604, 165566021, 5478188, 5480605, 22073, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195317774, 195318473, 5480620, 5481319, 27605, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51657122, 51660576, 5481334, 5484788, 7592, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204847736, 204848461, 5484803, 5485528, 29387, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204977726, 204978418, 5485543, 5486235, 29469, "entier"], ["github/C++", "nlohmann/json", "C++", 107213761, 107229734, 5486250, 5502223, 14630, "entier"], ["github/Python", "django/django", "Python", 1739799, 1744387, 5502238, 5506826, 328, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168598920, 168600621, 5506841, 5508542, 22623, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42615756, 42616781, 5508557, 5509582, 5520, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190265027, 190269545, 5509597, 5514115, 26596, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71287531, 71288668, 5514130, 5515267, 10585, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43323135, 43323441, 5515282, 5515588, 5750, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210887496, 210890704, 5515603, 5518811, 31111, "entier"], ["github/Go", "gohugoio/hugo", "Go", 84684911, 84715545, 5518826, 5549460, 11797, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58598028, 58599308, 5549475, 5550755, 9241, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71561529, 71561906, 5550770, 5551147, 10807, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216437083, 216441671, 5551162, 5555750, 32102, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197064180, 197065611, 5555765, 5557196, 27900, "entier"], ["github/Python", "django/django", "Python", 6671409, 6674835, 5557211, 5560637, 1174, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202127614, 202128718, 5560652, 5561756, 28755, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60090961, 60094631, 5561771, 5565441, 9475, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208932226, 208934257, 5565456, 5567487, 30506, "entier"], ["github/C", "libuv/libuv", "C", 100278493, 100302166, 5567502, 5591175, 13779, "entier"], ["github/PHP", "laravel/framework", "PHP", 182521323, 182527480, 5591190, 5597347, 24987, "entier"], ["github/Python", "django/django", "Python", 1007592, 1010866, 5597362, 5600636, 204, "entier"], ["github/Scala", "scala/scala", "Scala", 220689552, 220792785, 5600651, 5703884, 32487, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37763679, 37779293, 5703899, 5719513, 4913, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63394996, 63398648, 5719528, 5723180, 9837, "entier"], ["github/Python", "django/django", "Python", 6656491, 6657104, 5723195, 5723808, 1170, "entier"], ["github/Python", "django/django", "Python", 6086128, 6086564, 5723823, 5724259, 1042, "entier"], ["github/Python", "django/django", "Python", 993901, 994583, 5724274, 5724956, 190, "entier"], ["github/PHP", "laravel/framework", "PHP", 186374970, 186376023, 5724971, 5726024, 25848, "entier"], ["github/Python", "django/django", "Python", 929494, 931209, 5726039, 5727754, 137, "entier"], ["github/Python", "django/django", "Python", 6652974, 6652998, 5727769, 5727793, 1167, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 32023511, 32045468, 5727808, 5749765, 4175, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 127112616, 127135166, 5749780, 5772330, 16225, "entier"], ["github/PHP", "laravel/framework", "PHP", 184616246, 184623100, 5772345, 5779199, 25391, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11313323, 11317651, 5779214, 5783542, 1799, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158651284, 158675246, 5783557, 5807519, 20991, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52222934, 52223638, 5807534, 5808238, 7833, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53187022, 53189099, 5808253, 5810330, 8148, "entier"], ["github/Python", "django/django", "Python", 5596768, 5597440, 5810345, 5811017, 966, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53217427, 53217477, 5811032, 5811082, 8175, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197421741, 197425761, 5811097, 5815117, 27981, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55971225, 55975641, 5815132, 5819548, 8634, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90772379, 90774852, 5819563, 5822036, 12653, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175048297, 175054427, 5822051, 5828181, 23635, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193045576, 193046365, 5828196, 5828985, 27089, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 57932469, 57958066, 5829000, 5854597, 9145, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193031068, 193032002, 5854612, 5855546, 27070, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55664885, 55667378, 5855561, 5858054, 8574, "entier"], ["github/C++", "opencv/opencv", "C++", 116921802, 116923963, 5858069, 5860230, 15395, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195855093, 195856024, 5860245, 5861176, 27684, "entier"], ["github/PHP", "laravel/framework", "PHP", 186639240, 186639545, 5861191, 5861496, 25958, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90657580, 90663816, 5861511, 5867747, 12636, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45200300, 45202786, 5867762, 5870248, 6677, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197641149, 197642577, 5870263, 5871691, 28020, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121790426, 121792688, 5871706, 5873968, 15804, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54206399, 54210143, 5873983, 5877727, 8297, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216392952, 216396285, 5877742, 5881075, 32089, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88493828, 88494509, 5881090, 5881771, 12324, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175605920, 175608419, 5881786, 5884285, 23691, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209768869, 209803518, 5884300, 5918949, 30723, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197730542, 197738736, 5918964, 5927158, 28041, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162453845, 162455290, 5927173, 5928618, 21525, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52283274, 52286177, 5928633, 5931536, 7873, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 180635981, 180636307, 5931551, 5931877, 24529, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88905027, 88912300, 5931892, 5939165, 12385, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 179920427, 179921792, 5939180, 5940545, 24370, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 127087165, 127107002, 5940560, 5960397, 16223, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161038125, 161041922, 5960412, 5964209, 21339, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55146449, 55150661, 5964224, 5968436, 8490, "entier"], ["github/PHP", "laravel/framework", "PHP", 185596784, 185597549, 5968451, 5969216, 25650, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171827309, 171827618, 5969231, 5969540, 23060, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195387591, 195388379, 5969555, 5970343, 27623, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65403489, 65403682, 5970358, 5970551, 10126, "entier"], ["github/PHP", "laravel/framework", "PHP", 187992500, 187992980, 5970566, 5971046, 26204, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196462889, 196464194, 5971061, 5972366, 27803, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159043943, 159044998, 5972381, 5973436, 21063, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54122309, 54123701, 5973451, 5974843, 8292, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233859956, 233878417, 5974858, 5993319, 34934, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34322900, 34352992, 5993334, 6023426, 4398, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85609403, 85611896, 6023441, 6025934, 11984, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199733832, 199736961, 6025949, 6029078, 28252, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178951920, 178956143, 6029093, 6033316, 24242, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164398899, 164401955, 6033331, 6036387, 21899, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43358038, 43362476, 6036402, 6040840, 5784, "entier"], ["github/C", "madler/zlib", "C", 102826140, 102849541, 6040855, 6064256, 14062, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60080368, 60090946, 6064271, 6074849, 9474, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37378493, 37379362, 6074864, 6075733, 4780, "entier"], ["github/PHP", "laravel/framework", "PHP", 181425388, 181428990, 6075748, 6079350, 24715, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165683030, 165685179, 6079365, 6081514, 22117, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 124534728, 124538611, 6081529, 6085412, 16024, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56481891, 56483618, 6085427, 6087154, 9046, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 17545933, 17598994, 6087169, 6140230, 2131, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54439095, 54442184, 6140245, 6143334, 8336, "entier"], ["github/C++", "opencv/opencv", "C++", 118845452, 118849953, 6143349, 6147850, 15515, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71279612, 71280648, 6147865, 6148901, 10576, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173480848, 173485275, 6148916, 6153343, 23409, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 166851662, 166858046, 6153358, 6159742, 22271, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46829834, 46831836, 6159757, 6161759, 6896, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195280783, 195289200, 6161774, 6170191, 27599, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66543941, 66546823, 6170206, 6173088, 10321, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37440635, 37441339, 6173103, 6173807, 4796, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39248923, 39249403, 6173822, 6174302, 5074, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38069884, 38069991, 6174317, 6174424, 4961, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56376411, 56376516, 6174439, 6174544, 8950, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 119728677, 119734958, 6174559, 6180840, 15564, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56430069, 56431391, 6180855, 6182177, 9002, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177028073, 177028352, 6182192, 6182471, 23875, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214191373, 214192543, 6182486, 6183656, 31776, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75447295, 75468498, 6183671, 6204874, 11162, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168594164, 168595570, 6204889, 6206295, 22620, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 181161952, 181163217, 6206310, 6207575, 24638, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190542063, 190543176, 6207590, 6208703, 26655, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229586300, 229586834, 6208718, 6209252, 33859, "entier"], ["github/C++", "google/leveldb", "C++", 110866673, 110868140, 6209267, 6210734, 14892, "entier"], ["github/PHP", "laravel/framework", "PHP", 186608357, 186608814, 6210749, 6211206, 25935, "entier"], ["github/PHP", "laravel/framework", "PHP", 181582395, 181582669, 6211221, 6211495, 24749, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171937508, 171937537, 6211510, 6211539, 23122, "entier"], ["github/Swift", "vapor/vapor", "Swift", 217247128, 217251904, 6211554, 6216330, 32193, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160830857, 160832448, 6216345, 6217936, 21264, "entier"], ["github/Scala", "scala/scala", "Scala", 217660446, 217663398, 6217951, 6220903, 32278, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191824194, 191825819, 6220918, 6222543, 26867, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27131516, 27135021, 6222558, 6226063, 3592, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 119649579, 119654928, 6226078, 6231427, 15554, "entier"], ["github/PHP", "laravel/framework", "PHP", 183021886, 183022851, 6231442, 6232407, 25201, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211073540, 211079881, 6232422, 6238763, 31142, "entier"], ["github/C++", "opencv/opencv", "C++", 110987247, 110987544, 6238778, 6239075, 14927, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174815374, 174820335, 6239090, 6244051, 23557, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 73829768, 73847238, 6244066, 6261536, 10991, "entier"], ["github/Scala", "scala/scala", "Scala", 219914749, 219921892, 6261551, 6268694, 32445, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158944785, 158952567, 6268709, 6276491, 21041, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200560948, 200561180, 6276506, 6276738, 28513, "entier"], ["github/C", "curl/curl", "C", 96016488, 96021506, 6276753, 6281771, 13186, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204555610, 204557295, 6281786, 6283471, 29261, "entier"], ["github/PHP", "laravel/framework", "PHP", 189378620, 189391734, 6283486, 6296600, 26456, "entier"], ["github/C++", "opencv/opencv", "C++", 111390635, 111405888, 6296615, 6311868, 14996, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205021991, 205024148, 6311883, 6314040, 29488, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85231350, 85232529, 6314055, 6315234, 11905, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204869591, 204870023, 6315249, 6315681, 29422, "entier"], ["github/C", "curl/curl", "C", 98395157, 98398175, 6315696, 6318714, 13437, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 167312450, 167316271, 6318729, 6322550, 22297, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213857537, 213858878, 6322565, 6323906, 31694, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66239064, 66239127, 6323921, 6323984, 10263, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63366285, 63370411, 6323999, 6328125, 9825, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163522241, 163522897, 6328140, 6328796, 21726, "entier"], ["github/Go", "prometheus/prometheus", "Go", 79744749, 79752893, 6328811, 6336955, 11521, "entier"], ["github/PHP", "laravel/framework", "PHP", 188486494, 188487321, 6336970, 6337797, 26281, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238274897, 238293110, 6337812, 6356025, 35860, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208206674, 208209879, 6356040, 6359245, 30366, "entier"], ["github/PHP", "laravel/framework", "PHP", 186511322, 186511695, 6359260, 6359633, 25894, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25267886, 25295538, 6359648, 6387300, 3299, "entier"], ["github/C++", "opencv/opencv", "C++", 116517116, 116520689, 6387315, 6390888, 15312, "entier"], ["github/Python", "django/django", "Python", 960801, 961551, 6390903, 6391653, 167, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71337065, 71338109, 6391668, 6392712, 10633, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189928370, 189931316, 6392727, 6395673, 26550, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 127383494, 127384546, 6395688, 6396740, 16261, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69459031, 69461599, 6396755, 6399323, 10514, "entier"], ["github/PHP", "laravel/framework", "PHP", 189009154, 189009584, 6399338, 6399768, 26405, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9707162, 9711838, 6399783, 6404459, 1548, "entier"], ["github/Java", "google/guava", "Java", 129316719, 129516224, 6404474, 6603979, 16611, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213523137, 213527079, 6603994, 6607936, 31621, "entier"], ["github/PHP", "laravel/framework", "PHP", 186708191, 186709650, 6607951, 6609410, 25980, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71427819, 71428125, 6609425, 6609731, 10715, "entier"], ["github/PHP", "laravel/framework", "PHP", 182406853, 182409011, 6609746, 6611904, 24922, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204851083, 204852057, 6611919, 6612893, 29391, "entier"], ["github/Scala", "scala/scala", "Scala", 225360052, 225362001, 6612908, 6614857, 33139, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 74255281, 74263381, 6614872, 6622972, 11021, "entier"], ["github/C", "libuv/libuv", "C", 101114131, 101130347, 6622987, 6639203, 13852, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206370155, 206374810, 6639218, 6643873, 29924, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197633303, 197641134, 6643888, 6651719, 28019, "entier"], ["github/C++", "nlohmann/json", "C++", 104765158, 104787149, 6651734, 6673725, 14485, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90979688, 90994440, 6673740, 6688492, 12670, "entier"], ["github/Scala", "scala/scala", "Scala", 218706896, 218717038, 6688507, 6698649, 32353, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63377807, 63380454, 6698664, 6701311, 9830, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24306538, 24307387, 6701326, 6702175, 3182, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175764901, 175789098, 6702190, 6726387, 23726, "entier"], ["github/PHP", "laravel/framework", "PHP", 186467746, 186468142, 6726402, 6726798, 25878, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158529124, 158555332, 6726813, 6753021, 20970, "entier"], ["github/Python", "django/django", "Python", 1223326, 1242700, 6753036, 6772410, 219, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71269547, 71269942, 6772425, 6772820, 10564, "entier"], ["github/PHP", "laravel/framework", "PHP", 185118802, 185120126, 6772835, 6774159, 25494, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71655567, 71655888, 6774174, 6774495, 10883, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189777222, 189777703, 6774510, 6774991, 26505, "entier"], ["github/Scala", "sbt/sbt", "Scala", 239022916, 239025496, 6775006, 6777586, 36845, "entier"], ["github/PHP", "laravel/framework", "PHP", 184081636, 184086049, 6777601, 6782014, 25331, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206180675, 206189583, 6782029, 6790937, 29863, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229704313, 229704487, 6790952, 6791126, 33915, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238294843, 238295016, 6791141, 6791314, 35868, "entier"], ["github/Scala", "sbt/sbt", "Scala", 239285384, 239288695, 6791329, 6794640, 36900, "entier"], ["github/C", "libuv/libuv", "C", 99556571, 99557447, 6794655, 6795531, 13685, "entier"], ["github/C++", "nlohmann/json", "C++", 104209901, 104217077, 6795546, 6802722, 14472, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78126017, 78129954, 6802737, 6806674, 11360, "entier"], ["github/C", "jqlang/jq", "C", 103791189, 103793836, 6806689, 6809336, 14124, "entier"], ["github/Scala", "scala/scala", "Scala", 224723474, 224727022, 6809351, 6812899, 33088, "entier"], ["github/C++", "nlohmann/json", "C++", 104155533, 104155977, 6812914, 6813358, 14430, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 50223877, 50323175, 6813373, 6912671, 7155, "entier"], ["github/Python", "django/django", "Python", 1831348, 1832923, 6912686, 6914261, 353, "entier"], ["github/Go", "gohugoio/hugo", "Go", 84912995, 84915907, 6914276, 6917188, 11833, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191812901, 191824179, 6917203, 6928481, 26866, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209503214, 209506804, 6928496, 6932086, 30646, "entier"], ["github/Python", "django/django", "Python", 997555, 998574, 6932101, 6933120, 194, "entier"], ["github/Python", "django/django", "Python", 1343408, 1345830, 6933135, 6935557, 236, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237391083, 237398914, 6935572, 6943403, 35684, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202512654, 202513727, 6943418, 6944491, 28862, "entier"], ["github/C", "curl/curl", "C", 97346177, 97351620, 6944506, 6949949, 13268, "entier"], ["github/Go", "prometheus/prometheus", "Go", 79737874, 79744734, 6949964, 6956824, 11520, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168270230, 168271770, 6956839, 6958379, 22433, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60397865, 60432976, 6958394, 6993505, 9537, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208844324, 208849068, 6993520, 6998264, 30489, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230853705, 230859655, 6998279, 7004229, 34378, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190303585, 190310641, 7004244, 7011300, 26605, "entier"], ["github/C", "curl/curl", "C", 98728959, 98730979, 7011315, 7013335, 13553, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10396871, 10408425, 7013350, 7024904, 1667, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89073401, 89074895, 7024919, 7026413, 12416, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208590712, 208592746, 7026428, 7028462, 30439, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157026890, 157034816, 7028477, 7036403, 20634, "entier"], ["github/C", "curl/curl", "C", 98875556, 98877898, 7036418, 7038760, 13590, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199072995, 199074213, 7038775, 7039993, 28221, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196699293, 196700507, 7040008, 7041222, 27848, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228331478, 228339209, 7041237, 7048968, 33599, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198344608, 198344837, 7048983, 7049212, 28163, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171766022, 171771594, 7049227, 7054799, 23027, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190846296, 190847172, 7054814, 7055690, 26741, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 30437290, 30492460, 7055705, 7110875, 4082, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208759258, 208764276, 7110890, 7115908, 30469, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168636686, 168638055, 7115923, 7117292, 22644, "entier"], ["github/Scala", "sbt/sbt", "Scala", 239181506, 239182087, 7117307, 7117888, 36865, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160898837, 160900298, 7117903, 7119364, 21303, "entier"], ["github/PHP", "laravel/framework", "PHP", 183725139, 183730781, 7119379, 7125021, 25304, "entier"], ["github/Python", "django/django", "Python", 4592988, 4602574, 7125036, 7134622, 797, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161004159, 161005464, 7134637, 7135942, 21330, "entier"], ["github/C", "curl/curl", "C", 97274544, 97285642, 7135957, 7147055, 13260, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228146213, 228153311, 7147070, 7154168, 33577, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158648641, 158650091, 7154183, 7155633, 20989, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205844175, 205849423, 7155648, 7160896, 29734, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164481577, 164482203, 7160911, 7161537, 21911, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164282649, 164283256, 7161552, 7162159, 21890, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193097684, 193104496, 7162174, 7168986, 27134, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63059840, 63061829, 7169001, 7170990, 9762, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209575108, 209575930, 7171005, 7171827, 30663, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205090990, 205092143, 7171842, 7172995, 29527, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78946621, 78976263, 7173010, 7202652, 11450, "entier"], ["github/Scala", "scala/scala", "Scala", 224570595, 224577234, 7202667, 7209306, 33043, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197610426, 197611487, 7209321, 7210382, 28009, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177590483, 177599598, 7210397, 7219512, 24036, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65348928, 65354737, 7219527, 7225336, 10037, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212063919, 212067092, 7225351, 7228524, 31382, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193408237, 193409722, 7228539, 7230024, 27215, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238371330, 238371374, 7230039, 7230083, 36211, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231187069, 231187656, 7230098, 7230685, 34435, "entier"], ["github/Python", "django/django", "Python", 8440026, 8452715, 7230700, 7243389, 1343, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229647051, 229647553, 7243404, 7243906, 33874, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191834987, 191837016, 7243921, 7245950, 26872, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61687899, 61690103, 7245965, 7248169, 9632, "entier"], ["github/Scala", "playframework/playframework", "Scala", 225945558, 225952500, 7248184, 7255126, 33226, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 201825393, 201831312, 7255141, 7261060, 28725, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 125698019, 125798172, 7261075, 7361228, 16106, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238298018, 238298072, 7361243, 7361297, 35896, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231933647, 231936318, 7361312, 7363983, 34572, "entier"], ["github/PHP", "laravel/framework", "PHP", 184755343, 184770475, 7363998, 7379130, 25416, "entier"], ["github/Scala", "scala/scala", "Scala", 217770427, 217771678, 7379145, 7380396, 32294, "entier"], ["github/C", "curl/curl", "C", 98801505, 98816937, 7380411, 7395843, 13570, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216304915, 216326780, 7395858, 7417723, 32071, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226402184, 226403433, 7417738, 7418987, 33307, "entier"], ["github/Python", "django/django", "Python", 4638775, 4647240, 7419002, 7427467, 803, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174922617, 174928680, 7427482, 7433545, 23615, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227427463, 227429581, 7433560, 7435678, 33505, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 36477166, 36478304, 7435693, 7436831, 4692, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238320967, 238321008, 7436846, 7436887, 36038, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238419786, 238419834, 7436902, 7436950, 36451, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238304545, 238304586, 7436965, 7437006, 35954, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88445157, 88445423, 7437021, 7437287, 12318, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25488142, 25489799, 7437302, 7438959, 3343, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56290375, 56290682, 7438974, 7439281, 8834, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44957090, 44959690, 7439296, 7441896, 6511, "entier"], ["github/Go", "gohugoio/hugo", "Go", 87841736, 87845537, 7441911, 7445712, 12212, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200365336, 200376970, 7445727, 7457361, 28457, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231656714, 231663349, 7457376, 7464011, 34537, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 23149514, 23152430, 7464026, 7466942, 3117, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193321122, 193321715, 7466957, 7467550, 27185, "entier"], ["github/PHP", "laravel/framework", "PHP", 185450033, 185451270, 7467565, 7468802, 25596, "entier"], ["github/Go", "gohugoio/hugo", "Go", 87274419, 87275027, 7468817, 7469425, 12169, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 15700770, 15708139, 7469440, 7476809, 2068, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88232252, 88233665, 7476824, 7478237, 12275, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44449270, 44455164, 7478252, 7484146, 6305, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189856497, 189859593, 7484161, 7487257, 26524, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238729684, 238733460, 7487272, 7491048, 36774, "entier"], ["github/C", "curl/curl", "C", 98362880, 98364621, 7491063, 7492804, 13426, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178468924, 178474014, 7492819, 7497909, 24177, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230163358, 230164444, 7497924, 7499010, 34032, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210554292, 210555201, 7499025, 7499934, 31024, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226671770, 226672910, 7499949, 7501089, 33341, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169318060, 169368936, 7501104, 7551980, 22764, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139477924, 139522665, 7551995, 7596736, 18348, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9986281, 9989599, 7596751, 7600069, 1598, "entier"], ["github/C", "libuv/libuv", "C", 100505780, 100507785, 7600084, 7602089, 13790, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39556903, 39563148, 7602104, 7608349, 5126, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192432776, 192439972, 7608364, 7615560, 26989, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66636910, 66681519, 7615575, 7660184, 10331, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204774280, 204777638, 7660199, 7663557, 29329, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174880923, 174880949, 7663572, 7663598, 23585, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9351793, 9355055, 7663613, 7666875, 1471, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28432116, 28456574, 7666890, 7691348, 3898, "entier"], ["github/PHP", "laravel/framework", "PHP", 182798596, 182802941, 7691363, 7695708, 25138, "entier"], ["github/Python", "django/django", "Python", 4495860, 4498409, 7695723, 7698272, 780, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53875066, 53882332, 7698287, 7705553, 8267, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234576589, 234596713, 7705568, 7725692, 35175, "entier"], ["github/PHP", "laravel/framework", "PHP", 185549007, 185549591, 7725707, 7726291, 25622, "entier"], ["github/Python", "django/django", "Python", 5985787, 5987937, 7726306, 7728456, 1017, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190693781, 190695207, 7728471, 7729897, 26687, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37689605, 37689735, 7729912, 7730042, 4862, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203183415, 203194666, 7730057, 7741308, 28909, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189849606, 189851499, 7741323, 7743216, 26521, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176722179, 176732698, 7743231, 7753750, 23810, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192551514, 192556102, 7753765, 7758353, 27015, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47856273, 47866204, 7758368, 7768299, 7056, "entier"], ["github/Python", "django/django", "Python", 4295836, 4306091, 7768314, 7778569, 752, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138200258, 138206859, 7778584, 7785185, 18116, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198339715, 198339935, 7785200, 7785420, 28160, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19010460, 19010513, 7785435, 7785488, 2454, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200013747, 200014549, 7785503, 7786305, 28311, "entier"], ["github/Java", "square/okhttp", "Java", 148987484, 148989182, 7786320, 7788018, 19945, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211449648, 211450038, 7788033, 7788423, 31239, "entier"], ["github/Java", "apache/commons-lang", "Java", 154199067, 154200385, 7788438, 7789756, 20364, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43585511, 43587400, 7789771, 7791660, 5972, "entier"], ["github/C", "curl/curl", "C", 92290909, 92317011, 7791675, 7817777, 12890, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206939245, 206940449, 7817792, 7818996, 30036, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44883269, 44884129, 7819011, 7819871, 6439, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34209658, 34217419, 7819886, 7827647, 4384, "entier"], ["github/Scala", "scala/scala", "Scala", 223507311, 223518338, 7827662, 7838689, 32778, "entier"], ["github/C++", "opencv/opencv", "C++", 111749752, 111755534, 7838704, 7844486, 15019, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50973191, 50974881, 7844501, 7846191, 7224, "entier"], ["github/Java", "google/guava", "Java", 134171900, 134181662, 7846206, 7855968, 17152, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52155351, 52155952, 7855983, 7856584, 7785, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58752619, 58755003, 7856599, 7858983, 9279, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193440228, 193455377, 7858998, 7874147, 27223, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 180780347, 180783402, 7874162, 7877217, 24562, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39511305, 39513788, 7877232, 7879715, 5116, "entier"], ["github/C++", "nlohmann/json", "C++", 103967469, 103968743, 7879730, 7881004, 14204, "entier"], ["github/C++", "nlohmann/json", "C++", 104078632, 104079663, 7881019, 7882050, 14337, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71399422, 71400463, 7882065, 7883106, 10691, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45509979, 45510969, 7883121, 7884111, 6746, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205177871, 205186454, 7884126, 7892709, 29552, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137872268, 137874321, 7892724, 7894777, 18020, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230104078, 230105785, 7894792, 7896499, 34005, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55503832, 55505420, 7896514, 7898102, 8529, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173305422, 173306147, 7898117, 7898842, 23385, "entier"], ["github/Scala", "playframework/playframework", "Scala", 225931059, 225931287, 7898857, 7899085, 33222, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56259319, 56259652, 7899100, 7899433, 8797, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56305946, 56306115, 7899448, 7899617, 8856, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44899465, 44899993, 7899632, 7900160, 6449, "entier"], ["github/Java", "google/guava", "Java", 132761436, 132767319, 7900175, 7906058, 17014, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 40886692, 40887393, 7906073, 7906774, 5220, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227753432, 227756194, 7906789, 7909551, 33520, "entier"], ["github/Go", "spf13/cobra", "Go", 75708420, 75769562, 7909566, 7970708, 11188, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26915205, 26925425, 7970723, 7980943, 3512, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47664760, 47665622, 7980958, 7981820, 7021, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175761797, 175764886, 7981835, 7984924, 23725, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164511715, 164513773, 7984939, 7986997, 21922, "entier"], ["github/Python", "django/django", "Python", 1496572, 1520249, 7987012, 8010689, 259, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143438605, 143440665, 8010704, 8012764, 19018, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51148291, 51151296, 8012779, 8015784, 7276, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189863988, 189865605, 8015799, 8017416, 26526, "entier"], ["github/PHP", "laravel/framework", "PHP", 182625186, 182625307, 8017431, 8017552, 25104, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205653387, 205655905, 8017567, 8020085, 29688, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168159754, 168161153, 8020100, 8021499, 22386, "entier"], ["github/Java", "google/guava", "Java", 132449148, 132455328, 8021514, 8027694, 16965, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162769154, 162770187, 8027709, 8028742, 21616, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204879791, 204880642, 8028757, 8029608, 29433, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35394324, 35395174, 8029623, 8030473, 4534, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43757653, 43762766, 8030488, 8035601, 6144, "entier"], ["github/Scala", "sbt/sbt", "Scala", 239232005, 239243383, 8035616, 8046994, 36883, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193622167, 193628530, 8047009, 8053372, 27261, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35382573, 35383549, 8053387, 8054363, 4530, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142889458, 142891576, 8054378, 8056496, 18929, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 206029318, 206031089, 8056511, 8058282, 29793, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25120288, 25123122, 8058297, 8061131, 3262, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206083886, 206084460, 8061146, 8061720, 29824, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46940301, 46942460, 8061735, 8063894, 6932, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163320517, 163327572, 8063909, 8070964, 21682, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210872349, 210874519, 8070979, 8073149, 31108, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230164459, 230164989, 8073164, 8073694, 34033, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139522680, 139532078, 8073709, 8083107, 18349, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238393046, 238393235, 8083122, 8083311, 36274, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238415499, 238416023, 8083326, 8083850, 36419, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238368267, 238368514, 8083865, 8084112, 36193, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47934955, 47939631, 8084127, 8088803, 7071, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179357237, 179365768, 8088818, 8097349, 24280, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199386932, 199392446, 8097364, 8102878, 28240, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200111250, 200112235, 8102893, 8103878, 28374, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230236749, 230238460, 8103893, 8105604, 34101, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34750643, 34756609, 8105619, 8111585, 4457, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214281010, 214283303, 8111600, 8113893, 31803, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141920304, 141922865, 8113908, 8116469, 18651, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157868059, 157870645, 8116484, 8119070, 20839, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19016925, 19017160, 8119085, 8119320, 2474, "entier"], ["github/Java", "google/guava", "Java", 132015011, 132016357, 8119335, 8120681, 16888, "entier"], ["github/Java", "square/okhttp", "Java", 146691150, 146691877, 8120696, 8121423, 19702, "entier"], ["github/PHP", "laravel/framework", "PHP", 187158509, 187161973, 8121438, 8124902, 26066, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206984862, 206986430, 8124917, 8126485, 30045, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139705543, 139707034, 8126500, 8127991, 18368, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 15997536, 16005151, 8128006, 8135621, 2078, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168254456, 168256600, 8135636, 8137780, 22423, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211524037, 211527341, 8137795, 8141099, 31266, "entier"], ["github/PHP", "laravel/framework", "PHP", 184904774, 184908190, 8141114, 8144530, 25440, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175610386, 175610964, 8144545, 8145123, 23695, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 29543073, 29553875, 8145138, 8155940, 3988, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233924717, 233927710, 8155955, 8158948, 34972, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211434051, 211434452, 8158963, 8159364, 31226, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47976692, 47995535, 8159379, 8178222, 7080, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171562985, 171565184, 8178237, 8180436, 22957, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143103770, 143121058, 8180451, 8197739, 18996, "entier"], ["github/C", "curl/curl", "C", 91857085, 91878890, 8197754, 8219559, 12856, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207995580, 207999195, 8219574, 8223189, 30306, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19078602, 19078769, 8223204, 8223371, 2603, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27336915, 27337388, 8223386, 8223859, 3637, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179237433, 179240437, 8223874, 8226878, 24267, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203621719, 203623846, 8226893, 8229020, 28993, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 29208431, 29212974, 8229035, 8233578, 3968, "entier"], ["github/Java", "google/guava", "Java", 128578520, 128582474, 8233593, 8237547, 16467, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202209354, 202211377, 8237562, 8239585, 28779, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56320770, 56320895, 8239600, 8239725, 8879, "entier"], ["github/Python", "django/django", "Python", 9166079, 9186197, 8239740, 8259858, 1427, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54555495, 54557141, 8259873, 8261519, 8417, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142703845, 142707125, 8261534, 8264814, 18898, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34670185, 34672213, 8264829, 8266857, 4450, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51640919, 51641106, 8266872, 8267059, 7583, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43634845, 43635178, 8267074, 8267407, 6008, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159948817, 159971091, 8267422, 8289696, 21176, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43517590, 43518243, 8289711, 8290364, 5868, "entier"], ["github/C++", "opencv/opencv", "C++", 111279494, 111378803, 8290379, 8389688, 14993, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204230349, 204232967, 8389703, 8392321, 29179, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143579969, 143581952, 8392336, 8394319, 19059, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71981719, 72058068, 8394334, 8470683, 10915, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143454019, 143456285, 8470698, 8472964, 19023, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39236126, 39239836, 8472979, 8476689, 5071, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210329975, 210330348, 8476704, 8477077, 30938, "entier"], ["github/Java", "google/guava", "Java", 128525219, 128525314, 8477092, 8477187, 16451, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45002700, 45004307, 8477202, 8478809, 6560, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200188699, 200192196, 8478824, 8482321, 28404, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78129969, 78138301, 8482336, 8490668, 11361, "entier"], ["github/PHP", "laravel/framework", "PHP", 183273835, 183309707, 8490683, 8526555, 25227, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44825859, 44829562, 8526570, 8530273, 6414, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14976575, 14976951, 8530288, 8530664, 2038, "entier"], ["github/Java", "google/guava", "Java", 133977247, 133999198, 8530679, 8552630, 17138, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180618223, 180633292, 8552645, 8567714, 24526, "entier"], ["github/C", "libuv/libuv", "C", 99903436, 99909635, 8567729, 8573928, 13746, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50883776, 50889398, 8573943, 8579565, 7190, "entier"], ["github/Python", "django/django", "Python", 6684521, 6692007, 8579580, 8587066, 1177, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85662542, 85667996, 8587081, 8592535, 11994, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168328973, 168330327, 8592550, 8593904, 22467, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213012385, 213024011, 8593919, 8605545, 31501, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234060226, 234060712, 8605560, 8606046, 35055, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157264951, 157267563, 8606061, 8608673, 20701, "entier"], ["github/Go", "gohugoio/hugo", "Go", 86150091, 86151725, 8608688, 8610322, 12059, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55032341, 55039093, 8610337, 8617089, 8475, "entier"], ["github/C", "curl/curl", "C", 98611571, 98614033, 8617104, 8619566, 13518, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75469619, 75470439, 8619581, 8620401, 11164, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 215224675, 215232925, 8620416, 8628666, 31902, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157285427, 157287437, 8628681, 8630691, 20708, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138974013, 138982943, 8630706, 8639636, 18248, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10674169, 10683267, 8639651, 8648749, 1714, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44326744, 44329978, 8648764, 8651998, 6273, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141263901, 141264625, 8652013, 8652737, 18526, "entier"], ["github/Java", "square/okhttp", "Java", 147821771, 147823773, 8652752, 8654754, 19798, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192467270, 192468053, 8654769, 8655552, 26999, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136621832, 136623229, 8655567, 8656964, 17690, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194754974, 194755584, 8656979, 8657589, 27467, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45187461, 45191002, 8657604, 8661145, 6669, "entier"], ["github/C", "libuv/libuv", "C", 101916753, 101925056, 8661160, 8669463, 13966, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205798588, 205804431, 8669478, 8675321, 29723, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191806863, 191808830, 8675336, 8677303, 26864, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26948547, 27000224, 8677318, 8728995, 3514, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227318322, 227424769, 8729010, 8835457, 33503, "entier"], ["github/Java", "apache/commons-lang", "Java", 151974831, 151979056, 8835472, 8839697, 20222, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9523747, 9525852, 8839712, 8841817, 1512, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56344959, 56345176, 8841832, 8842049, 8909, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162930665, 162940586, 8842064, 8851985, 21645, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88514734, 88530411, 8852000, 8867677, 12327, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56044676, 56047474, 8867692, 8870490, 8680, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195790011, 195792769, 8870505, 8873263, 27666, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141264640, 141270488, 8873278, 8879126, 18527, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14187233, 14191902, 8879141, 8883810, 1950, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207118426, 207121082, 8883825, 8886481, 30089, "entier"], ["github/C", "curl/curl", "C", 91132773, 91133240, 8886496, 8886963, 12702, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190709015, 190712812, 8886978, 8890775, 26696, "entier"], ["github/Java", "square/okhttp", "Java", 145959572, 145961063, 8890790, 8892281, 19599, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213024026, 213024504, 8892296, 8892774, 31502, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45581663, 45590267, 8892789, 8901393, 6754, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159319646, 159321957, 8901408, 8903719, 21111, "entier"], ["github/Java", "apache/commons-lang", "Java", 154209688, 154216863, 8903734, 8910909, 20367, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204029732, 204034658, 8910924, 8915850, 29096, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168512277, 168513834, 8915865, 8917422, 22571, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189840468, 189848229, 8917437, 8925198, 26519, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43320079, 43321451, 8925213, 8926585, 5745, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143099580, 143103755, 8926600, 8930775, 18995, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52790794, 52791027, 8930790, 8931023, 8005, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173240340, 173255832, 8931038, 8946530, 23368, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207652561, 207653130, 8946545, 8947114, 30210, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53467472, 53469980, 8947129, 8949637, 8206, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200605430, 200606137, 8949652, 8950359, 28532, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45509202, 45509524, 8950374, 8950696, 6744, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38046471, 38046660, 8950711, 8950900, 4949, "entier"], ["github/PHP", "laravel/framework", "PHP", 187449910, 187450692, 8950915, 8951697, 26121, "entier"], ["github/PHP", "laravel/framework", "PHP", 185157588, 185158068, 8951712, 8952192, 25502, "entier"], ["github/C++", "opencv/opencv", "C++", 114404175, 114413171, 8952207, 8961203, 15188, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205016734, 205018861, 8961218, 8963345, 29486, "entier"], ["github/Go", "prometheus/prometheus", "Go", 81044818, 81056011, 8963360, 8974553, 11570, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190301196, 190303570, 8974568, 8976942, 26604, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202111092, 202113259, 8976957, 8979124, 28746, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55091972, 55100192, 8979139, 8987359, 8483, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196969713, 196971832, 8987374, 8989493, 27873, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 70170165, 70186167, 8989508, 9005510, 10543, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157011276, 157026875, 9005525, 9021124, 20633, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194616064, 194616914, 9021139, 9021989, 27424, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 16444476, 16474688, 9022004, 9052216, 2095, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193065666, 193067155, 9052231, 9053720, 27105, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205046665, 205050235, 9053735, 9057305, 29505, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88730660, 88731684, 9057320, 9058344, 12362, "entier"], ["github/PHP", "laravel/framework", "PHP", 187311470, 187313222, 9058359, 9060111, 26089, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85523499, 85524234, 9060126, 9060861, 11959, "entier"], ["github/PHP", "laravel/framework", "PHP", 185991846, 185992664, 9060876, 9061694, 25759, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209592225, 209592741, 9061709, 9062225, 30678, "entier"], ["github/Go", "prometheus/prometheus", "Go", 80812376, 80814133, 9062240, 9063997, 11555, "entier"], ["github/C++", "opencv/opencv", "C++", 114137247, 114156592, 9064012, 9083357, 15164, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75053179, 75053856, 9083372, 9084049, 11109, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174878967, 174879250, 9084064, 9084347, 23581, "entier"], ["github/PHP", "laravel/framework", "PHP", 187332207, 187339638, 9084362, 9091793, 26095, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55802657, 55816897, 9091808, 9106048, 8597, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142293785, 142344847, 9106063, 9157125, 18822, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66033111, 66036384, 9157140, 9160413, 10224, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159480636, 159482404, 9160428, 9162196, 21126, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159159072, 159159563, 9162211, 9162702, 21075, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165558839, 165560900, 9162717, 9164778, 22071, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69346336, 69352566, 9164793, 9171023, 10501, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207394582, 207411337, 9171038, 9187793, 30128, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168158374, 168159739, 9187808, 9189173, 22385, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194018809, 194028389, 9189188, 9198768, 27325, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56365532, 56368928, 9198783, 9202179, 8941, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 64942359, 64942754, 9202194, 9202589, 10001, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9475897, 9481357, 9202604, 9208064, 1495, "entier"], ["github/Go", "gohugoio/hugo", "Go", 86565458, 86587317, 9208079, 9229938, 12098, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47961310, 47963569, 9229953, 9232212, 7075, "entier"], ["github/C++", "nlohmann/json", "C++", 104821084, 104836751, 9232227, 9247894, 14488, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180499561, 180513308, 9247909, 9261656, 24503, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 40823967, 40824156, 9261671, 9261860, 5211, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 23998115, 24030180, 9261875, 9293940, 3162, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55565062, 55566873, 9293955, 9295766, 8545, "entier"], ["github/PHP", "laravel/framework", "PHP", 181648920, 181649361, 9295781, 9296222, 24761, "entier"], ["github/Python", "django/django", "Python", 1553929, 1554339, 9296237, 9296647, 267, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59443771, 59453527, 9296662, 9306418, 9393, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53559368, 53560868, 9306433, 9307933, 8229, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44876351, 44877452, 9307948, 9309049, 6433, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54448772, 54450396, 9309064, 9310688, 8347, "entier"], ["github/Java", "google/guava", "Java", 131742375, 131743926, 9310703, 9312254, 16863, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10207322, 10215307, 9312269, 9320254, 1640, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213527630, 213529802, 9320269, 9322441, 31623, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229577007, 229581877, 9322456, 9327326, 33856, "entier"], ["github/Java", "square/okhttp", "Java", 145190628, 145195238, 9327341, 9331951, 19469, "entier"], ["github/C++", "opencv/opencv", "C++", 117140757, 117148205, 9331966, 9339414, 15446, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238297057, 238297092, 9339429, 9339464, 35884, "entier"], ["github/PHP", "laravel/framework", "PHP", 184039767, 184056457, 9339479, 9356169, 25321, "entier"], ["github/Python", "django/django", "Python", 1752869, 1753732, 9356184, 9357047, 333, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61171979, 61178947, 9357062, 9364030, 9571, "entier"], ["github/Java", "apache/commons-lang", "Java", 151979071, 151982660, 9364045, 9367634, 20223, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238824509, 238825994, 9367649, 9369134, 36800, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143717047, 143718305, 9369149, 9370407, 19094, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234637658, 234639889, 9370422, 9372653, 35185, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203298034, 203304023, 9372668, 9378657, 28927, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54681323, 54697194, 9378672, 9394543, 8435, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233469419, 233477295, 9394558, 9402434, 34803, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60193617, 60195725, 9402449, 9404557, 9501, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 201467108, 201467177, 9404572, 9404641, 28694, "entier"], ["github/C++", "opencv/opencv", "C++", 111563745, 111577164, 9404656, 9418075, 15007, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 15850853, 15863111, 9418090, 9430348, 2072, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58875563, 58877643, 9430363, 9432443, 9312, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172785194, 172790698, 9432458, 9437962, 23304, "entier"], ["github/Java", "google/guava", "Java", 135582836, 135598573, 9437977, 9453714, 17293, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21292111, 21294623, 9453729, 9456241, 2894, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205379799, 205383862, 9456256, 9460319, 29614, "entier"], ["github/PHP", "laravel/framework", "PHP", 186912375, 186913500, 9460334, 9461459, 26004, "entier"], ["github/PHP", "laravel/framework", "PHP", 182920062, 182923365, 9461474, 9464777, 25187, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 56958397, 56964138, 9464792, 9470533, 9092, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39353979, 39355741, 9470548, 9472310, 5083, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 36049164, 36053728, 9472325, 9476889, 4653, "entier"], ["github/PHP", "laravel/framework", "PHP", 185193669, 185193800, 9476904, 9477035, 25517, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47898042, 47899514, 9477050, 9478522, 7067, "entier"], ["github/Python", "pallets/flask", "Python", 337631, 338060, 9478537, 9478966, 40, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194375770, 194377498, 9478981, 9480709, 27338, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137982253, 137987454, 9480724, 9485925, 18051, "entier"], ["github/Python", "django/django", "Python", 6873821, 6875042, 9485940, 9487161, 1197, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180130009, 180132894, 9487176, 9490061, 24414, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34889696, 34892903, 9490076, 9493283, 4473, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126262367, 126273188, 9493298, 9504119, 16135, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 64070299, 64073933, 9504134, 9507768, 9942, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44894216, 44899102, 9507783, 9512669, 6447, "entier"], ["github/Scala", "scala/scala", "Scala", 220147447, 220178150, 9512684, 9543387, 32462, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19022016, 19022091, 9543402, 9543477, 2492, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211924960, 211934482, 9543492, 9553014, 31359, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139567732, 139572364, 9553029, 9557661, 18354, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21856164, 21856945, 9557676, 9558457, 2986, "entier"], ["github/PHP", "laravel/framework", "PHP", 185280996, 185287367, 9558472, 9564843, 25552, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56015641, 56015744, 9564858, 9564961, 8667, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10761526, 10767750, 9564976, 9571200, 1725, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 29809625, 29811769, 9571215, 9573359, 4013, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136672342, 136673506, 9573374, 9574538, 17728, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43010565, 43013037, 9574553, 9577025, 5692, "entier"], ["github/Java", "apache/commons-lang", "Java", 154455833, 154458219, 9577040, 9579426, 20400, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52739629, 52739712, 9579441, 9579524, 7987, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18095967, 18096970, 9579539, 9580542, 2187, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60110356, 60116411, 9580557, 9586612, 9478, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52277860, 52277992, 9586627, 9586759, 7865, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52797668, 52797994, 9586774, 9587100, 8022, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27296451, 27296724, 9587115, 9587388, 3614, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175020159, 175023704, 9587403, 9590948, 23629, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194479573, 194480520, 9590963, 9591910, 27386, "entier"], ["github/PHP", "laravel/framework", "PHP", 186524513, 186525006, 9591925, 9592418, 25902, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43499990, 43502178, 9592433, 9594621, 5840, "entier"], ["github/Java", "square/okhttp", "Java", 144847232, 144850506, 9594636, 9597910, 19383, "entier"], ["github/PHP", "laravel/framework", "PHP", 185545945, 185546131, 9597925, 9598111, 25614, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193328560, 193329051, 9598126, 9598617, 27193, "entier"], ["github/Python", "django/django", "Python", 6006719, 6009598, 9598632, 9601511, 1021, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71505111, 71505493, 9601526, 9601908, 10729, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46872920, 46874848, 9601923, 9603851, 6912, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210081533, 210082449, 9603866, 9604782, 30858, "entier"], ["github/PHP", "laravel/framework", "PHP", 183716345, 183718796, 9604797, 9607248, 25302, "entier"], ["github/Java", "square/okhttp", "Java", 145136797, 145141211, 9607263, 9611677, 19457, "entier"], ["github/Python", "django/django", "Python", 3830977, 3832177, 9611692, 9612892, 679, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50966157, 50967371, 9612907, 9614121, 7212, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45124796, 45125682, 9614136, 9615022, 6628, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189758936, 189760955, 9615037, 9617056, 26498, "entier"], ["github/Java", "apache/commons-lang", "Java", 154176466, 154177747, 9617071, 9618352, 20357, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142907512, 142909366, 9618367, 9620221, 18935, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172206537, 172210104, 9620236, 9623803, 23206, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208705457, 208710864, 9623818, 9629225, 30456, "entier"], ["github/C++", "opencv/opencv", "C++", 112182626, 112207685, 9629240, 9654299, 15041, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41972637, 41978697, 9654314, 9660374, 5365, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238370327, 238370352, 9660389, 9660414, 36200, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230372368, 230373492, 9660429, 9661553, 34195, "entier"], ["github/Python", "django/django", "Python", 8161347, 8171841, 9661568, 9672062, 1312, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34999137, 35018997, 9672077, 9691937, 4489, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230434821, 230435751, 9691952, 9692882, 34226, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190108691, 190117776, 9692897, 9701982, 26578, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202666530, 202667421, 9701997, 9702888, 28878, "entier"], ["github/Java", "google/guava", "Java", 132605319, 132618789, 9702903, 9716373, 16988, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179451983, 179454390, 9716388, 9718795, 24313, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44541727, 44544312, 9718810, 9721395, 6338, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43616202, 43616403, 9721410, 9721611, 5987, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45965190, 45966528, 9721626, 9722964, 6814, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207722660, 207728558, 9722979, 9728877, 30236, "entier"], ["github/Python", "django/django", "Python", 9094919, 9095849, 9728892, 9729822, 1412, "entier"], ["github/Python", "django/django", "Python", 3178003, 3178863, 9729837, 9730697, 609, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228675575, 228688573, 9730712, 9743710, 33655, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45986164, 45989280, 9743725, 9746841, 6826, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173478442, 173480833, 9746856, 9749247, 23408, "entier"], ["github/Java", "google/guava", "Java", 130728281, 130734830, 9749262, 9755811, 16767, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55499724, 55501623, 9755826, 9757725, 8526, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 167533962, 167622993, 9757740, 9846771, 22316, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206203786, 206204531, 9846786, 9847531, 29872, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27609374, 27609700, 9847546, 9847872, 3714, "entier"], ["github/Java", "apache/commons-lang", "Java", 154039063, 154040396, 9847887, 9849220, 20339, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208092207, 208092965, 9849235, 9849993, 30324, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 214632188, 214655375, 9850008, 9873195, 31866, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 181252920, 181255192, 9873210, 9875482, 24663, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10043933, 10052864, 9875497, 9884428, 1611, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143554352, 143556484, 9884443, 9886575, 19053, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204895179, 204896910, 9886590, 9888321, 29443, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238169560, 238171544, 9888336, 9890320, 35831, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238354445, 238354464, 9890335, 9890354, 36151, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37368715, 37378478, 9890369, 9900132, 4779, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137591753, 137598391, 9900147, 9906785, 17961, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227035959, 227036972, 9906800, 9907813, 33416, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178863999, 178865713, 9907828, 9909542, 24208, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234895934, 234896177, 9909557, 9909800, 35272, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229674648, 229675330, 9909815, 9910497, 33903, "entier"], ["github/PHP", "laravel/framework", "PHP", 184776729, 184799339, 9910512, 9933122, 25418, "entier"], ["github/Python", "django/django", "Python", 4412328, 4413442, 9933137, 9934251, 768, "entier"], ["github/Java", "google/guava", "Java", 134475309, 134475992, 9934266, 9934949, 17174, "entier"], ["github/Scala", "sbt/sbt", "Scala", 239199655, 239202516, 9934964, 9937825, 36878, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203613037, 203619817, 9937840, 9944620, 28991, "entier"], ["github/Python", "django/django", "Python", 915301, 916656, 9944635, 9945990, 127, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 32751923, 32766779, 9946005, 9960861, 4211, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230368353, 230368800, 9960876, 9961323, 34191, "entier"], ["github/Java", "google/guava", "Java", 135697996, 135702605, 9961338, 9965947, 17302, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230386334, 230386746, 9965962, 9966374, 34211, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37686301, 37686335, 9966389, 9966423, 4853, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43517411, 43517575, 9966438, 9966602, 5867, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177495754, 177498592, 9966617, 9969455, 24003, "entier"], ["github/Python", "django/django", "Python", 9059211, 9061609, 9969470, 9971868, 1405, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 73238660, 73293905, 9971883, 10027128, 10953, "entier"], ["github/Scala", "scala/scala", "Scala", 223479518, 223483675, 10027143, 10031300, 32774, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138918940, 138922132, 10031315, 10034507, 18241, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138240859, 138241808, 10034522, 10035471, 18126, "entier"], ["github/Scala", "scala/scala", "Scala", 217319018, 217319837, 10035486, 10036305, 32205, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238412673, 238412713, 10036320, 10036360, 36375, "entier"], ["github/Java", "google/guava", "Java", 135664981, 135668440, 10036375, 10039834, 17299, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10469187, 10475072, 10039849, 10045734, 1684, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206743200, 206746849, 10045749, 10049398, 30004, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177560555, 177563776, 10049413, 10052634, 24027, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139474784, 139476357, 10052649, 10054222, 18345, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226723978, 226730128, 10054237, 10060387, 33343, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206203455, 206203771, 10060402, 10060718, 29871, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138791423, 138797154, 10060733, 10066464, 18223, "entier"], ["github/Python", "django/django", "Python", 2157463, 2158974, 10066479, 10067990, 426, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209913449, 209914979, 10068005, 10069535, 30770, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9513293, 9513692, 10069550, 10069949, 1503, "entier"], ["github/Scala", "scala/scala", "Scala", 223970406, 223971328, 10069964, 10070886, 32835, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200196935, 200198034, 10070901, 10072000, 28409, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 12644495, 12646019, 10072015, 10073539, 1877, "entier"], ["github/Python", "django/django", "Python", 5498386, 5499158, 10073554, 10074326, 942, "entier"], ["github/PHP", "laravel/framework", "PHP", 184403892, 184410302, 10074341, 10080751, 25364, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210898817, 210902194, 10080766, 10084143, 31115, "entier"], ["github/Java", "square/okhttp", "Java", 146385905, 146397825, 10084158, 10096078, 19657, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46443962, 46475266, 10096093, 10127397, 6875, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 29785537, 29803643, 10127412, 10145518, 4010, "entier"], ["github/PHP", "laravel/framework", "PHP", 189422232, 189426271, 10145533, 10149572, 26463, "entier"], ["github/Scala", "scala/scala", "Scala", 225458464, 225474262, 10149587, 10165385, 33152, "entier"], ["github/Java", "square/okhttp", "Java", 146724188, 146725031, 10165400, 10166243, 19712, "entier"], ["github/Java", "google/guava", "Java", 132012027, 132013331, 10166258, 10167562, 16886, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176652573, 176664275, 10167577, 10179279, 23805, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194484898, 194485805, 10179294, 10180201, 27392, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138128991, 138129924, 10180216, 10181149, 18083, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209682633, 209691851, 10181164, 10190382, 30698, "entier"], ["github/Java", "google/guava", "Java", 133503270, 133507598, 10190397, 10194725, 17102, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194491271, 194495805, 10194740, 10199274, 27399, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 12624258, 12644480, 10199289, 10219511, 1876, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138780140, 138781927, 10219526, 10221313, 18219, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233883846, 233884905, 10221328, 10222387, 34940, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 123897459, 123988670, 10222402, 10313613, 15991, "entier"], ["github/Java", "google/guava", "Java", 129170103, 129171704, 10313628, 10315229, 16586, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 27066204, 27067168, 10315244, 10316208, 3561, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191042267, 191043497, 10316223, 10317453, 26790, "entier"], ["github/Java", "google/guava", "Java", 132185869, 132188004, 10317468, 10319603, 16913, "entier"], ["github/PHP", "laravel/framework", "PHP", 182589607, 182590088, 10319618, 10320099, 25057, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 27068281, 27071130, 10320114, 10322963, 3566, "entier"], ["github/Java", "apache/commons-lang", "Java", 154943686, 154945428, 10322978, 10324720, 20489, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197429924, 197432654, 10324735, 10327465, 27983, "entier"], ["github/Java", "apache/commons-lang", "Java", 154713905, 154715995, 10327480, 10329570, 20445, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192211315, 192212245, 10329585, 10330515, 26940, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43948813, 43950102, 10330530, 10331819, 6187, "entier"], ["github/C", "curl/curl", "C", 96506946, 96680888, 10331834, 10505776, 13207, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53049322, 53049494, 10505791, 10505963, 8109, "entier"], ["github/Java", "google/guava", "Java", 129756673, 129760408, 10505978, 10509713, 16669, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27983906, 27989241, 10509728, 10515063, 3801, "entier"], ["github/Scala", "playframework/playframework", "Scala", 225842948, 225858636, 10515078, 10530766, 33195, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204650304, 204656888, 10530781, 10537365, 29290, "entier"], ["github/Java", "apache/commons-lang", "Java", 150802637, 150804143, 10537380, 10538886, 20150, "entier"], ["github/Java", "google/guava", "Java", 135960500, 135963632, 10538901, 10542033, 17325, "entier"], ["github/Python", "django/django", "Python", 918573, 919760, 10542048, 10543235, 130, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174006831, 174010837, 10543250, 10547256, 23458, "entier"], ["github/Python", "django/django", "Python", 5013014, 5015440, 10547271, 10549697, 892, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39369799, 39381756, 10549712, 10561669, 5087, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190037650, 190051342, 10561684, 10575376, 26569, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234125842, 234126445, 10575391, 10575994, 35095, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144196644, 144205295, 10576009, 10584660, 19194, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208976653, 208980541, 10584675, 10588563, 30524, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 181011807, 181012667, 10588578, 10589438, 24618, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10557357, 10561431, 10589453, 10593527, 1696, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177294104, 177294859, 10593542, 10594297, 23943, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206530562, 206531487, 10594312, 10595237, 29964, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51167750, 51167900, 10595252, 10595402, 7291, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33480257, 33495654, 10595417, 10610814, 4283, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172257253, 172258229, 10610829, 10611805, 23221, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56325783, 56326926, 10611820, 10612963, 8889, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213399873, 213400204, 10612978, 10613309, 31585, "entier"], ["github/Java", "google/guava", "Java", 132016372, 132022804, 10613324, 10619756, 16889, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207579003, 207579169, 10619771, 10619937, 30179, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204870038, 204870369, 10619952, 10620283, 29423, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208145844, 208146133, 10620298, 10620587, 30348, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228729764, 228741261, 10620602, 10632099, 33676, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177293418, 177294089, 10632114, 10632785, 23942, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44336960, 44341539, 10632800, 10637379, 6278, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143719593, 143721184, 10637394, 10638985, 19096, "entier"], ["github/Python", "django/django", "Python", 4569050, 4577059, 10639000, 10647009, 793, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178272924, 178275633, 10647024, 10649733, 24141, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202365327, 202371240, 10649748, 10655661, 28840, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51810331, 51810980, 10655676, 10656325, 7675, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198426226, 198434898, 10656340, 10665012, 28172, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47155518, 47157585, 10665027, 10667094, 6959, "entier"], ["github/Java", "google/guava", "Java", 135735254, 135745007, 10667109, 10676862, 17306, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 68617779, 68657184, 10676877, 10716282, 10453, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237572421, 237574155, 10716297, 10718031, 35710, "entier"], ["github/Python", "django/django", "Python", 5003232, 5003838, 10718046, 10718652, 859, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43748116, 43748282, 10718667, 10718833, 6134, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233983201, 233984183, 10718848, 10719830, 35000, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43675270, 43675480, 10719845, 10720055, 6068, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238439807, 238440054, 10720070, 10720317, 36609, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238303163, 238303270, 10720332, 10720439, 35937, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51791463, 51792888, 10720454, 10721879, 7658, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159471747, 159480621, 10721894, 10730768, 21125, "entier"], ["github/Python", "django/django", "Python", 2196053, 2197858, 10730783, 10732588, 437, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56428665, 56429690, 10732603, 10733628, 9000, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43612509, 43613099, 10733643, 10734233, 5981, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193030626, 193031053, 10734248, 10734675, 27069, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37697930, 37698309, 10734690, 10735069, 4879, "entier"], ["github/Go", "prometheus/prometheus", "Go", 80632562, 80812361, 10735084, 10914883, 11554, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45289276, 45290092, 10914898, 10915714, 6716, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43613649, 43613862, 10915729, 10915942, 5983, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45155023, 45157123, 10915957, 10918057, 6649, "entier"], ["github/Java", "apache/commons-lang", "Java", 155579435, 155590216, 10918072, 10928853, 20548, "entier"], ["github/Python", "django/django", "Python", 7605045, 7612086, 10928868, 10935909, 1267, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203920934, 203927830, 10935924, 10942820, 29079, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51474626, 51475563, 10942835, 10943772, 7505, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157043442, 157043979, 10943787, 10944324, 20636, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28479164, 28494013, 10944339, 10959188, 3905, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51747554, 51747794, 10959203, 10959443, 7627, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54431917, 54432171, 10959458, 10959712, 8334, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169890776, 169892701, 10959727, 10961652, 22776, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54533751, 54537434, 10961667, 10965350, 8410, "entier"], ["github/Java", "apache/commons-lang", "Java", 155518668, 155520483, 10965365, 10967180, 20542, "entier"], ["github/Python", "psf/requests", "Python", 112546, 113450, 10967195, 10968099, 16, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160757450, 160757841, 10968114, 10968505, 21236, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230934559, 230956121, 10968520, 10990082, 34401, "entier"], ["github/Python", "django/django", "Python", 934656, 935367, 10990097, 10990808, 142, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157718436, 157719581, 10990823, 10991968, 20785, "entier"], ["github/PHP", "laravel/framework", "PHP", 186562961, 186578950, 10991983, 11007972, 25917, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 119340605, 119343670, 11007987, 11011052, 15530, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168277269, 168278617, 11011067, 11012415, 22437, "entier"], ["github/Python", "django/django", "Python", 6425814, 6429063, 11012430, 11015679, 1106, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137234528, 137242763, 11015694, 11023929, 17885, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161002678, 161003594, 11023944, 11024860, 21328, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161222676, 161224081, 11024875, 11026280, 21368, "entier"], ["github/C++", "opencv/opencv", "C++", 118285015, 118291982, 11026295, 11033262, 15498, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143581967, 143583643, 11033277, 11034953, 19060, "entier"], ["github/Python", "django/django", "Python", 2277414, 2281800, 11034968, 11039354, 457, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170363575, 170364807, 11039369, 11040601, 22818, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47700317, 47713179, 11040616, 11053478, 7028, "entier"], ["github/Java", "google/guava", "Java", 129171719, 129173785, 11053493, 11055559, 16587, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157182049, 157182440, 11055574, 11055965, 20670, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179840875, 179860567, 11055980, 11075672, 24362, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19938434, 19945105, 11075687, 11082358, 2781, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163406336, 163407416, 11082373, 11083453, 21696, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209887209, 209901065, 11083468, 11097324, 30766, "entier"], ["github/PHP", "laravel/framework", "PHP", 182534473, 182534985, 11097339, 11097851, 25000, "entier"], ["github/PHP", "laravel/framework", "PHP", 181819762, 181819991, 11097866, 11098095, 24810, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234016379, 234017972, 11098110, 11099703, 35021, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193375409, 193376876, 11099718, 11101185, 27209, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230370102, 230371993, 11101200, 11103091, 34193, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 123625234, 123633795, 11103106, 11111667, 15976, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27601724, 27602417, 11111682, 11112375, 3710, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58870735, 58875548, 11112390, 11117203, 9311, "entier"], ["github/Java", "google/guava", "Java", 128150719, 128163539, 11117218, 11130038, 16370, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27458839, 27458930, 11130053, 11130144, 3679, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 167753885, 167758790, 11130159, 11135064, 22324, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 37908104, 37908603, 11135079, 11135578, 4928, "entier"], ["github/Python", "django/django", "Python", 2163066, 2173321, 11135593, 11145848, 428, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230294578, 230301746, 11145863, 11153031, 34144, "entier"], ["github/C++", "google/leveldb", "C++", 110827142, 110828038, 11153046, 11153942, 14884, "entier"], ["github/PHP", "laravel/framework", "PHP", 186412764, 186421801, 11153957, 11162994, 25859, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216045387, 216048114, 11163009, 11165736, 32010, "entier"], ["github/C++", "opencv/opencv", "C++", 116665376, 116667431, 11165751, 11167806, 15329, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42755487, 42762647, 11167821, 11174981, 5600, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121677173, 121679799, 11174996, 11177622, 15769, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237970731, 237972396, 11177637, 11179302, 35779, "entier"], ["github/Java", "google/guava", "Java", 130946256, 130953490, 11179317, 11186551, 16798, "entier"], ["github/C++", "fmtlib/fmt", "C++", 109886528, 109886988, 11186566, 11187026, 14764, "entier"], ["github/Python", "django/django", "Python", 2173906, 2175269, 11187041, 11188404, 431, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230544770, 230546605, 11188419, 11190254, 34286, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43536605, 43537212, 11190269, 11190876, 5901, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 123139400, 123142434, 11190891, 11193925, 15936, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56299882, 56300138, 11193940, 11194196, 8850, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 171116471, 171125553, 11194211, 11203293, 22908, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56380758, 56381236, 11203308, 11203786, 8957, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230277156, 230278572, 11203801, 11205217, 34138, "entier"], ["github/Java", "google/guava", "Java", 132412307, 132413917, 11205232, 11206842, 16950, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43673633, 43673952, 11206857, 11207176, 6062, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200672070, 200677943, 11207191, 11213064, 28552, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56073446, 56074039, 11213079, 11213672, 8688, "entier"], ["github/PHP", "laravel/framework", "PHP", 187614145, 187618262, 11213687, 11217804, 26154, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54451914, 54452331, 11217819, 11218236, 8355, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53324262, 53324350, 11218251, 11218339, 8192, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54286459, 54286572, 11218354, 11218467, 8304, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52161832, 52162059, 11218482, 11218709, 7793, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44927997, 44928414, 11218724, 11219141, 6473, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140197086, 140202408, 11219156, 11224478, 18455, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237462373, 237468042, 11224493, 11230162, 35695, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195532155, 195534686, 11230177, 11232708, 27642, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50895315, 50900358, 11232723, 11237766, 7192, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10870981, 10881305, 11237781, 11248105, 1750, "entier"], ["github/Java", "google/guava", "Java", 132272719, 132274389, 11248120, 11249790, 16933, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140040528, 140042406, 11249805, 11251683, 18416, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 72892325, 72918049, 11251698, 11277422, 10942, "entier"], ["github/Scala", "scala/scala", "Scala", 222378644, 222380117, 11277437, 11278910, 32689, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136684471, 136686255, 11278925, 11280709, 17736, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213647615, 213652208, 11280724, 11285317, 31653, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 30737512, 30769828, 11285332, 11317648, 4098, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 125064719, 125082033, 11317663, 11334977, 16055, "entier"], ["github/Scala", "scala/scala", "Scala", 221593464, 221594619, 11334992, 11336147, 32585, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37044662, 37046587, 11336162, 11338087, 4747, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143955135, 143956904, 11338102, 11339871, 19146, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229731778, 229732023, 11339886, 11340131, 33936, "entier"], ["github/PHP", "laravel/framework", "PHP", 189451303, 189457389, 11340146, 11346232, 26467, "entier"], ["github/Scala", "scala/scala", "Scala", 224649779, 224651562, 11346247, 11348030, 33068, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136192895, 136194252, 11348045, 11349402, 17377, "entier"], ["github/Java", "google/guava", "Java", 131272381, 131273645, 11349417, 11350681, 16838, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11081769, 11083649, 11350696, 11352576, 1785, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53074444, 53080229, 11352591, 11358376, 8130, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215757998, 215760431, 11358391, 11360824, 31950, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138677206, 138681724, 11360839, 11365357, 18201, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230426164, 230430964, 11365372, 11370172, 34221, "entier"], ["github/Python", "django/django", "Python", 2578948, 2579547, 11370187, 11370786, 543, "entier"], ["github/C++", "opencv/opencv", "C++", 116470079, 116470165, 11370801, 11370887, 15290, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45163048, 45163606, 11370902, 11371460, 6656, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230867592, 230868331, 11371475, 11372214, 34383, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51639415, 51639699, 11372229, 11372513, 7578, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10705964, 10710505, 11372528, 11377069, 1718, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43547519, 43547850, 11377084, 11377415, 5911, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229556256, 229556571, 11377430, 11377745, 33848, "entier"], ["github/PHP", "laravel/framework", "PHP", 182751512, 182760643, 11377760, 11386891, 25125, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51145434, 51148276, 11386906, 11389748, 7275, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165073290, 165092552, 11389763, 11409025, 22028, "entier"], ["github/C++", "opencv/opencv", "C++", 117415616, 117423606, 11409040, 11417030, 15464, "entier"], ["github/Java", "square/okhttp", "Java", 146061822, 146073722, 11417045, 11428945, 19605, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205572282, 205584396, 11428960, 11441074, 29669, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44298188, 44299476, 11441089, 11442377, 6264, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178157686, 178172339, 11442392, 11457045, 24127, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44160315, 44160681, 11457060, 11457426, 6241, "entier"], ["github/PHP", "laravel/framework", "PHP", 188852264, 188852785, 11457441, 11457962, 26386, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9656675, 9664943, 11457977, 11466245, 1542, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197063386, 197064165, 11466260, 11467039, 27899, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121799070, 121802757, 11467054, 11470741, 15806, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143479589, 143482852, 11470756, 11474019, 19032, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 49195285, 49201662, 11474034, 11480411, 7125, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63995567, 64002066, 11480426, 11486925, 9928, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138922147, 138924459, 11486940, 11489252, 18242, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142085790, 142086676, 11489267, 11490153, 18762, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27642238, 27645580, 11490168, 11493510, 3723, "entier"], ["github/C++", "opencv/opencv", "C++", 118212565, 118221712, 11493525, 11502672, 15489, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205696845, 205701024, 11502687, 11506866, 29700, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164278108, 164279251, 11506881, 11508024, 21886, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 22665550, 22672489, 11508039, 11514978, 3087, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162737846, 162738266, 11514993, 11515413, 21604, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200444981, 200445029, 11515428, 11515476, 28486, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209950980, 209951872, 11515491, 11516383, 30793, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170625652, 170627995, 11516398, 11518741, 22861, "entier"], ["github/Java", "google/guava", "Java", 130055637, 130078119, 11518756, 11541238, 16700, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211336135, 211337797, 11541253, 11542915, 31194, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161037217, 161038110, 11542930, 11543823, 21338, "entier"], ["github/Python", "django/django", "Python", 3056950, 3073716, 11543838, 11560604, 598, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 57301324, 57319952, 11560619, 11579247, 9111, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25359052, 25361954, 11579262, 11582164, 3318, "entier"], ["github/PHP", "laravel/framework", "PHP", 189086307, 189113291, 11582179, 11609163, 26416, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168559196, 168560742, 11609178, 11610724, 22600, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 20730722, 20731113, 11610739, 11611130, 2812, "entier"], ["github/Scala", "scala/scala", "Scala", 218422382, 218473207, 11611145, 11661970, 32333, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168521718, 168523290, 11661985, 11663557, 22577, "entier"], ["github/C++", "opencv/opencv", "C++", 118291997, 118310853, 11663572, 11682428, 15499, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208751538, 208759243, 11682443, 11690148, 30468, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173437060, 173445031, 11690163, 11698134, 23399, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 20902454, 20908682, 11698149, 11704377, 2834, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141559320, 141561745, 11704392, 11706817, 18570, "entier"], ["github/Java", "google/guava", "Java", 132669914, 132674819, 11706832, 11711737, 16996, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38333796, 38372649, 11711752, 11750605, 4976, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19057702, 19058047, 11750620, 11750965, 2564, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65399405, 65399513, 11750980, 11751088, 10103, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205295860, 205296853, 11751103, 11752096, 29579, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 28009092, 28011565, 11752111, 11754584, 3810, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 125362888, 125363957, 11754599, 11755668, 16076, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120295544, 120296094, 11755683, 11756233, 15622, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10462699, 10469172, 11756248, 11762721, 1683, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33585715, 33586444, 11762736, 11763465, 4299, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158580386, 158594123, 11763480, 11777217, 20977, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137465433, 137475158, 11777232, 11786957, 17935, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19118390, 19119873, 11786972, 11788455, 2663, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173114992, 173115603, 11788470, 11789081, 23342, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 215215771, 215224660, 11789096, 11797985, 31901, "entier"], ["github/Python", "django/django", "Python", 2249375, 2249626, 11798000, 11798251, 449, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199410553, 199412784, 11798266, 11800497, 28243, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144541095, 144541312, 11800512, 11800729, 19298, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33653303, 33658616, 11800744, 11806057, 4323, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10941030, 10945119, 11806072, 11810161, 1759, "entier"], ["github/C++", "nlohmann/json", "C++", 108334787, 108349625, 11810176, 11825014, 14678, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60432991, 60448293, 11825029, 11840331, 9538, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200709810, 200721509, 11840346, 11852045, 28559, "entier"], ["github/Java", "square/okhttp", "Java", 146930413, 146937984, 11852060, 11859631, 19750, "entier"], ["github/PHP", "laravel/framework", "PHP", 187438282, 187443696, 11859646, 11865060, 26119, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21773828, 21774596, 11865075, 11865843, 2949, "entier"], ["github/Python", "django/django", "Python", 2116278, 2118234, 11865858, 11867814, 406, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159499738, 159500572, 11867829, 11868663, 21140, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10430550, 10432528, 11868678, 11870656, 1673, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142516133, 142519050, 11870671, 11873588, 18861, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193077649, 193078194, 11873603, 11874148, 27117, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 29643817, 29650713, 11874163, 11881059, 4001, "entier"], ["github/Java", "google/guava", "Java", 127849487, 127851873, 11881074, 11883460, 16301, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171607083, 171618529, 11883475, 11894921, 22972, "entier"], ["github/PHP", "symfony/symfony", "PHP", 198125716, 198129915, 11894936, 11899135, 28130, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9369394, 9372920, 11899150, 11902676, 1475, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 127324581, 127330920, 11902691, 11909030, 16257, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169139640, 169146610, 11909045, 11916015, 22746, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207877900, 207878589, 11916030, 11916719, 30266, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237589265, 237591896, 11916734, 11919365, 35720, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51320543, 51320926, 11919380, 11919763, 7433, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54423053, 54423460, 11919778, 11920185, 8322, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204147082, 204148594, 11920200, 11921712, 29136, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56289312, 56290360, 11921727, 11922775, 8833, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196466198, 196468642, 11922790, 11925234, 27805, "entier"], ["github/C++", "nlohmann/json", "C++", 104123113, 104124277, 11925249, 11926413, 14393, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209134814, 209135160, 11926428, 11926774, 30580, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227211286, 227214073, 11926789, 11929576, 33483, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 36100553, 36105183, 11929591, 11934221, 4659, "entier"], ["github/PHP", "laravel/framework", "PHP", 183740496, 183740642, 11934236, 11934382, 25308, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52039521, 52041629, 11934397, 11936505, 7736, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210240735, 210241351, 11936520, 11937136, 30911, "entier"], ["github/Java", "apache/commons-lang", "Java", 154106199, 154120718, 11937151, 11951670, 20348, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210044791, 210045215, 11951685, 11952109, 30837, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238368529, 238368561, 11952124, 11952156, 36194, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236250673, 236250968, 11952171, 11952466, 35550, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43509587, 43510579, 11952481, 11953473, 5854, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203864853, 203866049, 11953488, 11954684, 29061, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162265952, 162267477, 11954699, 11956224, 21502, "entier"], ["github/Scala", "scala/scala", "Scala", 217390663, 217393025, 11956239, 11958601, 32218, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 119987345, 119993735, 11958616, 11965006, 15592, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190689277, 190693766, 11965021, 11969510, 26686, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56356222, 56357560, 11969525, 11970863, 8927, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207838565, 207839341, 11970878, 11971654, 30260, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56361553, 56361751, 11971669, 11971867, 8933, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52496053, 52497459, 11971882, 11973288, 7933, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71964837, 71981704, 11973303, 11990170, 10914, "entier"], ["github/Scala", "scala/scala", "Scala", 223881443, 223884453, 11990185, 11993195, 32828, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 12380659, 12394368, 11993210, 12006919, 1858, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 122752101, 122753812, 12006934, 12008645, 15900, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56340989, 56342897, 12008660, 12010568, 8904, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200600886, 200604195, 12010583, 12013892, 28530, "entier"], ["github/Java", "google/guava", "Java", 128272360, 128275269, 12013907, 12016816, 16400, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164663431, 164668517, 12016831, 12021917, 21966, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 123136467, 123137012, 12021932, 12022477, 15932, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230203374, 230204215, 12022492, 12023333, 34072, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172065957, 172066790, 12023348, 12024181, 23176, "entier"], ["github/C++", "google/leveldb", "C++", 110738921, 110741848, 12024196, 12027123, 14871, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 20732004, 20742656, 12027138, 12037790, 2815, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42971289, 42974283, 12037805, 12040799, 5675, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192561856, 192569980, 12040814, 12048938, 27019, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227164790, 227169614, 12048953, 12053777, 33467, "entier"], ["github/C++", "nlohmann/json", "C++", 104027190, 104027628, 12053792, 12054230, 14267, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162482528, 162483637, 12054245, 12055354, 21531, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43636106, 43637574, 12055369, 12056837, 6011, "entier"], ["github/C++", "opencv/opencv", "C++", 117330618, 117334778, 12056852, 12061012, 15461, "entier"], ["github/Java", "google/guava", "Java", 129234251, 129247668, 12061027, 12074444, 16598, "entier"], ["github/Scala", "playframework/playframework", "Scala", 233344349, 233345079, 12074459, 12075189, 34781, "entier"], ["github/Python", "django/django", "Python", 988385, 989073, 12075204, 12075892, 186, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238327754, 238329198, 12075907, 12077351, 36073, "entier"], ["github/PHP", "laravel/framework", "PHP", 182619725, 182619992, 12077366, 12077633, 25096, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10148748, 10150470, 12077648, 12079370, 1627, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 50329664, 50335394, 12079385, 12085115, 7157, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197864761, 197866036, 12085130, 12086405, 28073, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202099098, 202108317, 12086420, 12095639, 28744, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216533743, 216534188, 12095654, 12096099, 32138, "entier"], ["github/Python", "django/django", "Python", 6626842, 6628487, 12096114, 12097759, 1155, "entier"], ["github/C++", "opencv/opencv", "C++", 112854385, 112861285, 12097774, 12104674, 15108, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24068241, 24074414, 12104689, 12110862, 3167, "entier"], ["github/Python", "django/django", "Python", 948482, 950205, 12110877, 12112600, 158, "entier"], ["github/Java", "google/guava", "Java", 130324166, 130328357, 12112615, 12116806, 16716, "entier"], ["github/Scala", "scala/scala", "Scala", 219228473, 219238069, 12116821, 12126417, 32395, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 156611209, 156622122, 12126432, 12137345, 20615, "entier"], ["github/C", "madler/zlib", "C", 102326337, 102334137, 12137360, 12145160, 14030, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 68396833, 68405925, 12145175, 12154267, 10438, "entier"], ["github/C++", "nlohmann/json", "C++", 104027643, 104028260, 12154282, 12154899, 14268, "entier"], ["github/Python", "django/django", "Python", 7669208, 7670219, 12154914, 12155925, 1278, "entier"], ["github/Go", "spf13/cobra", "Go", 76088385, 76101996, 12155940, 12169551, 11209, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43857376, 43863776, 12169566, 12175966, 6168, "entier"], ["github/Java", "square/okhttp", "Java", 147348095, 147351288, 12175981, 12179174, 19769, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205426672, 205427244, 12179189, 12179761, 29624, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173191277, 173204764, 12179776, 12193263, 23362, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200094333, 200095688, 12193278, 12194633, 28366, "entier"], ["github/Scala", "scala/scala", "Scala", 221527123, 221527938, 12194648, 12195463, 32570, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120008233, 120017347, 12195478, 12204592, 15596, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26843946, 26849360, 12204607, 12210021, 3487, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228087440, 228088532, 12210036, 12211128, 33568, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202254811, 202255432, 12211143, 12211764, 28798, "entier"], ["github/PHP", "laravel/framework", "PHP", 186729475, 186746498, 12211779, 12228802, 25987, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206905627, 206906622, 12228817, 12229812, 30023, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9851934, 9861871, 12229827, 12239764, 1572, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160865137, 160865615, 12239779, 12240257, 21282, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157335419, 157336359, 12240272, 12241212, 20714, "entier"], ["github/C++", "nlohmann/json", "C++", 104104871, 104105094, 12241227, 12241450, 14365, "entier"], ["github/JavaScript", "lodash/lodash", "JavaScript", 18670337, 18671347, 12241465, 12242475, 2332, "entier"], ["github/C++", "nlohmann/json", "C++", 109121891, 109122434, 12242490, 12243033, 14703, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38538602, 38547272, 12243048, 12251718, 4990, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126705985, 126706398, 12251733, 12252146, 16195, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19463428, 19463794, 12252161, 12252527, 2733, "entier"], ["github/C++", "nlohmann/json", "C++", 104072308, 104072730, 12252542, 12252964, 14328, "entier"], ["github/C", "madler/zlib", "C", 102718129, 102722687, 12252979, 12257537, 14053, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28160334, 28160923, 12257552, 12258141, 3845, "entier"], ["github/Swift", "vapor/vapor", "Swift", 217182737, 217186108, 12258156, 12261527, 32186, "entier"], ["github/C++", "nlohmann/json", "C++", 104153442, 104154003, 12261542, 12262103, 14426, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90492271, 90493305, 12262118, 12263152, 12598, "entier"], ["github/C++", "nlohmann/json", "C++", 104128261, 104128966, 12263167, 12263872, 14400, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165634139, 165637024, 12263887, 12266772, 22100, "entier"], ["github/Scala", "playframework/playframework", "Scala", 225983092, 225995326, 12266787, 12279021, 33233, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 42055863, 42056042, 12279036, 12279215, 5390, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169222536, 169224108, 12279230, 12280802, 22754, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45223184, 45223641, 12280817, 12281274, 6692, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45921807, 45923170, 12281289, 12282652, 6799, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 23157049, 23166432, 12282667, 12292050, 3119, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203082334, 203094733, 12292065, 12304464, 28902, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61704438, 61725244, 12304479, 12325285, 9638, "entier"], ["github/Java", "google/guava", "Java", 135268282, 135307182, 12325300, 12364200, 17251, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171957474, 171957900, 12364215, 12364641, 23142, "entier"], ["github/Python", "django/django", "Python", 1242715, 1251714, 12364656, 12373655, 220, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238341510, 238341578, 12373670, 12373738, 36097, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235281254, 235281917, 12373753, 12374416, 35369, "entier"], ["github/Go", "gohugoio/hugo", "Go", 84738192, 84750006, 12374431, 12386245, 11800, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173266489, 173267444, 12386260, 12387215, 23376, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229655882, 229656243, 12387230, 12387591, 33888, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229711522, 229712369, 12387606, 12388453, 33927, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165059047, 165065548, 12388468, 12394969, 22026, "entier"], ["github/Scala", "scala/scala", "Scala", 221700388, 221701584, 12394984, 12396180, 32626, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21924352, 21925078, 12396195, 12396921, 3026, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176968704, 176970725, 12396936, 12398957, 23844, "entier"], ["github/Python", "django/django", "Python", 4985539, 4986528, 12398972, 12399961, 849, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227013682, 227018360, 12399976, 12404654, 33410, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 22396104, 22400086, 12404669, 12408651, 3073, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38765339, 38783292, 12408666, 12426619, 5012, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238377242, 238377250, 12426634, 12426642, 36228, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215928989, 215930088, 12426657, 12427756, 31994, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231042160, 231043386, 12427771, 12428997, 34417, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18099274, 18100467, 12429012, 12430205, 2191, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238347668, 238347723, 12430220, 12430275, 36122, "entier"], ["github/Python", "django/django", "Python", 1806241, 1812235, 12430290, 12436284, 345, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177556627, 177560540, 12436299, 12440212, 24026, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27747410, 27748494, 12440227, 12441311, 3761, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197973453, 197997167, 12441326, 12465040, 28107, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212991677, 212997242, 12465055, 12470620, 31496, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90774867, 90779531, 12470635, 12475299, 12654, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159749516, 159757904, 12475314, 12483702, 21164, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25045437, 25049047, 12483717, 12487327, 3247, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10329073, 10331210, 12487342, 12489479, 1652, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175601903, 175602627, 12489494, 12490218, 23686, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9526187, 9526601, 12490233, 12490647, 1514, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209952887, 209954429, 12490662, 12492204, 30795, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51486982, 51487222, 12492219, 12492459, 7524, "entier"], ["github/Go", "gohugoio/hugo", "Go", 84581963, 84586806, 12492474, 12497317, 11776, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210226293, 210226722, 12497332, 12497761, 30902, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 49212593, 49214871, 12497776, 12500054, 7129, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 68208144, 68223808, 12500069, 12515733, 10425, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44926933, 44927982, 12515748, 12516797, 6472, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169884086, 169889156, 12516812, 12521882, 22774, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43318217, 43320064, 12521897, 12523744, 5744, "entier"], ["github/Go", "prometheus/prometheus", "Go", 76327475, 76329125, 12523759, 12525409, 11227, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176168989, 176175370, 12525424, 12531805, 23792, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88693903, 88695143, 12531820, 12533060, 12347, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42606953, 42609233, 12533075, 12535355, 5514, "entier"], ["github/PHP", "laravel/framework", "PHP", 183319509, 183320564, 12535370, 12536425, 25233, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18420624, 18437901, 12536440, 12553717, 2275, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56329579, 56329960, 12553732, 12554113, 8892, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78083585, 78085277, 12554128, 12555820, 11355, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51493054, 51494572, 12555835, 12557353, 7528, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193991729, 193994139, 12557368, 12559778, 27319, "entier"], ["github/Python", "django/django", "Python", 6716856, 6735754, 12559793, 12578691, 1181, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233762324, 233777502, 12578706, 12593884, 34932, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37637326, 37638120, 12593899, 12594693, 4826, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170967020, 170970444, 12594708, 12598132, 22890, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42694662, 42695099, 12598147, 12598584, 5573, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216124817, 216129285, 12598599, 12603067, 32027, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63319284, 63321261, 12603082, 12605059, 9815, "entier"], ["github/C", "curl/curl", "C", 97152681, 97194407, 12605074, 12646800, 13239, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200326173, 200342583, 12646815, 12663225, 28450, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39011656, 39017213, 12663240, 12668797, 5052, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177505675, 177507447, 12668812, 12670584, 24010, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71531208, 71532645, 12670599, 12672036, 10760, "entier"], ["github/Go", "prometheus/prometheus", "Go", 80462737, 80470975, 12672051, 12680289, 11542, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165597066, 165600747, 12680304, 12683985, 22086, "entier"], ["github/PHP", "laravel/framework", "PHP", 186379402, 186388374, 12684000, 12692972, 25851, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 56534823, 56537810, 12692987, 12695974, 9071, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18997909, 18998090, 12695989, 12696170, 2432, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171962297, 171963933, 12696185, 12697821, 23146, "entier"], ["github/Java", "square/okhttp", "Java", 148239147, 148299974, 12697836, 12758663, 19843, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24031104, 24033926, 12758678, 12761500, 3164, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165587313, 165590492, 12761515, 12764694, 22082, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 67677630, 67682584, 12764709, 12769663, 10388, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21792983, 21794233, 12769678, 12770928, 2955, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175670009, 175673278, 12770943, 12774212, 23707, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162577361, 162578570, 12774227, 12775436, 21558, "entier"], ["github/Scala", "sbt/sbt", "Scala", 239025511, 239088060, 12775451, 12838000, 36846, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 20972471, 20974401, 12838015, 12839945, 2850, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88029784, 88035775, 12839960, 12845951, 12240, "entier"], ["github/Python", "psf/requests", "Python", 24906, 30947, 12845966, 12852007, 6, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159039207, 159040439, 12852022, 12853254, 21060, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33562568, 33563091, 12853269, 12853792, 4290, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204181739, 204182290, 12853807, 12854358, 29155, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159496069, 159496455, 12854373, 12854759, 21136, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157789222, 157790019, 12854774, 12855571, 20823, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59807423, 59811937, 12855586, 12860100, 9445, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37442575, 37462290, 12860115, 12879830, 4799, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 201333397, 201336054, 12879845, 12882502, 28679, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174621705, 174622900, 12882517, 12883712, 23513, "entier"], ["github/PHP", "laravel/framework", "PHP", 186916571, 186929356, 12883727, 12896512, 26006, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34878419, 34886488, 12896527, 12904596, 4471, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162963607, 162968337, 12904611, 12909341, 21649, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204084846, 204086878, 12909356, 12911388, 29113, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205367053, 205367517, 12911403, 12911867, 29606, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177981759, 177986540, 12911882, 12916663, 24119, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210027139, 210028507, 12916678, 12918046, 30829, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168153925, 168155399, 12918061, 12919535, 22382, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 56559547, 56570691, 12919550, 12930694, 9075, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 16902493, 16917199, 12930709, 12945415, 2111, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195399563, 195403061, 12945430, 12948928, 27626, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209545731, 209550235, 12948943, 12953447, 30659, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44581729, 44582814, 12953462, 12954547, 6354, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170043097, 170049478, 12954562, 12960943, 22788, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171721363, 171722983, 12960958, 12962578, 23017, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 31733894, 31745530, 12962593, 12974229, 4155, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 42280483, 42286124, 12974244, 12979885, 5400, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171786797, 171788552, 12979900, 12981655, 23034, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 65410582, 65415763, 12981670, 12986851, 10162, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207728573, 207734522, 12986866, 12992815, 30237, "entier"], ["github/Java", "square/okhttp", "Java", 145674298, 145688836, 12992830, 13007368, 19577, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174844885, 174845418, 13007383, 13007916, 23570, "entier"], ["github/Python", "django/django", "Python", 4682516, 4687232, 13007931, 13012647, 812, "entier"], ["github/PHP", "laravel/framework", "PHP", 187198141, 187213730, 13012662, 13028251, 26077, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63084092, 63084524, 13028266, 13028698, 9771, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160539490, 160544663, 13028713, 13033886, 21192, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71400478, 71401684, 13033901, 13035107, 10692, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215966040, 215972036, 13035122, 13041118, 32002, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47873755, 47883340, 13041133, 13050718, 7061, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65408948, 65409153, 13050733, 13050938, 10158, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35618006, 35622179, 13050953, 13055126, 4575, "entier"], ["github/C", "curl/curl", "C", 98124894, 98128937, 13055141, 13059184, 13376, "entier"], ["github/Python", "django/django", "Python", 1552240, 1552586, 13059199, 13059545, 264, "entier"], ["github/Python", "django/django", "Python", 7478290, 7479107, 13059560, 13060377, 1244, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 74301799, 74304327, 13060392, 13062920, 11028, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9585199, 9585870, 13062935, 13063606, 1527, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202265178, 202267865, 13063621, 13066308, 28803, "entier"], ["github/Java", "apache/commons-lang", "Java", 154177762, 154179832, 13066323, 13068393, 20358, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18967503, 18968151, 13068408, 13069056, 2366, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9514050, 9514855, 13069071, 13069876, 1505, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19099140, 19099197, 13069891, 13069948, 2626, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164541220, 164543645, 13069963, 13072388, 21929, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33697490, 33698533, 13072403, 13073446, 4330, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60191982, 60193602, 13073461, 13075081, 9500, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 12620966, 12621885, 13075096, 13076015, 1874, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204377288, 204377759, 13076030, 13076501, 29210, "entier"], ["github/Java", "google/guava", "Java", 132503266, 132507589, 13076516, 13080839, 16979, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50970400, 50970781, 13080854, 13081235, 7217, "entier"], ["github/C", "curl/curl", "C", 98048623, 98051402, 13081250, 13084029, 13355, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204480402, 204482285, 13084044, 13085927, 29234, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51072583, 51074829, 13085942, 13088188, 7266, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138789341, 138791408, 13088203, 13090270, 18222, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163560423, 163562813, 13090285, 13092675, 21741, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10001805, 10006300, 13092690, 13097185, 1602, "entier"], ["github/PHP", "laravel/framework", "PHP", 186609248, 186609763, 13097200, 13097715, 25937, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52219083, 52219770, 13097730, 13098417, 7826, "entier"], ["github/Scala", "scala/scala", "Scala", 224022309, 224029422, 13098432, 13105545, 32853, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214318002, 214319789, 13105560, 13107347, 31818, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193487036, 193489311, 13107362, 13109637, 27236, "entier"], ["github/Python", "django/django", "Python", 937570, 938292, 13109652, 13110374, 146, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171722998, 171735312, 13110389, 13122703, 23018, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203396461, 203396943, 13122718, 13123200, 28949, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194544952, 194545884, 13123215, 13124147, 27411, "entier"], ["github/Python", "django/django", "Python", 1305410, 1306087, 13124162, 13124839, 226, "entier"], ["github/Java", "apache/commons-lang", "Java", 152134538, 152143517, 13124854, 13133833, 20244, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 119397465, 119591628, 13133848, 13328011, 15544, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207718045, 207720638, 13328026, 13330619, 30234, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170062578, 170068588, 13330634, 13336644, 22790, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194497770, 194501547, 13336659, 13340436, 27401, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226630370, 226635249, 13340451, 13345330, 33330, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54504803, 54516423, 13345345, 13356965, 8401, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197157123, 197158263, 13356980, 13358120, 27930, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238409924, 238409963, 13358135, 13358174, 36345, "entier"], ["github/PHP", "laravel/framework", "PHP", 183696736, 183697091, 13358189, 13358544, 25288, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209914994, 209918566, 13358559, 13362131, 30771, "entier"], ["github/Java", "square/okhttp", "Java", 147997007, 148004911, 13362146, 13370050, 19822, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162481966, 162482513, 13370065, 13370612, 21530, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21314398, 21338786, 13370627, 13395015, 2896, "entier"], ["github/PHP", "laravel/framework", "PHP", 186969406, 186972363, 13395030, 13397987, 26018, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213383404, 213383705, 13398002, 13398303, 31576, "entier"], ["github/Java", "square/okhttp", "Java", 146397840, 146399006, 13398318, 13399484, 19658, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205661266, 205662406, 13399499, 13400639, 29690, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54447442, 54448215, 13400654, 13401427, 8344, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165907306, 165912273, 13401442, 13406409, 22181, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136637629, 136638573, 13406424, 13407368, 17703, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198463738, 198465829, 13407383, 13409474, 28177, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229937673, 229950315, 13409489, 13422131, 33979, "entier"], ["github/Java", "google/guava", "Java", 134492152, 134495895, 13422146, 13425889, 17176, "entier"], ["github/C", "curl/curl", "C", 94893258, 94911240, 13425904, 13443886, 13115, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51368013, 51371669, 13443901, 13447557, 7455, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194447081, 194448797, 13447572, 13449288, 27357, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168323208, 168324483, 13449303, 13450578, 22463, "entier"], ["github/PHP", "laravel/framework", "PHP", 189334092, 189335873, 13450593, 13452374, 26446, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210233722, 210239388, 13452389, 13458055, 30908, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44818068, 44819708, 13458070, 13459710, 6409, "entier"], ["github/PHP", "laravel/framework", "PHP", 185196862, 185197160, 13459725, 13460023, 25521, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51736188, 51737111, 13460038, 13460961, 7613, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42645544, 42645830, 13460976, 13461262, 5542, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 167446857, 167450373, 13461277, 13464793, 22309, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45860124, 45861929, 13464808, 13466613, 6791, "entier"], ["github/PHP", "laravel/framework", "PHP", 187869680, 187873530, 13466628, 13470478, 26188, "entier"], ["github/Scala", "scala/scala", "Scala", 224200798, 224201393, 13470493, 13471088, 32929, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138086459, 138102918, 13471103, 13487562, 18074, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172411381, 172419063, 13487577, 13495259, 23254, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160868239, 160869601, 13495274, 13496636, 21286, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27379940, 27380014, 13496651, 13496725, 3661, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204523155, 204526569, 13496740, 13500154, 29250, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195247450, 195249201, 13500169, 13501920, 27579, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 64527158, 64576006, 13501935, 13550783, 9966, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44799244, 44804879, 13550798, 13556433, 6403, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21065355, 21069073, 13556448, 13560166, 2871, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52162926, 52163166, 13560181, 13560421, 7796, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52874745, 52874947, 13560436, 13560638, 8064, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51310702, 51310730, 13560653, 13560681, 7413, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142651422, 142652773, 13560696, 13562047, 18888, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 16504818, 16549139, 13562062, 13606383, 2097, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44423014, 44424179, 13606398, 13607563, 6299, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211349625, 211353344, 13607578, 13611297, 31201, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28646488, 28648358, 13611312, 13613182, 3915, "entier"], ["github/Java", "google/guava", "Java", 132022819, 132024143, 13613197, 13614521, 16890, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27801242, 27801336, 13614536, 13614630, 3774, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37731445, 37733517, 13614645, 13616717, 4899, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33865024, 33866011, 13616732, 13617719, 4353, "entier"], ["github/Java", "square/okhttp", "Java", 145231227, 145237100, 13617734, 13623607, 19479, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190460053, 190473770, 13623622, 13637339, 26633, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33591768, 33594293, 13637354, 13639879, 4302, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 181207274, 181209608, 13639894, 13642228, 24659, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215697773, 215703377, 13642243, 13647847, 31937, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159818145, 159832352, 13647862, 13662069, 21170, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136438984, 136440588, 13662084, 13663688, 17547, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28725662, 28727248, 13663703, 13665289, 3945, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211891629, 211896950, 13665304, 13670625, 31355, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44039983, 44048130, 13670640, 13678787, 6199, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139575898, 139580973, 13678802, 13683877, 18356, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26652404, 26656972, 13683892, 13688460, 3457, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51290356, 51290609, 13688475, 13688728, 7364, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209842711, 209843682, 13688743, 13689714, 30752, "entier"], ["github/Java", "square/okhttp", "Java", 148951731, 148954914, 13689729, 13692912, 19927, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197116373, 197116913, 13692927, 13693467, 27913, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19043829, 19044030, 13693482, 13693683, 2530, "entier"], ["github/Java", "apache/commons-lang", "Java", 154676130, 154677431, 13693698, 13694999, 20431, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200817238, 200818992, 13695014, 13696768, 28598, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142183353, 142185354, 13696783, 13698784, 18788, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21963637, 21966357, 13698799, 13701519, 3057, "entier"], ["github/C", "curl/curl", "C", 94353573, 94372409, 13701534, 13720370, 13074, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237640099, 237688920, 13720385, 13769206, 35727, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200087339, 200090744, 13769221, 13772626, 28362, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179405303, 179416729, 13772641, 13784067, 24297, "entier"], ["github/Java", "google/guava", "Java", 128511537, 128525087, 13784082, 13797632, 16449, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164122427, 164128676, 13797647, 13803896, 21858, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200047037, 200047866, 13803911, 13804740, 28349, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21136291, 21144455, 13804755, 13812919, 2879, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207995194, 207995565, 13812934, 13813305, 30305, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210046206, 210046946, 13813320, 13814060, 30841, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200679194, 200681708, 13814075, 13816589, 28554, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160806681, 160807146, 13816604, 13817069, 21252, "entier"], ["github/Java", "square/okhttp", "Java", 144840788, 144844168, 13817084, 13820464, 19380, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162688639, 162690369, 13820479, 13822209, 21590, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 27062372, 27064636, 13822224, 13824488, 3556, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205547202, 205548721, 13824503, 13826022, 29659, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138138713, 138139421, 13826037, 13826745, 18091, "entier"], ["github/PHP", "laravel/framework", "PHP", 183029947, 183057443, 13826760, 13854256, 25206, "entier"], ["github/Python", "django/django", "Python", 4602589, 4607317, 13854271, 13858999, 798, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204864273, 204864914, 13859014, 13859655, 29412, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142987753, 142990291, 13859670, 13862208, 18967, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18968166, 18971080, 13862223, 13865137, 2367, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164801665, 164805488, 13865152, 13868975, 22004, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 27007326, 27007482, 13868990, 13869146, 3521, "entier"], ["github/Java", "google/guava", "Java", 130734845, 130738976, 13869161, 13873292, 16768, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203623861, 203627013, 13873307, 13876459, 28994, "entier"], ["github/Python", "django/django", "Python", 5976947, 5977954, 13876474, 13877481, 1013, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171784362, 171784641, 13877496, 13877775, 23031, "entier"], ["github/Go", "prometheus/prometheus", "Go", 82408209, 82549876, 13877790, 14019457, 11658, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174698987, 174699306, 14019472, 14019791, 23530, "entier"], ["github/C", "curl/curl", "C", 93645675, 93647351, 14019806, 14021482, 13035, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157775780, 157776648, 14021497, 14022365, 20804, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144511569, 144514275, 14022380, 14025086, 19286, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144159434, 144162674, 14025101, 14028341, 19185, "entier"], ["github/Java", "google/guava", "Java", 128499870, 128500860, 14028356, 14029346, 16444, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45738709, 45788828, 14029361, 14079480, 6777, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202178941, 202186452, 14079495, 14087006, 28771, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139131827, 139137349, 14087021, 14092543, 18276, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 167623008, 167633604, 14092558, 14103154, 22317, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226119643, 226120828, 14103169, 14104354, 33270, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138126612, 138127777, 14104369, 14105534, 18081, "entier"], ["github/Java", "square/okhttp", "Java", 146345748, 146346875, 14105549, 14106676, 19648, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190812272, 190812732, 14106691, 14107151, 26718, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34229240, 34252081, 14107166, 14130007, 4388, "entier"], ["github/Java", "square/okhttp", "Java", 145150955, 145154273, 14130022, 14133340, 19460, "entier"], ["github/C", "libuv/libuv", "C", 99955739, 99969788, 14133355, 14147404, 13751, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 13155733, 13179897, 14147419, 14171583, 1898, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136476316, 136477227, 14171598, 14172509, 17580, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139473134, 139474769, 14172524, 14174159, 18344, "entier"], ["github/Java", "square/okhttp", "Java", 144920248, 144921016, 14174174, 14174942, 19400, "entier"], ["github/PHP", "laravel/framework", "PHP", 185565113, 185573454, 14174957, 14183298, 25631, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163357688, 163358190, 14183313, 14183815, 21685, "entier"], ["github/Java", "square/okhttp", "Java", 145672634, 145674283, 14183830, 14185479, 19576, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136647937, 136648711, 14185494, 14186268, 17710, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141185212, 141188156, 14186283, 14189227, 18515, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180237502, 180255303, 14189242, 14207043, 24451, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157101201, 157105589, 14207058, 14211446, 20649, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 202003389, 202014671, 14211461, 14222743, 28727, "entier"], ["github/Java", "google/guava", "Java", 132884626, 132891489, 14222758, 14229621, 17024, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19003174, 19004297, 14229636, 14230759, 2440, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139818593, 139821419, 14230774, 14233600, 18386, "entier"], ["github/PHP", "laravel/framework", "PHP", 187487150, 187496517, 14233615, 14242982, 26131, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19008714, 19008769, 14242997, 14243052, 2447, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27983571, 27983891, 14243067, 14243387, 3800, "entier"], ["github/C++", "nlohmann/json", "C++", 103915109, 103916102, 14243402, 14244395, 14152, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162401995, 162408273, 14244410, 14250688, 21518, "entier"], ["github/Java", "square/okhttp", "Java", 144650251, 144651507, 14250703, 14251959, 19324, "entier"], ["github/C++", "opencv/opencv", "C++", 116751039, 116752174, 14251974, 14253109, 15362, "entier"], ["github/Python", "django/django", "Python", 942849, 944169, 14253124, 14254444, 151, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136300453, 136301737, 14254459, 14255743, 17452, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18200517, 18204326, 14255758, 14259567, 2234, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136456871, 136457804, 14259582, 14260515, 17560, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233888203, 233888665, 14260530, 14260992, 34944, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206631104, 206634346, 14261007, 14264249, 29981, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56484363, 56484459, 14264264, 14264360, 9050, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 166068219, 166070323, 14264375, 14266479, 22227, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197225469, 197229111, 14266494, 14270136, 27955, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204128423, 204129199, 14270151, 14270927, 29126, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 31839899, 31845340, 14270942, 14276383, 4162, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 72507684, 72584777, 14276398, 14353491, 10934, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205044895, 205046650, 14353506, 14355261, 29504, "entier"], ["github/C", "curl/curl", "C", 92272237, 92286262, 14355276, 14369301, 12888, "entier"], ["github/Java", "google/guava", "Java", 130196408, 130216076, 14369316, 14388984, 16711, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196251175, 196254229, 14388999, 14392053, 27746, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33707186, 33708158, 14392068, 14393040, 4333, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27609715, 27610019, 14393055, 14393359, 3715, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18976506, 18976878, 14393374, 14393746, 2372, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164039208, 164047235, 14393761, 14401788, 21848, "entier"], ["github/PHP", "laravel/framework", "PHP", 189331149, 189334077, 14401803, 14404731, 26445, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 16572732, 16593156, 14404746, 14425170, 2101, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210709829, 210716141, 14425185, 14431497, 31066, "entier"], ["github/Scala", "scala/scala", "Scala", 218923529, 218989795, 14431512, 14497778, 32365, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27461230, 27468785, 14497793, 14505348, 3681, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55338714, 55363747, 14505363, 14530396, 8502, "entier"], ["github/PHP", "laravel/framework", "PHP", 185451800, 185459258, 14530411, 14537869, 25598, "entier"], ["github/Java", "google/guava", "Java", 130971126, 130979000, 14537884, 14545758, 16804, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210705957, 210707761, 14545773, 14547577, 31062, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176606865, 176616874, 14547592, 14557601, 23803, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233963974, 233965555, 14557616, 14559197, 34988, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26606612, 26611193, 14559212, 14563793, 3447, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142909381, 142912406, 14563808, 14566833, 18936, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197853261, 197854411, 14566848, 14567998, 28065, "entier"], ["github/PHP", "laravel/framework", "PHP", 184359656, 184360899, 14568013, 14569256, 25351, "entier"], ["github/Java", "google/guava", "Java", 130993157, 130995102, 14569271, 14571216, 16808, "entier"], ["github/Python", "django/django", "Python", 5736790, 5737048, 14571231, 14571489, 993, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211033572, 211040756, 14571504, 14578688, 31133, "entier"], ["github/Python", "django/django", "Python", 6838129, 6839628, 14578703, 14580202, 1191, "entier"], ["github/Java", "apache/commons-lang", "Java", 153939455, 153941858, 14580217, 14582620, 20334, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 13461860, 13462106, 14582635, 14582881, 1905, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33587566, 33591753, 14582896, 14587083, 4301, "entier"], ["github/C", "curl/curl", "C", 96291615, 96300520, 14587098, 14596003, 13192, "entier"], ["github/PHP", "laravel/framework", "PHP", 189346647, 189351247, 14596018, 14600618, 26448, "entier"], ["github/Java", "square/okhttp", "Java", 146482023, 146485417, 14600633, 14604027, 19678, "entier"], ["github/Python", "pallets/flask", "Python", 350517, 353020, 14604042, 14606545, 48, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19054348, 19054494, 14606560, 14606706, 2555, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194919622, 194920793, 14606721, 14607892, 27505, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216326795, 216344989, 14607907, 14626101, 32072, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 36468851, 36471866, 14626116, 14629131, 4688, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179382814, 179383619, 14629146, 14629951, 24285, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189770339, 189771009, 14629966, 14630636, 26502, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210633200, 210636424, 14630651, 14633875, 31044, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174783011, 174784148, 14633890, 14635027, 23541, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190284596, 190288050, 14635042, 14638496, 26600, "entier"], ["github/C++", "nlohmann/json", "C++", 106381139, 106459824, 14638511, 14717196, 14605, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204868597, 204869068, 14717211, 14717682, 29420, "entier"], ["github/Java", "google/guava", "Java", 130022105, 130039309, 14717697, 14734901, 16697, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 180765106, 180766561, 14734916, 14736371, 24551, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233608203, 233608460, 14736386, 14736643, 34850, "entier"], ["github/Python", "django/django", "Python", 3218149, 3230866, 14736658, 14749375, 615, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193176408, 193178811, 14749390, 14751793, 27145, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200552952, 200555641, 14751808, 14754497, 28510, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27255435, 27266622, 14754512, 14765699, 3602, "entier"], ["github/C", "libuv/libuv", "C", 99893566, 99900280, 14765714, 14772428, 13743, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174650143, 174652646, 14772443, 14774946, 23520, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 199969707, 199970909, 14774961, 14776163, 28290, "entier"], ["github/Java", "google/guava", "Java", 130601947, 130605002, 14776178, 14779233, 16743, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191991902, 191999364, 14779248, 14786710, 26909, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202518990, 202521354, 14786725, 14789089, 28864, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210423899, 210424339, 14789104, 14789544, 30973, "entier"], ["github/Java", "google/guava", "Java", 130675495, 130679718, 14789559, 14793782, 16759, "entier"], ["github/Python", "django/django", "Python", 3026311, 3029358, 14793797, 14796844, 594, "entier"], ["github/C", "curl/curl", "C", 98511777, 98513823, 14796859, 14798905, 13485, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26391291, 26395760, 14798920, 14803389, 3416, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137556766, 137559270, 14803404, 14805908, 17955, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 64703453, 64703725, 14805923, 14806195, 9981, "entier"], ["github/PHP", "laravel/framework", "PHP", 188488441, 188495130, 14806210, 14812899, 26283, "entier"], ["github/Scala", "scala/scala", "Scala", 222282548, 222291214, 14812914, 14821580, 32680, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202724034, 202734567, 14821595, 14832128, 28882, "entier"], ["github/Java", "apache/commons-lang", "Java", 155206552, 155221028, 14832143, 14846619, 20511, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197154005, 197154339, 14846634, 14846968, 27928, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 62030337, 62038409, 14846983, 14855055, 9682, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238417241, 238417266, 14855070, 14855095, 36437, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230210422, 230211308, 14855110, 14855996, 34077, "entier"], ["github/C", "libuv/libuv", "C", 101631768, 101641642, 14856011, 14865885, 13923, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191573008, 191576377, 14865900, 14869269, 26830, "entier"], ["github/Scala", "scala/scala", "Scala", 224721672, 224723459, 14869284, 14871071, 33087, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25415462, 25430437, 14871086, 14886061, 3330, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198610795, 198611618, 14886076, 14886899, 28190, "entier"], ["github/PHP", "laravel/framework", "PHP", 182918079, 182918380, 14886914, 14887215, 25181, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235981625, 235986110, 14887230, 14891715, 35511, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211659092, 211659814, 14891730, 14892452, 31311, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66074730, 66079418, 14892467, 14897155, 10229, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210172172, 210173173, 14897170, 14898171, 30883, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 50336320, 50398926, 14898186, 14960792, 7159, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234087202, 234089883, 14960807, 14963488, 35075, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205364528, 205365070, 14963503, 14964045, 29601, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195734416, 195740855, 14964060, 14970499, 27661, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90707519, 90711447, 14970514, 14974442, 12641, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 16474703, 16504803, 14974457, 15004557, 2096, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207434934, 207436662, 15004572, 15006300, 30141, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231223869, 231228253, 15006315, 15010699, 34448, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 166769264, 166839183, 15010714, 15080633, 22267, "entier"], ["github/Java", "square/okhttp", "Java", 146043279, 146061807, 15080648, 15099176, 19604, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89424886, 89425557, 15099191, 15099862, 12473, "entier"], ["github/C", "curl/curl", "C", 91549502, 91553014, 15099877, 15103389, 12819, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238429948, 238430198, 15103404, 15103654, 36586, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202162084, 202164403, 15103669, 15105988, 28766, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193847086, 193848645, 15106003, 15107562, 27291, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25606196, 25607570, 15107577, 15108951, 3354, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58799046, 58805300, 15108966, 15115220, 9299, "entier"], ["github/PHP", "laravel/framework", "PHP", 188120033, 188121509, 15115235, 15116711, 26235, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206176676, 206177104, 15116726, 15117154, 29860, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65404759, 65404884, 15117169, 15117294, 10135, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89213661, 89220898, 15117309, 15124546, 12440, "entier"], ["github/C", "curl/curl", "C", 98112244, 98115016, 15124561, 15127333, 13371, "entier"], ["github/PHP", "laravel/framework", "PHP", 185854264, 185857763, 15127348, 15130847, 25706, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209742654, 209746796, 15130862, 15135004, 30716, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143440680, 143442506, 15135019, 15136845, 19019, "entier"], ["github/Java", "square/okhttp", "Java", 144654366, 144654800, 15136860, 15137294, 19327, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 122814759, 122828012, 15137309, 15150562, 15911, "entier"], ["github/C", "madler/zlib", "C", 102292732, 102294222, 15150577, 15152067, 14025, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205222088, 205222485, 15152082, 15152479, 29568, "entier"], ["github/Java", "google/guava", "Java", 128238543, 128244124, 15152494, 15158075, 16391, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69272012, 69282951, 15158090, 15169029, 10488, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 32837890, 32854783, 15169044, 15185937, 4220, "entier"], ["github/C", "curl/curl", "C", 93566932, 93568710, 15185952, 15187730, 13025, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138368586, 138371791, 15187745, 15190950, 18146, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178613152, 178649335, 15190965, 15227148, 24188, "entier"], ["github/C++", "nlohmann/json", "C++", 104035265, 104035839, 15227163, 15227737, 14280, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136468549, 136469285, 15227752, 15228488, 17571, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190096618, 190108676, 15228503, 15240561, 26577, "entier"], ["github/C", "curl/curl", "C", 91535869, 91537750, 15240576, 15242457, 12815, "entier"], ["github/C++", "opencv/opencv", "C++", 117207661, 117212114, 15242472, 15246925, 15452, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212641519, 212650704, 15246940, 15256125, 31451, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90521851, 90531871, 15256140, 15266160, 12606, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142951448, 142957194, 15266175, 15271921, 18954, "entier"], ["github/Scala", "scala/scala", "Scala", 221795685, 221831347, 15271936, 15307598, 32641, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120074778, 120075690, 15307613, 15308525, 15604, "entier"], ["github/C", "curl/curl", "C", 98865832, 98868933, 15308540, 15311641, 13586, "entier"], ["github/Java", "google/guava", "Java", 131872994, 131874587, 15311656, 15313249, 16871, "entier"], ["github/Python", "encode/httpx", "Python", 17896171, 17905820, 15313264, 15322913, 2160, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142957209, 142961083, 15322928, 15326802, 18955, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194796026, 194797944, 15326817, 15328735, 27478, "entier"], ["github/C", "curl/curl", "C", 98816952, 98819675, 15328750, 15331473, 13571, "entier"], ["github/PHP", "laravel/framework", "PHP", 186259934, 186260548, 15331488, 15332102, 25819, "entier"], ["github/Java", "square/okhttp", "Java", 144714426, 144718643, 15332117, 15336334, 19353, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88266827, 88271114, 15336349, 15340636, 12281, "entier"], ["github/Java", "google/guava", "Java", 129281297, 129282438, 15340651, 15341792, 16603, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34897837, 34907014, 15341807, 15350984, 4475, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214185527, 214191358, 15350999, 15356830, 31775, "entier"], ["github/C", "curl/curl", "C", 92711607, 92714448, 15356845, 15359686, 12962, "entier"], ["github/C++", "nlohmann/json", "C++", 104836766, 104857611, 15359701, 15380546, 14489, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52486462, 52487637, 15380561, 15381736, 7925, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85082789, 85084134, 15381751, 15383096, 11878, "entier"], ["github/Java", "google/guava", "Java", 135964818, 135973503, 15383111, 15391796, 17327, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44942945, 44944141, 15391811, 15393007, 6498, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 58145248, 58168371, 15393022, 15416145, 9157, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233878845, 233880182, 15416160, 15417497, 34936, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27588523, 27589904, 15417512, 15418893, 3700, "entier"], ["github/Go", "prometheus/prometheus", "Go", 77881234, 77884771, 15418908, 15422445, 11340, "entier"], ["github/C", "curl/curl", "C", 91395780, 91398322, 15422460, 15425002, 12769, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205856521, 205859677, 15425017, 15428173, 29738, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143767505, 143769903, 15428188, 15430586, 19108, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35553139, 35555557, 15430601, 15433019, 4562, "entier"], ["github/Java", "square/okhttp", "Java", 144935279, 144936289, 15433034, 15434044, 19409, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136593484, 136594213, 15434059, 15434788, 17669, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88374276, 88375783, 15434803, 15436310, 12308, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216387257, 216388825, 15436325, 15437893, 32084, "entier"], ["github/Scala", "scala/scala", "Scala", 224475072, 224476785, 15437908, 15439621, 33030, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204463389, 204464984, 15439636, 15441231, 29224, "entier"], ["github/C", "libuv/libuv", "C", 101604199, 101607335, 15441246, 15444382, 13917, "entier"], ["github/Java", "apache/commons-lang", "Java", 156264108, 156268166, 15444397, 15448455, 20589, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238314359, 238315338, 15448470, 15449449, 36015, "entier"], ["github/Go", "gin-gonic/gin", "Go", 74907725, 74911563, 15449464, 15453302, 11080, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191586044, 191613322, 15453317, 15480595, 26835, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227132180, 227133230, 15480610, 15481660, 33457, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28153593, 28160319, 15481675, 15488401, 3844, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209529461, 209532344, 15488416, 15491299, 30655, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229348374, 229349409, 15491314, 15492349, 33798, "entier"], ["github/Scala", "scala/scala", "Scala", 224198972, 224199563, 15492364, 15492955, 32926, "entier"], ["github/Java", "square/okhttp", "Java", 148330856, 148339276, 15492970, 15501390, 19847, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206525671, 206525914, 15501405, 15501648, 29961, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213818833, 213819252, 15501663, 15502082, 31678, "entier"], ["github/C", "jqlang/jq", "C", 103301363, 103306103, 15502097, 15506837, 14090, "entier"], ["github/Scala", "scala/scala", "Scala", 224698436, 224705398, 15506852, 15513814, 33080, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59848722, 59851939, 15513829, 15517046, 9450, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203560978, 203564004, 15517061, 15520087, 28975, "entier"], ["github/Java", "square/okhttp", "Java", 144897796, 144899651, 15520102, 15521957, 19388, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33342273, 33346578, 15521972, 15526277, 4265, "entier"], ["github/Go", "prometheus/prometheus", "Go", 77318852, 77327660, 15526292, 15535100, 11297, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140722299, 140726868, 15535115, 15539684, 18493, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238406006, 238406292, 15539699, 15539985, 36325, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 40965753, 41000896, 15540000, 15575143, 5237, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204082575, 204084831, 15575158, 15577414, 29112, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230113468, 230115751, 15577429, 15579712, 34010, "entier"], ["github/C", "curl/curl", "C", 98900990, 98903893, 15579727, 15582630, 13596, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 12106749, 12147373, 15582645, 15623269, 1844, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162501306, 162506191, 15623284, 15628169, 21540, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230458647, 230459966, 15628184, 15629503, 34237, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141438061, 141443551, 15629518, 15635008, 18551, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35527947, 35533880, 15635023, 15640956, 4557, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172739842, 172740029, 15640971, 15641158, 23292, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227134786, 227135678, 15641173, 15642065, 33460, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207388816, 207392049, 15642080, 15645313, 30126, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229873991, 229875164, 15645328, 15646501, 33972, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174800229, 174801698, 15646516, 15647985, 23550, "entier"], ["github/Java", "google/guava", "Java", 135337088, 135338882, 15648000, 15649794, 17258, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234897229, 234898030, 15649809, 15650610, 35275, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168485003, 168486686, 15650625, 15652308, 22554, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85392996, 85396880, 15652323, 15656207, 11935, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230796314, 230796871, 15656222, 15656779, 34356, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19014967, 19015721, 15656794, 15657548, 2467, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144235594, 144238025, 15657563, 15659994, 19208, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204848476, 204849061, 15660009, 15660594, 29388, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138145564, 138145706, 15660609, 15660751, 18097, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204621617, 204622253, 15660766, 15661402, 29277, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174227967, 174229657, 15661417, 15663107, 23476, "entier"], ["github/C++", "opencv/opencv", "C++", 112115116, 112160459, 15663122, 15708465, 15038, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136504929, 136506021, 15708480, 15709572, 17606, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197389778, 197394937, 15709587, 15714746, 27976, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27970503, 27973751, 15714761, 15718009, 3796, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204846823, 204847721, 15718024, 15718922, 29386, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238910770, 238916323, 15718937, 15724490, 36820, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89759516, 89760770, 15724505, 15725759, 12532, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206218265, 206219039, 15725774, 15726548, 29880, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71753569, 71775644, 15726563, 15748638, 10906, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75053871, 75054431, 15748653, 15749213, 11110, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229633295, 229633791, 15749228, 15749724, 33868, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211511101, 211513321, 15749739, 15751959, 31262, "entier"], ["github/C", "curl/curl", "C", 99074394, 99085844, 15751974, 15763424, 13641, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233895232, 233897301, 15763439, 15765508, 34950, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196259032, 196261851, 15765523, 15768342, 27749, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161878442, 161888110, 15768357, 15778025, 21430, "entier"], ["github/Scala", "scala/scala", "Scala", 220365515, 220369392, 15778040, 15781917, 32473, "entier"], ["github/PHP", "laravel/framework", "PHP", 186508823, 186509946, 15781932, 15783055, 25891, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 32807632, 32815723, 15783070, 15791161, 4217, "entier"], ["github/Go", "prometheus/prometheus", "Go", 82836588, 82842960, 15791176, 15797548, 11672, "entier"], ["github/PHP", "laravel/framework", "PHP", 187176235, 187176856, 15797563, 15798184, 26071, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205662421, 205666232, 15798199, 15802010, 29691, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173209816, 173217137, 15802025, 15809346, 23365, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235165454, 235170071, 15809361, 15813978, 35342, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42631729, 42632710, 15813993, 15814974, 5529, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43335977, 43336538, 15814989, 15815550, 5770, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75429152, 75429942, 15815565, 15816355, 11150, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42879060, 42880431, 15816370, 15817741, 5642, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157772739, 157773027, 15817756, 15818044, 20799, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235038318, 235039199, 15818059, 15818940, 35301, "entier"], ["github/Java", "square/okhttp", "Java", 146834070, 146870354, 15818955, 15855239, 19730, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43702298, 43704421, 15855254, 15857377, 6097, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230278587, 230280152, 15857392, 15858957, 34139, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238407657, 238407741, 15858972, 15859056, 36335, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230328472, 230328825, 15859071, 15859424, 34175, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231476855, 231477168, 15859439, 15859752, 34505, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238416089, 238416241, 15859767, 15859919, 36421, "entier"], ["github/Python", "django/django", "Python", 2463146, 2463768, 15859934, 15860556, 522, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157912410, 157918638, 15860571, 15866799, 20855, "entier"], ["github/C", "curl/curl", "C", 95684897, 95689895, 15866814, 15871812, 13166, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39249418, 39255043, 15871827, 15877452, 5075, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 64012868, 64019301, 15877467, 15883900, 9934, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35431969, 35444427, 15883915, 15896373, 4539, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171960262, 171962282, 15896388, 15898408, 23145, "entier"], ["github/PHP", "laravel/framework", "PHP", 186775926, 186796258, 15898423, 15918755, 25991, "entier"], ["github/C++", "opencv/opencv", "C++", 112349303, 112351268, 15918770, 15920735, 15056, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45225050, 45225337, 15920750, 15921037, 6694, "entier"], ["github/C++", "nlohmann/json", "C++", 103917914, 103918680, 15921052, 15921818, 14155, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43749564, 43750030, 15921833, 15922299, 6138, "entier"], ["github/C", "madler/zlib", "C", 102283856, 102284382, 15922314, 15922840, 14021, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162230969, 162232900, 15922855, 15924786, 21481, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60239636, 60241773, 15924801, 15926938, 9515, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121777730, 121781027, 15926953, 15930250, 15795, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53493973, 53497836, 15930265, 15934128, 8210, "entier"], ["github/C", "curl/curl", "C", 98451773, 98453935, 15934143, 15936305, 13461, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164277041, 164278093, 15936320, 15937372, 21885, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 56838584, 56839839, 15937387, 15938642, 9086, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41979254, 41979706, 15938657, 15939109, 5367, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59392601, 59393100, 15939124, 15939623, 9385, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163539810, 163541202, 15939638, 15941030, 21733, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66212943, 66213744, 15941045, 15941846, 10242, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44498341, 44500374, 15941861, 15943894, 6327, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233600065, 233600609, 15943909, 15944453, 34844, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65395000, 65395345, 15944468, 15944813, 10075, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25071444, 25075479, 15944828, 15948863, 3253, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65026176, 65026691, 15948878, 15949393, 10024, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168193624, 168194992, 15949408, 15950776, 22408, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177605412, 177612434, 15950791, 15957813, 24038, "entier"], ["github/C++", "opencv/opencv", "C++", 114782431, 114791012, 15957828, 15966409, 15218, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71367355, 71368326, 15966424, 15967395, 10659, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43307365, 43308197, 15967410, 15968242, 5728, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138215743, 138222666, 15968257, 15975180, 18119, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66237103, 66237381, 15975195, 15975473, 10250, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52139790, 52141959, 15975488, 15977657, 7776, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35582946, 35584901, 15977672, 15979627, 4566, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 171471477, 171474868, 15979642, 15983033, 22942, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55029785, 55030679, 15983048, 15983942, 8473, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 68962325, 68966731, 15983957, 15988363, 10466, "entier"], ["github/Java", "square/okhttp", "Java", 144681589, 144684652, 15988378, 15991441, 19336, "entier"], ["github/C++", "nlohmann/json", "C++", 103946620, 103948208, 15991456, 15993044, 14183, "entier"], ["github/Python", "django/django", "Python", 3135704, 3164357, 15993059, 16021712, 606, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51225662, 51228642, 16021727, 16024707, 7317, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234226913, 234227115, 16024722, 16024924, 35151, "entier"], ["github/C", "curl/curl", "C", 97942573, 97952507, 16024939, 16034873, 13344, "entier"], ["github/Java", "google/guava", "Java", 135956589, 135960485, 16034888, 16038784, 17324, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157073539, 157075951, 16038799, 16041211, 20641, "entier"], ["github/PHP", "laravel/framework", "PHP", 184698848, 184706997, 16041226, 16049375, 25408, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63370426, 63372675, 16049390, 16051639, 9826, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172249467, 172250470, 16051654, 16052657, 23217, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51371684, 51375758, 16052672, 16056746, 7456, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61932819, 61933834, 16056761, 16057776, 9667, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174878177, 174878952, 16057791, 16058566, 23580, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 171216373, 171218954, 16058581, 16061162, 22915, "entier"], ["github/Scala", "scala/scala", "Scala", 221847446, 221893831, 16061177, 16107562, 32645, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 119381696, 119394168, 16107577, 16120049, 15541, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212109959, 212149755, 16120064, 16159860, 31389, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196464209, 196466183, 16159875, 16161849, 27804, "entier"], ["github/Java", "apache/commons-lang", "Java", 153927342, 153939440, 16161864, 16173962, 20333, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44622498, 44627422, 16173977, 16178901, 6362, "entier"], ["github/PHP", "laravel/framework", "PHP", 188858791, 188859633, 16178916, 16179758, 26389, "entier"], ["github/PHP", "laravel/framework", "PHP", 186226231, 186226809, 16179773, 16180351, 25796, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176664290, 176668595, 16180366, 16184671, 23806, "entier"], ["github/PHP", "laravel/framework", "PHP", 188495145, 188499257, 16184686, 16188798, 26284, "entier"], ["github/Java", "google/guava", "Java", 129717965, 129720841, 16188813, 16191689, 16662, "entier"], ["github/C++", "opencv/opencv", "C++", 114731228, 114737577, 16191704, 16198053, 15216, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 20873999, 20902439, 16198068, 16226508, 2833, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195856039, 195856967, 16226523, 16227451, 27685, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 171456818, 171469433, 16227466, 16240081, 22940, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137152733, 137158070, 16240096, 16245433, 17863, "entier"], ["github/PHP", "laravel/framework", "PHP", 184543817, 184544433, 16245448, 16246064, 25381, "entier"], ["github/C++", "google/leveldb", "C++", 110587030, 110589455, 16246079, 16248504, 14837, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177315634, 177318445, 16248519, 16251330, 23965, "entier"], ["github/C", "libuv/libuv", "C", 101458587, 101469963, 16251345, 16262721, 13889, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10444438, 10448700, 16262736, 16266998, 1679, "entier"], ["github/Java", "google/guava", "Java", 128210011, 128211617, 16267013, 16268619, 16384, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78808299, 78871495, 16268634, 16331830, 11439, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136261929, 136263413, 16331845, 16333329, 17430, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234047681, 234049759, 16333344, 16335422, 35046, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38991423, 39010600, 16335437, 16354614, 5050, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141237655, 141242339, 16354629, 16359313, 18521, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175652365, 175653476, 16359328, 16360439, 23705, "entier"], ["github/Python", "django/django", "Python", 2421906, 2424161, 16360454, 16362709, 511, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180182014, 180182540, 16362724, 16363250, 24428, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157251437, 157252115, 16363265, 16363943, 20689, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177374103, 177375091, 16363958, 16364946, 23974, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120738471, 120754361, 16364961, 16380851, 15660, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192657476, 192673667, 16380866, 16397057, 27036, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 72122149, 72160222, 16397072, 16435145, 10920, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168523305, 168524824, 16435160, 16436679, 22578, "entier"], ["github/C", "curl/curl", "C", 97713383, 97714831, 16436694, 16438142, 13299, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177820691, 177822736, 16438157, 16440202, 24082, "entier"], ["github/Scala", "scala/scala", "Scala", 219270194, 219272868, 16440217, 16442891, 32403, "entier"], ["github/Python", "django/django", "Python", 3397324, 3410098, 16442906, 16455680, 634, "entier"], ["github/Java", "google/guava", "Java", 135777594, 135798829, 16455695, 16476930, 17310, "entier"], ["github/Scala", "scala/scala", "Scala", 221336687, 221341283, 16476945, 16481541, 32537, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172717631, 172720231, 16481556, 16484156, 23289, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47773194, 47777400, 16484171, 16488377, 7036, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205866738, 205868371, 16488392, 16490025, 29741, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 181163345, 181163410, 16490040, 16490105, 24640, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53792664, 53793897, 16490120, 16491353, 8255, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177589936, 177590468, 16491368, 16491900, 24035, "entier"], ["github/C++", "google/leveldb", "C++", 110159846, 110169918, 16491915, 16501987, 14793, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191808845, 191812886, 16502002, 16506043, 26865, "entier"], ["github/C", "curl/curl", "C", 99105839, 99115011, 16506058, 16515230, 13648, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174820350, 174821205, 16515245, 16516100, 23558, "entier"], ["github/Scala", "sbt/sbt", "Scala", 239194124, 239199640, 16516115, 16521631, 36877, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136618841, 136619897, 16521646, 16522702, 17687, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205150397, 205153752, 16522717, 16526072, 29543, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10993924, 10996390, 16526087, 16528553, 1770, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171875529, 171876479, 16528568, 16529518, 23080, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141620698, 141621857, 16529533, 16530692, 18584, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25669278, 25686709, 16530707, 16548138, 3365, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55164990, 55171801, 16548153, 16554964, 8493, "entier"], ["github/Python", "django/django", "Python", 5123840, 5123952, 16554979, 16555091, 902, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238738832, 238740080, 16555106, 16556354, 36780, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238304213, 238304284, 16556369, 16556440, 35951, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238316366, 238316434, 16556455, 16556523, 36023, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165396492, 165418737, 16556538, 16578783, 22043, "entier"], ["github/Java", "square/okhttp", "Java", 145381823, 145389102, 16578798, 16586077, 19516, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177312483, 177315175, 16586092, 16588784, 23963, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55991523, 55991797, 16588799, 16589073, 8644, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233995616, 233996238, 16589088, 16589710, 35009, "entier"], ["github/PHP", "laravel/framework", "PHP", 186176888, 186188601, 16589725, 16601438, 25785, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144401801, 144403786, 16601453, 16603438, 19257, "entier"], ["github/C", "curl/curl", "C", 94824300, 94826934, 16603453, 16606087, 13107, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43389899, 43394493, 16606102, 16610696, 5792, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141960115, 141960953, 16610711, 16611549, 18676, "entier"], ["github/Python", "django/django", "Python", 7699467, 7712917, 16611564, 16625014, 1288, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51131820, 51134214, 16625029, 16627423, 7272, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143759453, 143767490, 16627438, 16635475, 19107, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24362022, 24363253, 16635490, 16636721, 3193, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52224138, 52224361, 16636736, 16636959, 7836, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52714681, 52715054, 16636974, 16637347, 7974, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55023393, 55025617, 16637362, 16639586, 8470, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202609802, 202626447, 16639601, 16656246, 28872, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59704159, 59715215, 16656261, 16667317, 9423, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137445830, 137449453, 16667332, 16670955, 17925, "entier"], ["github/Scala", "scala/scala", "Scala", 224367637, 224394150, 16670970, 16697483, 33020, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33470820, 33477307, 16697498, 16703985, 4281, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52820193, 52821805, 16704000, 16705612, 8033, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179595905, 179605165, 16705627, 16714887, 24335, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42645845, 42646138, 16714902, 16715195, 5543, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43332746, 43333042, 16715210, 16715506, 5763, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195308366, 195316914, 16715521, 16724069, 27603, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51168979, 51169297, 16724084, 16724402, 7293, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41204135, 41204731, 16724417, 16725013, 5259, "entier"], ["github/Java", "apache/commons-lang", "Java", 150938340, 150944171, 16725028, 16730859, 20163, "entier"], ["github/C", "curl/curl", "C", 95484562, 95496996, 16730874, 16743308, 13154, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168602340, 168603847, 16743323, 16744830, 22625, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19067623, 19067717, 16744845, 16744939, 2579, "entier"], ["github/Python", "pallets/flask", "Python", 772060, 776924, 16744954, 16749818, 100, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19101402, 19101910, 16749833, 16750341, 2634, "entier"], ["github/Java", "google/guava", "Java", 132274404, 132276040, 16750356, 16751992, 16934, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157657917, 157659997, 16752007, 16754087, 20780, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 57890791, 57893974, 16754102, 16757285, 9142, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88024426, 88029769, 16757300, 16762643, 12239, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194532224, 194534972, 16762658, 16765406, 27408, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137839868, 137846256, 16765421, 16771809, 18015, "entier"], ["github/Python", "django/django", "Python", 6604258, 6608962, 16771824, 16776528, 1144, "entier"], ["github/PHP", "laravel/framework", "PHP", 186049462, 186052522, 16776543, 16779603, 25771, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54104983, 54122294, 16779618, 16796929, 8291, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 31754080, 31768758, 16796944, 16811622, 4157, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210533176, 210536905, 16811637, 16815366, 31016, "entier"], ["github/Scala", "scala/scala", "Scala", 224241375, 224242047, 16815381, 16816053, 32990, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194849856, 194851746, 16816068, 16817958, 27490, "entier"], ["github/Go", "prometheus/prometheus", "Go", 80937686, 80943352, 16817973, 16823639, 11565, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66356490, 66367933, 16823654, 16835097, 10284, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196169153, 196170196, 16835112, 16836155, 27723, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9991649, 9998463, 16836170, 16842984, 1600, "entier"], ["github/Scala", "playframework/playframework", "Scala", 225905067, 225909736, 16842999, 16847668, 33212, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200216069, 200217369, 16847683, 16848983, 28419, "entier"], ["github/PHP", "laravel/framework", "PHP", 185237561, 185238349, 16848998, 16849786, 25533, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235553152, 235553324, 16849801, 16849973, 35430, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88345759, 88347369, 16849988, 16851598, 12302, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238126525, 238127275, 16851613, 16852363, 35812, "entier"], ["github/Scala", "scala/scala", "Scala", 224163822, 224164556, 16852378, 16853112, 32896, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238416730, 238416771, 16853127, 16853168, 36429, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234850879, 234851310, 16853183, 16853614, 35243, "entier"], ["github/Python", "psf/requests", "Python", 195400, 196239, 16853629, 16854468, 25, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141085414, 141111493, 16854483, 16880562, 18510, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47218173, 47218740, 16880577, 16881144, 6973, "entier"], ["github/Scala", "scala/scala", "Scala", 224624905, 224626212, 16881159, 16882466, 33060, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51956885, 51957138, 16882481, 16882734, 7686, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195827038, 195835389, 16882749, 16891100, 27670, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238303353, 238303397, 16891115, 16891159, 35939, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43800797, 43802946, 16891174, 16893323, 6157, "entier"], ["github/Scala", "playframework/playframework", "Scala", 225941636, 225943435, 16893338, 16895137, 33224, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56467768, 56468328, 16895152, 16895712, 9032, "entier"], ["github/Python", "encode/httpx", "Python", 17785486, 17790987, 16895727, 16901228, 2146, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226044775, 226045657, 16901243, 16902125, 33243, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177397566, 177411018, 16902140, 16915592, 23980, "entier"], ["github/Scala", "scala/scala", "Scala", 221209728, 221210630, 16915607, 16916509, 32513, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238758019, 238760525, 16916524, 16919030, 36784, "entier"], ["github/PHP", "laravel/framework", "PHP", 188582819, 188585008, 16919045, 16921234, 26333, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26470761, 26483219, 16921249, 16933707, 3425, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195377897, 195378560, 16933722, 16934385, 27618, "entier"], ["github/PHP", "laravel/framework", "PHP", 182617181, 182618365, 16934400, 16935584, 25091, "entier"], ["github/Python", "django/django", "Python", 3646155, 3652295, 16935599, 16941739, 658, "entier"], ["github/PHP", "laravel/framework", "PHP", 182496604, 182497711, 16941754, 16942861, 24956, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46280896, 46297431, 16942876, 16959411, 6861, "entier"], ["github/PHP", "laravel/framework", "PHP", 181892211, 181895128, 16959426, 16962343, 24820, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19022422, 19022514, 16962358, 16962450, 2494, "entier"], ["github/Python", "django/django", "Python", 2579562, 2582299, 16962465, 16965202, 544, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51516080, 51516402, 16965217, 16965539, 7542, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176099561, 176102440, 16965554, 16968433, 23775, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161981032, 162034999, 16968448, 17022415, 21445, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140930166, 140972993, 17022430, 17065257, 18499, "entier"], ["github/Python", "django/django", "Python", 2830780, 2847454, 17065272, 17081946, 583, "entier"], ["github/Go", "prometheus/prometheus", "Go", 84481164, 84524586, 17081961, 17125383, 11765, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39585378, 39599211, 17125398, 17139231, 5136, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177855765, 177860043, 17139246, 17143524, 24088, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18437916, 18464657, 17143539, 17170280, 2276, "entier"], ["github/PHP", "laravel/framework", "PHP", 184473572, 184505615, 17170295, 17202338, 25373, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 201657874, 201708908, 17202353, 17253387, 28712, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60935292, 60995747, 17253402, 17313857, 9557, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56322584, 56323021, 17313872, 17314309, 8882, "entier"], ["github/Python", "encode/httpx", "Python", 17924541, 17924865, 17314324, 17314648, 2164, "entier"], ["github/Python", "django/django", "Python", 7443130, 7443251, 17314663, 17314784, 1234, "entier"], ["github/Scala", "scala/scala", "Scala", 219442040, 219502193, 17314799, 17374952, 32418, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47150001, 47155503, 17374967, 17380469, 6958, "entier"], ["github/C++", "nlohmann/json", "C++", 106480355, 106650411, 17380484, 17550540, 14608, "entier"], ["github/Python", "django/django", "Python", 6140796, 6145845, 17550555, 17555604, 1057, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55041871, 55043918, 17555619, 17557666, 8477, "entier"], ["github/Python", "django/django", "Python", 9186212, 9187466, 17557681, 17558935, 1428, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18995403, 18995431, 17558950, 17558978, 2421, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178474029, 178485721, 17558993, 17570685, 24178, "entier"], ["github/C", "curl/curl", "C", 93809894, 93874424, 17570700, 17635230, 13047, "entier"], ["github/Java", "google/guava", "Java", 129037474, 129052633, 17635245, 17650404, 16559, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 12207839, 12219294, 17650419, 17661874, 1848, "entier"], ["github/Java", "google/guava", "Java", 129559949, 129563424, 17661889, 17665364, 16618, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 32766794, 32780951, 17665379, 17679536, 4212, "entier"], ["github/Python", "django/django", "Python", 6083641, 6083808, 17679551, 17679718, 1031, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88413738, 88417696, 17679733, 17683691, 12314, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196223910, 196238713, 17683706, 17698509, 27736, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233577426, 233587028, 17698524, 17708126, 34836, "entier"], ["github/Java", "square/okhttp", "Java", 145363261, 145379179, 17708141, 17724059, 19513, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35115922, 35116787, 17724074, 17724939, 4498, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34207987, 34208559, 17724954, 17725526, 4382, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170362165, 170363560, 17725541, 17726936, 22817, "entier"], ["github/Go", "gohugoio/hugo", "Go", 87533833, 87539315, 17726951, 17732433, 12191, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18110670, 18112990, 17732448, 17734768, 2205, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175004017, 175010956, 17734783, 17741722, 23625, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157477326, 157480576, 17741737, 17744987, 20758, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141834833, 141838196, 17745002, 17748365, 18619, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88928909, 88930947, 17748380, 17750418, 12391, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 23052307, 23057478, 17750433, 17755604, 3109, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139901595, 139901863, 17755619, 17755887, 18397, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192003621, 192005722, 17755902, 17758003, 26912, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231835041, 231840824, 17758018, 17763801, 34562, "entier"], ["github/Java", "google/guava", "Java", 128994913, 128999110, 17763816, 17768013, 16556, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78440443, 78442004, 17768028, 17769589, 11421, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204533800, 204534147, 17769604, 17769951, 29252, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138604733, 138605977, 17769966, 17771210, 18188, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195519047, 195524574, 17771225, 17776752, 27639, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168953254, 168960961, 17776767, 17784474, 22724, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231338879, 231340478, 17784489, 17786088, 34469, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180204372, 180205603, 17786103, 17787334, 24438, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28214457, 28220470, 17787349, 17793362, 3855, "entier"], ["github/Python", "pallets/flask", "Python", 684846, 716133, 17793377, 17824664, 88, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139917131, 139926791, 17824679, 17834339, 18403, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 64020623, 64032837, 17834354, 17846568, 9936, "entier"], ["github/PHP", "laravel/framework", "PHP", 184938904, 184940162, 17846583, 17847841, 25450, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231357214, 231364762, 17847856, 17855404, 34475, "entier"], ["github/Java", "square/okhttp", "Java", 145046749, 145047201, 17855419, 17855871, 19440, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171771609, 171776017, 17855886, 17860294, 23028, "entier"], ["github/Java", "square/okhttp", "Java", 144694052, 144698474, 17860309, 17864731, 19347, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212555171, 212570724, 17864746, 17880299, 31444, "entier"], ["github/PHP", "laravel/framework", "PHP", 184532265, 184540762, 17880314, 17888811, 25378, "entier"], ["github/Scala", "scala/scala", "Scala", 224763993, 224765658, 17888826, 17890491, 33091, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157955297, 157961397, 17890506, 17896606, 20862, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66236580, 66236679, 17896621, 17896720, 10247, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25304212, 25313618, 17896735, 17906141, 3302, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141949950, 141951766, 17906156, 17907972, 18667, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66522397, 66523619, 17907987, 17909209, 10317, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136458753, 136459557, 17909224, 17910028, 17562, "entier"], ["github/Java", "google/guava", "Java", 132442045, 132443071, 17910043, 17911069, 16961, "entier"], ["github/Go", "prometheus/prometheus", "Go", 79339700, 79363217, 17911084, 17934601, 11472, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 181068625, 181071862, 17934616, 17937853, 24628, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162115344, 162116713, 17937868, 17939237, 21455, "entier"], ["github/Java", "apache/commons-lang", "Java", 152307485, 152314965, 17939252, 17946732, 20253, "entier"], ["github/PHP", "laravel/framework", "PHP", 181486371, 181489740, 17946747, 17950116, 24726, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 74270922, 74278647, 17950131, 17957856, 11025, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235324236, 235336222, 17957871, 17969857, 35381, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157404533, 157407073, 17969872, 17972412, 20737, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190620897, 190621772, 17972427, 17973302, 26670, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27771019, 27777005, 17973317, 17979303, 3770, "entier"], ["github/Java", "apache/commons-lang", "Java", 154718127, 154721545, 17979318, 17982736, 20447, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194474743, 194475967, 17982751, 17983975, 27380, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179050272, 179051608, 17983990, 17985326, 24247, "entier"], ["github/PHP", "laravel/framework", "PHP", 182029788, 182029906, 17985341, 17985459, 24825, "entier"], ["github/Java", "square/okhttp", "Java", 144675996, 144676789, 17985474, 17986267, 19333, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193323933, 193325101, 17986282, 17987450, 27189, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 180766576, 180767105, 17987465, 17987994, 24552, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193764109, 193765281, 17988009, 17989181, 27273, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139941787, 139945062, 17989196, 17992471, 18406, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9958370, 9963218, 17992486, 17997334, 1593, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163621668, 163627777, 17997349, 18003458, 21756, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59002999, 59009578, 18003473, 18010052, 9327, "entier"], ["github/Java", "google/guava", "Java", 127921336, 127924181, 18010067, 18012912, 16307, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227092083, 227096619, 18012927, 18017463, 33437, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197754134, 197758109, 18017478, 18021453, 28050, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142361459, 142363355, 18021468, 18023364, 18829, "entier"], ["github/C", "curl/curl", "C", 92858598, 92859953, 18023379, 18024734, 12985, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205833915, 205844160, 18024749, 18034994, 29733, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235222339, 235224167, 18035009, 18036837, 35351, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 65453055, 65453128, 18036852, 18036925, 10176, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189899477, 189900966, 18036940, 18038429, 26536, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10479009, 10483111, 18038444, 18042546, 1686, "entier"], ["github/Scala", "sbt/sbt", "Scala", 239262725, 239263161, 18042561, 18042997, 36891, "entier"], ["github/Java", "google/guava", "Java", 128813965, 128819221, 18043012, 18048268, 16522, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162928947, 162930650, 18048283, 18049986, 21644, "entier"], ["github/PHP", "laravel/framework", "PHP", 182507496, 182507931, 18050001, 18050436, 24969, "entier"], ["github/C", "curl/curl", "C", 97798754, 97801540, 18050451, 18053237, 13311, "entier"], ["github/Scala", "scala/scala", "Scala", 223806270, 223809607, 18053252, 18056589, 32816, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9511493, 9513278, 18056604, 18058389, 1502, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59656649, 59666430, 18058404, 18068185, 9418, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226162571, 226164887, 18068200, 18070516, 33276, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193494754, 193502808, 18070531, 18078585, 27240, "entier"], ["github/Python", "django/django", "Python", 1657454, 1660178, 18078600, 18081324, 302, "entier"], ["github/C", "curl/curl", "C", 98733470, 98736065, 18081339, 18083934, 13555, "entier"], ["github/Scala", "playframework/playframework", "Scala", 225879394, 225879890, 18083949, 18084445, 33207, "entier"], ["github/Java", "apache/commons-lang", "Java", 153260898, 153272316, 18084460, 18095878, 20306, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238424521, 238424589, 18095893, 18095961, 36514, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236432593, 236432988, 18095976, 18096371, 35583, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206097929, 206098714, 18096386, 18097171, 29830, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175134804, 175148014, 18097186, 18110396, 23647, "entier"], ["github/Python", "django/django", "Python", 2156891, 2157448, 18110411, 18110968, 425, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213742162, 213742872, 18110983, 18111693, 31671, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202226846, 202227457, 18111708, 18112319, 28783, "entier"], ["github/C", "libuv/libuv", "C", 101423955, 101426166, 18112334, 18114545, 13880, "entier"], ["github/PHP", "laravel/framework", "PHP", 186610210, 186610537, 18114560, 18114887, 25939, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165152800, 165165198, 18114902, 18127300, 22034, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216761524, 216826926, 18127315, 18192717, 32167, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58668219, 58669539, 18192732, 18194052, 9252, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138143547, 138145549, 18194067, 18196069, 18096, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195049129, 195051974, 18196084, 18198929, 27520, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142000135, 142001075, 18198944, 18199884, 18713, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213603801, 213607895, 18199899, 18203993, 31645, "entier"], ["github/C", "curl/curl", "C", 97885086, 97886737, 18204008, 18205659, 13330, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 125420523, 125422292, 18205674, 18207443, 16090, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 20072817, 20108140, 18207458, 18242781, 2795, "entier"], ["github/C", "curl/curl", "C", 98342284, 98345054, 18242796, 18245566, 13420, "entier"], ["github/C++", "opencv/opencv", "C++", 113031189, 113039648, 18245581, 18254040, 15123, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209317540, 209321950, 18254055, 18258465, 30606, "entier"], ["github/Scala", "scala/scala", "Scala", 220394928, 220418070, 18258480, 18281622, 32476, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192390993, 192400999, 18281637, 18291643, 26973, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163519279, 163522226, 18291658, 18294605, 21725, "entier"], ["github/C++", "nlohmann/json", "C++", 103918695, 103919750, 18294620, 18295675, 14156, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206842680, 206843625, 18295690, 18296635, 30015, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144028194, 144055388, 18296650, 18323844, 19154, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177303661, 177305869, 18323859, 18326067, 23953, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206137392, 206138361, 18326082, 18327051, 29850, "entier"], ["github/Python", "django/django", "Python", 2801229, 2829761, 18327066, 18355598, 581, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159040454, 159043178, 18355613, 18358337, 21061, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195145825, 195146486, 18358352, 18359013, 27557, "entier"], ["github/Go", "gin-gonic/gin", "Go", 74930228, 74969746, 18359028, 18398546, 11086, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202164418, 202166340, 18398561, 18400483, 28767, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164375002, 164375914, 18400498, 18401410, 21895, "entier"], ["github/C++", "opencv/opencv", "C++", 117174509, 117186766, 18401425, 18413682, 15449, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193314485, 193319142, 18413697, 18418354, 27181, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200812284, 200816417, 18418369, 18422502, 28594, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238736680, 238738027, 18422517, 18423864, 36778, "entier"], ["github/Scala", "scala/scala", "Scala", 221642543, 221644048, 18423879, 18425384, 32592, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238348127, 238348165, 18425399, 18425437, 36124, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238410325, 238410353, 18425452, 18425480, 36352, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176117853, 176125245, 18425495, 18432887, 23782, "entier"], ["github/Java", "square/okhttp", "Java", 144759793, 144763135, 18432902, 18436244, 19366, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 167437333, 167446842, 18436259, 18445768, 22308, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204484451, 204486432, 18445783, 18447764, 29236, "entier"], ["github/Scala", "playframework/playframework", "Scala", 233384678, 233388621, 18447779, 18451722, 34788, "entier"], ["github/C++", "opencv/opencv", "C++", 111014954, 111020864, 18451737, 18457647, 14970, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194975783, 194985151, 18457662, 18467030, 27511, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209998823, 209999469, 18467045, 18467691, 30815, "entier"], ["github/Java", "square/okhttp", "Java", 146277199, 146283298, 18467706, 18473805, 19641, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210045463, 210045778, 18473820, 18474135, 30839, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227097079, 227100028, 18474150, 18477099, 33439, "entier"], ["github/C++", "google/leveldb", "C++", 110885000, 110886106, 18477114, 18478220, 14899, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211988895, 211990320, 18478235, 18479660, 31369, "entier"], ["github/C++", "opencv/opencv", "C++", 116696179, 116697414, 18479675, 18480910, 15345, "entier"], ["github/C", "madler/zlib", "C", 102619408, 102645422, 18480925, 18506939, 14049, "entier"], ["github/C++", "google/leveldb", "C++", 110675625, 110677472, 18506954, 18508801, 14859, "entier"], ["github/Python", "pallets/flask", "Python", 353666, 353964, 18508816, 18509114, 50, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231416919, 231419520, 18509129, 18511730, 34488, "entier"], ["github/PHP", "laravel/framework", "PHP", 188542400, 188543068, 18511745, 18512413, 26307, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204891835, 204895164, 18512428, 18515757, 29442, "entier"], ["github/Java", "google/guava", "Java", 129856408, 129864333, 18515772, 18523697, 16683, "entier"], ["github/C++", "opencv/opencv", "C++", 116402000, 116404282, 18523712, 18525994, 15287, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235145512, 235146275, 18526009, 18526772, 35332, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213581019, 213581538, 18526787, 18527306, 31637, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 32003728, 32023496, 18527321, 18547089, 4174, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180010844, 180014573, 18547104, 18550833, 24392, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238049407, 238054707, 18550848, 18556148, 35797, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136867181, 136869508, 18556163, 18558490, 17792, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206497381, 206500091, 18558505, 18561215, 29953, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136147611, 136149421, 18561230, 18563040, 17342, "entier"], ["github/Java", "apache/commons-lang", "Java", 150738813, 150740094, 18563055, 18564336, 20122, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233642899, 233643508, 18564351, 18564960, 34877, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197229126, 197241289, 18564975, 18577138, 27956, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226172248, 226173857, 18577153, 18578762, 33278, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144213336, 144214653, 18578777, 18580094, 19198, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159804961, 159817717, 18580109, 18592865, 21168, "entier"], ["github/Python", "psf/requests", "Python", 196693, 212036, 18592880, 18608223, 27, "entier"], ["github/Scala", "scala/scala", "Scala", 224194757, 224195291, 18608238, 18608772, 32919, "entier"], ["github/Scala", "scala/scala", "Scala", 224100946, 224101689, 18608787, 18609530, 32868, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90752795, 90755042, 18609545, 18611792, 12648, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211551642, 211556297, 18611807, 18616462, 31282, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 181071877, 181075930, 18616477, 18620530, 24629, "entier"], ["github/Go", "prometheus/prometheus", "Go", 79697954, 79698699, 18620545, 18621290, 11501, "entier"], ["github/Scala", "scala/scala", "Scala", 221222980, 221228929, 18621305, 18627254, 32518, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213391657, 213392323, 18627269, 18627935, 31583, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19020261, 19020282, 18627950, 18627971, 2485, "entier"], ["github/Java", "google/guava", "Java", 132518079, 132535830, 18627986, 18645737, 16984, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213295107, 213295836, 18645752, 18646481, 31555, "entier"], ["github/PHP", "laravel/framework", "PHP", 187016058, 187018659, 18646496, 18649097, 26034, "entier"], ["github/Scala", "scala/scala", "Scala", 224597332, 224600260, 18649112, 18652040, 33051, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197894485, 197895596, 18652055, 18653166, 28091, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192678145, 192678755, 18653181, 18653791, 27038, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164799393, 164801650, 18653806, 18656063, 22003, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177370858, 177374088, 18656078, 18659308, 23973, "entier"], ["github/Python", "django/django", "Python", 2393121, 2397157, 18659323, 18663359, 499, "entier"], ["github/Scala", "scala/scala", "Scala", 225170578, 225173458, 18663374, 18666254, 33126, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194664963, 194666664, 18666269, 18667970, 27446, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 31115074, 31126583, 18667985, 18679494, 4128, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197051735, 197053758, 18679509, 18681532, 27892, "entier"], ["github/Java", "square/okhttp", "Java", 144908323, 144909955, 18681547, 18683179, 19397, "entier"], ["github/Scala", "scala/scala", "Scala", 219078660, 219081926, 18683194, 18686460, 32370, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 15484386, 15487152, 18686475, 18689241, 2059, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194434046, 194434689, 18689256, 18689899, 27348, "entier"], ["github/Go", "gohugoio/hugo", "Go", 84715560, 84732299, 18689914, 18706653, 11798, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 124611224, 124662835, 18706668, 18758279, 16028, "entier"], ["github/Java", "square/okhttp", "Java", 144959352, 144965440, 18758294, 18764382, 19421, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195025670, 195028519, 18764397, 18767246, 27515, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179505082, 179507590, 18767261, 18769769, 24321, "entier"], ["github/Python", "django/django", "Python", 9093498, 9094904, 18769784, 18771190, 1411, "entier"], ["github/Java", "square/okhttp", "Java", 146138809, 146140211, 18771205, 18772607, 19618, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238784552, 238791495, 18772622, 18779565, 36792, "entier"], ["github/PHP", "laravel/framework", "PHP", 186335809, 186339253, 18779580, 18783024, 25836, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 20961460, 20963619, 18783039, 18785198, 2845, "entier"], ["github/Java", "google/guava", "Java", 133348514, 133351423, 18785213, 18788122, 17087, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207448841, 207467800, 18788137, 18807096, 30146, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238370597, 238370710, 18807111, 18807224, 36205, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 49608544, 49859305, 18807239, 19058000, 7142, "entier"], ["github/PHP", "laravel/framework", "PHP", 185557236, 185559929, 19058015, 19060708, 25629, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 70473306, 70583895, 19060723, 19171312, 10550, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137941641, 137949931, 19171327, 19179617, 18039, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9499439, 9511478, 19179632, 19191671, 1501, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229138855, 229143548, 19191686, 19196379, 33747, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75055152, 75055632, 19196394, 19196874, 11112, "entier"], ["github/PHP", "laravel/framework", "PHP", 182578245, 182579899, 19196889, 19198543, 25046, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195965901, 195968140, 19198558, 19200797, 27696, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226032326, 226039671, 19200812, 19208157, 33241, "entier"], ["github/Go", "gohugoio/hugo", "Go", 86843398, 86851842, 19208172, 19216616, 12121, "entier"], ["github/Python", "django/django", "Python", 6888609, 6888974, 19216631, 19216996, 1200, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24638648, 24658300, 19217011, 19236663, 3215, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176142037, 176155723, 19236678, 19250364, 23785, "entier"], ["github/Java", "google/guava", "Java", 133851965, 133869831, 19250379, 19268245, 17130, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202364777, 202364850, 19268260, 19268333, 28838, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238333356, 238333404, 19268348, 19268396, 36082, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210060926, 210061149, 19268411, 19268634, 30851, "entier"], ["github/PHP", "laravel/framework", "PHP", 187906255, 187918285, 19268649, 19280679, 26192, "entier"], ["github/C++", "nlohmann/json", "C++", 104061185, 104061668, 19280694, 19281177, 14311, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211619437, 211626002, 19281192, 19287757, 31307, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126758258, 126761308, 19287772, 19290822, 16204, "entier"], ["github/Go", "gohugoio/hugo", "Go", 84991330, 84998190, 19290837, 19297697, 11850, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139223213, 139227896, 19297712, 19302395, 18290, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18681002, 18681538, 19302410, 19302946, 2337, "entier"], ["github/PHP", "laravel/framework", "PHP", 185056236, 185058342, 19302961, 19305067, 25477, "entier"], ["github/C++", "opencv/opencv", "C++", 117423621, 117431841, 19305082, 19313302, 15465, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202286363, 202287593, 19313317, 19314547, 28814, "entier"], ["github/PHP", "laravel/framework", "PHP", 188103478, 188105406, 19314562, 19316490, 26229, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90501646, 90502930, 19316505, 19317789, 12600, "entier"], ["github/Java", "google/guava", "Java", 130582043, 130590168, 19317804, 19325929, 16740, "entier"], ["github/C", "libuv/libuv", "C", 100180072, 100224051, 19325944, 19369923, 13771, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34623523, 34629389, 19369938, 19375804, 4439, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195388394, 195388903, 19375819, 19376328, 27624, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88930962, 88932753, 19376343, 19378134, 12392, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190926307, 190927785, 19378149, 19379627, 26761, "entier"], ["github/C++", "opencv/opencv", "C++", 116669568, 116671180, 19379642, 19381254, 15332, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 127251823, 127252412, 19381269, 19381858, 16246, "entier"], ["github/Java", "apache/commons-lang", "Java", 151635794, 151640041, 19381873, 19386120, 20202, "entier"], ["github/PHP", "laravel/framework", "PHP", 188012051, 188015664, 19386135, 19389748, 26209, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27598020, 27600345, 19389763, 19392088, 3708, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 164867262, 164926489, 19392103, 19451330, 22022, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178856467, 178861138, 19451345, 19456016, 24206, "entier"], ["github/Scala", "scala/scala", "Scala", 220326825, 220365500, 19456031, 19494706, 32472, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27377927, 27379530, 19494721, 19496324, 3657, "entier"], ["github/PHP", "laravel/framework", "PHP", 188559572, 188561231, 19496339, 19497998, 26325, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27095404, 27095943, 19498013, 19498552, 3582, "entier"], ["github/PHP", "laravel/framework", "PHP", 184086207, 184086336, 19498567, 19498696, 25333, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197383740, 197385974, 19498711, 19500945, 27973, "entier"], ["github/C++", "opencv/opencv", "C++", 111610738, 111625919, 19500960, 19516141, 15010, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143000249, 143012293, 19516156, 19528200, 18972, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214052738, 214069807, 19528215, 19545284, 31746, "entier"], ["github/PHP", "laravel/framework", "PHP", 184626650, 184629222, 19545299, 19547871, 25394, "entier"], ["github/Go", "prometheus/prometheus", "Go", 82819945, 82836573, 19547886, 19564514, 11671, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 30328982, 30337685, 19564529, 19573232, 4074, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174893672, 174897195, 19573247, 19576770, 23609, "entier"], ["github/PHP", "laravel/framework", "PHP", 184770490, 184776714, 19576785, 19583009, 25417, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144549320, 144561329, 19583024, 19595033, 19302, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179507605, 179508752, 19595048, 19596195, 24322, "entier"], ["github/C++", "opencv/opencv", "C++", 117011334, 117018237, 19596210, 19603113, 15411, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28644667, 28646473, 19603128, 19604934, 3914, "entier"], ["github/C++", "nlohmann/json", "C++", 104161594, 104162101, 19604949, 19605456, 14441, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 181277602, 181280232, 19605471, 19608101, 24668, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141988139, 141989200, 19608116, 19609177, 18700, "entier"], ["github/PHP", "laravel/framework", "PHP", 182249968, 182254708, 19609192, 19613932, 24878, "entier"], ["github/C++", "fmtlib/fmt", "C++", 109838548, 109840814, 19613947, 19616213, 14754, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89048293, 89049367, 19616228, 19617302, 12410, "entier"], ["github/C++", "nlohmann/json", "C++", 103955054, 103955859, 19617317, 19618122, 14192, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137777066, 137783294, 19618137, 19624365, 18007, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90727913, 90730523, 19624380, 19626990, 12645, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197381615, 197383725, 19627005, 19629115, 27972, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126229701, 126236176, 19629130, 19635605, 16132, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190900356, 190901304, 19635620, 19636568, 26756, "entier"], ["github/Java", "apache/commons-lang", "Java", 151001743, 151005405, 19636583, 19640245, 20169, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209628022, 209638016, 19640260, 19650254, 30685, "entier"], ["github/Go", "spf13/cobra", "Go", 76028328, 76032982, 19650269, 19654923, 11198, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35030713, 35050337, 19654938, 19674562, 4491, "entier"], ["github/Python", "django/django", "Python", 4891392, 4975263, 19674577, 19758448, 847, "entier"], ["github/PHP", "laravel/framework", "PHP", 182780905, 182787973, 19758463, 19765531, 25132, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175148029, 175156733, 19765546, 19774250, 23648, "entier"], ["github/Java", "apache/commons-lang", "Java", 150461470, 150477810, 19774265, 19790605, 20073, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200242603, 200242974, 19790620, 19790991, 28427, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204814822, 204815837, 19791006, 19792021, 29342, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204860685, 204861197, 19792036, 19792548, 29406, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 64007253, 64008799, 19792563, 19794109, 9931, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213011965, 213012370, 19794124, 19794529, 31500, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226300292, 226331575, 19794544, 19825827, 33295, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71575733, 71576419, 19825842, 19826528, 10831, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19463246, 19463413, 19826543, 19826710, 2732, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27301051, 27302467, 19826725, 19828141, 3618, "entier"], ["github/PHP", "laravel/framework", "PHP", 189426286, 189437442, 19828156, 19839312, 26464, "entier"], ["github/Go", "prometheus/prometheus", "Go", 80847078, 80862163, 19839327, 19854412, 11559, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63929094, 63933339, 19854427, 19858672, 9920, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19054237, 19054333, 19858687, 19858783, 2554, "entier"], ["github/Java", "square/okhttp", "Java", 144568399, 144573299, 19858798, 19863698, 19309, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26877373, 26878330, 19863713, 19864670, 3500, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203240499, 203247160, 19864685, 19871346, 28921, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27377399, 27377587, 19871361, 19871549, 3655, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168164342, 168165800, 19871564, 19873022, 22389, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34478098, 34481302, 19873037, 19876241, 4418, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137937239, 137941626, 19876256, 19880643, 18038, "entier"], ["github/C", "curl/curl", "C", 92098539, 92114287, 19880658, 19896406, 12879, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162642471, 162643375, 19896421, 19897325, 21576, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178370261, 178375062, 19897340, 19902141, 24162, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160888092, 160888941, 19902156, 19903005, 21296, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168669719, 168671105, 19903020, 19904406, 22661, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206800311, 206801882, 19904421, 19905992, 30007, "entier"], ["github/PHP", "laravel/framework", "PHP", 189010392, 189014646, 19906007, 19910261, 26407, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19463809, 19469287, 19910276, 19915754, 2734, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142158195, 142168261, 19915769, 19925835, 18781, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158362133, 158364594, 19925850, 19928311, 20953, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177515782, 177516543, 19928326, 19929087, 24015, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197450154, 197451299, 19929102, 19930247, 27988, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19132762, 19133779, 19930262, 19931279, 2688, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230735054, 230735623, 19931294, 19931863, 34330, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161664707, 161667136, 19931878, 19934307, 21406, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27887092, 27887922, 19934322, 19935152, 3783, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89202129, 89208642, 19935167, 19941680, 12438, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19561127, 19562446, 19941695, 19943014, 2751, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19082244, 19082449, 19943029, 19943234, 2620, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203577061, 203586417, 19943249, 19952605, 28980, "entier"], ["github/Java", "google/guava", "Java", 135853182, 135861636, 19952620, 19961074, 17319, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26881948, 26882813, 19961089, 19961954, 3505, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33595701, 33596492, 19961969, 19962760, 4304, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178387386, 178393472, 19962775, 19968861, 24165, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18233676, 18235422, 19968876, 19970622, 2240, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157736239, 157741608, 19970637, 19976006, 20790, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85423009, 85426399, 19976021, 19979411, 11943, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137683087, 137689707, 19979426, 19986046, 17986, "entier"], ["github/Scala", "scala/scala", "Scala", 223198198, 223215090, 19986061, 20002953, 32742, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204242562, 204243804, 20002968, 20004210, 29181, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159206012, 159207932, 20004225, 20006145, 21088, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69779151, 69817694, 20006160, 20044703, 10532, "entier"], ["github/Java", "google/guava", "Java", 132752179, 132753905, 20044718, 20046444, 17009, "entier"], ["github/Go", "gohugoio/hugo", "Go", 84569624, 84574237, 20046459, 20051072, 11773, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33167198, 33179231, 20051087, 20063120, 4240, "entier"], ["github/Java", "apache/commons-lang", "Java", 149990579, 149994016, 20063135, 20066572, 20029, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170621641, 170625637, 20066587, 20070583, 22860, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137689722, 137692861, 20070598, 20073737, 17987, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207090578, 207097144, 20073752, 20080318, 30082, "entier"], ["github/Go", "prometheus/prometheus", "Go", 84019141, 84020677, 20080333, 20081869, 11747, "entier"], ["github/C++", "opencv/opencv", "C++", 115702479, 115799049, 20081884, 20178454, 15231, "entier"], ["github/Java", "square/okhttp", "Java", 148708963, 148710044, 20178469, 20179550, 19875, "entier"], ["github/C", "jqlang/jq", "C", 103753434, 103769925, 20179565, 20196056, 14120, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162555916, 162556624, 20196071, 20196779, 21550, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177411033, 177417955, 20196794, 20203716, 23981, "entier"], ["github/Java", "google/guava", "Java", 129849326, 129856393, 20203731, 20210798, 16682, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85042741, 85048982, 20210813, 20217054, 11864, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204161137, 204162586, 20217069, 20218518, 29142, "entier"], ["github/Java", "google/guava", "Java", 132256844, 132258041, 20218533, 20219730, 16925, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237447730, 237462358, 20219745, 20234373, 35694, "entier"], ["github/Python", "django/django", "Python", 8476498, 8477569, 20234388, 20235459, 1346, "entier"], ["github/JavaScript", "lodash/lodash", "JavaScript", 18659698, 18669653, 20235474, 20245429, 2329, "entier"], ["github/Java", "apache/commons-lang", "Java", 149931111, 149937258, 20245444, 20251591, 20023, "entier"], ["github/Python", "django/django", "Python", 1005383, 1006291, 20251606, 20252514, 202, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 179919400, 179919857, 20252529, 20252986, 24368, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198945880, 198997989, 20253001, 20305110, 28209, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178888229, 178889609, 20305125, 20306505, 24216, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 166681065, 166695509, 20306520, 20320964, 22259, "entier"], ["github/Java", "google/guava", "Java", 128633533, 128637234, 20320979, 20324680, 16480, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85472476, 85482508, 20324695, 20334727, 11953, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27452611, 27454057, 20334742, 20336188, 3675, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 15922020, 15931825, 20336203, 20346008, 2076, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174189688, 174192393, 20346023, 20348728, 23471, "entier"], ["github/C", "curl/curl", "C", 91485312, 91487627, 20348743, 20351058, 12797, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138206874, 138213556, 20351073, 20357755, 18117, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28243854, 28245111, 20357770, 20359027, 3857, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18988421, 18988698, 20359042, 20359319, 2388, "entier"], ["github/C", "madler/zlib", "C", 102883602, 102884024, 20359334, 20359756, 14065, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177397388, 177397551, 20359771, 20359934, 23979, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138130832, 138132154, 20359949, 20361271, 18085, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35667067, 35670460, 20361286, 20364679, 4586, "entier"], ["github/C", "curl/curl", "C", 91418529, 91420427, 20364694, 20366592, 12778, "entier"], ["github/Java", "google/guava", "Java", 133703620, 133704648, 20366607, 20367635, 17114, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231911633, 231923501, 20367650, 20379518, 34570, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 67422359, 67430691, 20379533, 20387865, 10367, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179713643, 179715764, 20387880, 20390001, 24349, "entier"], ["github/Java", "square/okhttp", "Java", 147882428, 147884397, 20390016, 20391985, 19806, "entier"], ["github/Go", "gohugoio/hugo", "Go", 91092206, 91093452, 20392000, 20393246, 12690, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19004312, 19005551, 20393261, 20394500, 2441, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168438786, 168440160, 20394515, 20395889, 22531, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136209090, 136210868, 20395904, 20397682, 17392, "entier"], ["github/C", "curl/curl", "C", 97259133, 97260546, 20397697, 20399110, 13257, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89101603, 89102614, 20399125, 20400136, 12421, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21840557, 21841755, 20400151, 20401349, 2973, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144304380, 144306344, 20401364, 20403328, 19227, "entier"], ["github/Python", "django/django", "Python", 5604135, 5609453, 20403343, 20408661, 969, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 201779499, 201806943, 20408676, 20436120, 28720, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162189183, 162192232, 20436135, 20439184, 21475, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71526162, 71527190, 20439199, 20440227, 10757, "entier"], ["github/Scala", "scala/scala", "Scala", 221703965, 221704574, 20440242, 20440851, 32631, "entier"], ["github/Java", "square/okhttp", "Java", 148936044, 148942308, 20440866, 20447130, 19924, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177686538, 177690407, 20447145, 20451014, 24051, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25098654, 25105471, 20451029, 20457846, 3259, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63168495, 63171309, 20457861, 20460675, 9784, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170307416, 170308785, 20460690, 20462059, 22806, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137837016, 137839853, 20462074, 20464911, 18014, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231537836, 231545027, 20464926, 20472117, 34513, "entier"], ["github/Java", "google/guava", "Java", 134299813, 134301880, 20472132, 20474199, 17164, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19109020, 19109049, 20474214, 20474243, 2640, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89352718, 89365922, 20474258, 20487462, 12466, "entier"], ["github/Python", "django/django", "Python", 4807987, 4817673, 20487477, 20497163, 824, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175573773, 175575016, 20497178, 20498421, 23664, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41209876, 41210470, 20498436, 20499030, 5262, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165424191, 165429890, 20499045, 20504744, 22045, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37356334, 37357624, 20504759, 20506049, 4776, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139786352, 139790116, 20506064, 20509828, 18376, "entier"], ["github/Scala", "scala/scala", "Scala", 224661202, 224663465, 20509843, 20512106, 33073, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176125260, 176126566, 20512121, 20513427, 23783, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227021276, 227022948, 20513442, 20515114, 33412, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55832904, 55837433, 20515129, 20519658, 8602, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139908654, 139913730, 20519673, 20524749, 18399, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168319195, 168320632, 20524764, 20526201, 22461, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27940104, 27952606, 20526216, 20538718, 3791, "entier"], ["github/Scala", "scala/scala", "Scala", 224132556, 224135548, 20538733, 20541725, 32888, "entier"], ["github/Python", "django/django", "Python", 2460180, 2463131, 20541740, 20544691, 521, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168195007, 168196748, 20544706, 20546447, 22409, "entier"], ["github/C", "curl/curl", "C", 94386034, 94406680, 20546462, 20567108, 13076, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90153146, 90153449, 20567123, 20567426, 12572, "entier"], ["github/C++", "nlohmann/json", "C++", 104070930, 104071269, 20567441, 20567780, 14325, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227316700, 227318307, 20567795, 20569402, 33502, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190746714, 190749324, 20569417, 20572027, 26703, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78923927, 78926107, 20572042, 20574222, 11447, "entier"], ["github/Scala", "scala/scala", "Scala", 221701599, 221702187, 20574237, 20574825, 32627, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158717787, 158719349, 20574840, 20576402, 20996, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235300882, 235302852, 20576417, 20578387, 35376, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120902348, 120907937, 20578402, 20583991, 15677, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11181415, 11186447, 20584006, 20589038, 1794, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38303775, 38314555, 20589053, 20599833, 4973, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207671819, 207672197, 20599848, 20600226, 30219, "entier"], ["github/Java", "google/guava", "Java", 129262716, 129280456, 20600241, 20617981, 16601, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162122504, 162125625, 20617996, 20621117, 21459, "entier"], ["github/Go", "gohugoio/hugo", "Go", 84795503, 84799140, 20621132, 20624769, 11804, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27310282, 27310699, 20624784, 20625201, 3624, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172872494, 172882111, 20625216, 20634833, 23321, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237273247, 237279336, 20634848, 20640937, 35678, "entier"], ["github/C++", "fmtlib/fmt", "C++", 109576746, 109582855, 20640952, 20647061, 14732, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214361699, 214367294, 20647076, 20652671, 31824, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43617278, 43617606, 20652686, 20653014, 5991, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136372100, 136373317, 20653029, 20654246, 17502, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227009858, 227013667, 20654261, 20658070, 33409, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9481372, 9491681, 20658085, 20668394, 1496, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 122531243, 122534400, 20668409, 20671566, 15878, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209586087, 209586925, 20671581, 20672419, 30673, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238444987, 238445197, 20672434, 20672644, 36640, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226920987, 226923179, 20672659, 20674851, 33385, "entier"], ["github/Java", "square/okhttp", "Java", 145141961, 145150940, 20674866, 20683845, 19459, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205559315, 205561445, 20683860, 20685990, 29665, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46237387, 46247891, 20686005, 20696509, 6857, "entier"], ["github/C++", "google/leveldb", "C++", 110773571, 110779108, 20696524, 20702061, 14877, "entier"], ["github/Scala", "scala/scala", "Scala", 221214377, 221217269, 20702076, 20704968, 32516, "entier"], ["github/PHP", "laravel/framework", "PHP", 181326016, 181353393, 20704983, 20732360, 24680, "entier"], ["github/Python", "django/django", "Python", 6086690, 6086786, 20732375, 20732471, 1044, "entier"], ["github/Python", "django/django", "Python", 1560082, 1560493, 20732486, 20732897, 274, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136196892, 136197631, 20732912, 20733651, 17380, "entier"], ["github/C++", "opencv/opencv", "C++", 116073121, 116073955, 20733666, 20734500, 15256, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206511543, 206514486, 20734515, 20737458, 29956, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238350123, 238350339, 20737473, 20737689, 36134, "entier"], ["github/C++", "nlohmann/json", "C++", 105905233, 105906258, 20737704, 20738729, 14585, "entier"], ["github/C++", "opencv/opencv", "C++", 116677859, 116679164, 20738744, 20740049, 15335, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56505456, 56506113, 20740064, 20740721, 9066, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24039873, 24068226, 20740736, 20769089, 3166, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211750333, 211751267, 20769104, 20770038, 31330, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44964451, 44964788, 20770053, 20770390, 6517, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43555451, 43555655, 20770405, 20770609, 5925, "entier"], ["github/Java", "google/guava", "Java", 132150715, 132159502, 20770624, 20779411, 16909, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44400833, 44402086, 20779426, 20780679, 6292, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121460573, 121465510, 20780694, 20785631, 15735, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204534162, 204536790, 20785646, 20788274, 29253, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42766266, 42768826, 20788289, 20790849, 5603, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126639241, 126639831, 20790864, 20791454, 16174, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52715069, 52715539, 20791469, 20791939, 7975, "entier"], ["github/C", "curl/curl", "C", 92607950, 92620353, 20791954, 20804357, 12936, "entier"], ["github/C++", "nlohmann/json", "C++", 105255412, 105257237, 20804372, 20806197, 14510, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207963281, 207964621, 20806212, 20807552, 30301, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52400140, 52403353, 20807567, 20810780, 7902, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 122646044, 122647656, 20810795, 20812407, 15888, "entier"], ["github/Java", "square/okhttp", "Java", 146224828, 146235473, 20812422, 20823067, 19632, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85912226, 85947524, 20823082, 20858380, 12038, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45243182, 45244112, 20858395, 20859325, 6700, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43612224, 43612363, 20859340, 20859479, 5979, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121066379, 121071850, 20859494, 20864965, 15691, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45133728, 45135032, 20864980, 20866284, 6636, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 13610547, 13633700, 20866299, 20889452, 1912, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214129615, 214135140, 20889467, 20894992, 31764, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51167585, 51167735, 20895007, 20895157, 7290, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141848013, 141850951, 20895172, 20898110, 18622, "entier"], ["github/C++", "opencv/opencv", "C++", 117042197, 117043614, 20898125, 20899542, 15418, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193233506, 193236511, 20899557, 20902562, 27158, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44048145, 44052237, 20902577, 20906669, 6200, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136223654, 136224602, 20906684, 20907632, 17402, "entier"], ["github/Java", "square/okhttp", "Java", 148980756, 148982531, 20907647, 20909422, 19941, "entier"], ["github/PHP", "laravel/framework", "PHP", 186608829, 186609233, 20909437, 20909841, 25936, "entier"], ["github/PHP", "laravel/framework", "PHP", 182592393, 182592514, 20909856, 20909977, 25066, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194477445, 194478135, 20909992, 20910682, 27383, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 180939159, 180959827, 20910697, 20931365, 24609, "entier"], ["github/Java", "google/guava", "Java", 135508710, 135510286, 20931380, 20932956, 17280, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211476520, 211479285, 20932971, 20935736, 31251, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 50816466, 50818856, 20935751, 20938141, 7173, "entier"], ["github/C", "libuv/libuv", "C", 99565389, 99567575, 20938156, 20940342, 13695, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143048579, 143052684, 20940357, 20944462, 18987, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27705660, 27709520, 20944477, 20948337, 3746, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56026109, 56027785, 20948352, 20950028, 8674, "entier"], ["github/PHP", "laravel/framework", "PHP", 187683590, 187689242, 20950043, 20955695, 26169, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212659801, 212661812, 20955710, 20957721, 31454, "entier"], ["github/C", "curl/curl", "C", 97130630, 97132252, 20957736, 20959358, 13231, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66868631, 66963683, 20959373, 21054425, 10339, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143022221, 143026853, 21054440, 21059072, 18978, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44145889, 44150386, 21059087, 21063584, 6236, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202403769, 202404719, 21063599, 21064549, 28851, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24414191, 24417128, 21064564, 21067501, 3201, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191879455, 191880390, 21067516, 21068451, 26886, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216545288, 216547956, 21068466, 21071134, 32143, "entier"], ["github/C", "curl/curl", "C", 92699023, 92701650, 21071149, 21073776, 12959, "entier"], ["github/Java", "apache/commons-lang", "Java", 151598640, 151601076, 21073791, 21076227, 20198, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190622822, 190624133, 21076242, 21077553, 26673, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50980356, 50981311, 21077568, 21078523, 7230, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27745323, 27747395, 21078538, 21080610, 3760, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9283797, 9286792, 21080625, 21083620, 1453, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192587411, 192590779, 21083635, 21087003, 27026, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44879714, 44883254, 21087018, 21090558, 6438, "entier"], ["github/C", "curl/curl", "C", 91489756, 91492278, 21090573, 21093095, 12799, "entier"], ["github/Python", "django/django", "Python", 6618660, 6619936, 21093110, 21094386, 1151, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27547878, 27551693, 21094401, 21098216, 3691, "entier"], ["github/Python", "django/django", "Python", 5007633, 5007678, 21098231, 21098276, 876, "entier"], ["github/PHP", "laravel/framework", "PHP", 182530096, 182530715, 21098291, 21098910, 24992, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52736977, 52739614, 21098925, 21101562, 7986, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19071248, 19071965, 21101577, 21102294, 2592, "entier"], ["github/C", "curl/curl", "C", 98641548, 98643332, 21102309, 21104093, 13529, "entier"], ["github/C++", "opencv/opencv", "C++", 112207700, 112248174, 21104108, 21144582, 15042, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11062451, 11066912, 21144597, 21149058, 1779, "entier"], ["github/JavaScript", "lodash/lodash", "JavaScript", 18669788, 18670322, 21149073, 21149607, 2331, "entier"], ["github/Java", "google/guava", "Java", 135807858, 135826836, 21149622, 21168600, 17313, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52388969, 52390047, 21168615, 21169693, 7897, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46834146, 46835009, 21169708, 21170571, 6900, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35503590, 35506553, 21170586, 21173549, 4555, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44965345, 44965657, 21173564, 21173876, 6519, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203959874, 203976963, 21173891, 21190980, 29088, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19099548, 19099688, 21190995, 21191135, 2628, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19114713, 19114928, 21191150, 21191365, 2648, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189876415, 189887393, 21191380, 21202358, 26530, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35709008, 35711620, 21202373, 21204985, 4601, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45086951, 45094474, 21205000, 21212523, 6606, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227635505, 227718239, 21212538, 21295272, 33513, "entier"], ["github/Python", "pallets/flask", "Python", 454540, 463821, 21295287, 21304568, 60, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143473987, 143476656, 21304583, 21307252, 19030, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35606879, 35611761, 21307267, 21312149, 4572, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42771462, 42772009, 21312164, 21312711, 5606, "entier"], ["github/PHP", "laravel/framework", "PHP", 182028225, 182029773, 21312726, 21314274, 24824, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138711837, 138718105, 21314289, 21320557, 18209, "entier"], ["github/C", "libuv/libuv", "C", 100569137, 100582643, 21320572, 21334078, 13793, "entier"], ["github/Go", "prometheus/prometheus", "Go", 76646148, 76666352, 21334093, 21354297, 11252, "entier"], ["github/PHP", "laravel/framework", "PHP", 185002181, 185003257, 21354312, 21355388, 25464, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19118292, 19118375, 21355403, 21355486, 2662, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19019792, 19019813, 21355501, 21355522, 2481, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234293004, 234318284, 21355537, 21380817, 35160, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39232230, 39236111, 21380832, 21384713, 5070, "entier"], ["github/Python", "django/django", "Python", 3737120, 3737719, 21384728, 21385327, 668, "entier"], ["github/PHP", "laravel/framework", "PHP", 187384507, 187385140, 21385342, 21385975, 26106, "entier"], ["github/PHP", "laravel/framework", "PHP", 182915349, 182915581, 21385990, 21386222, 25174, "entier"], ["github/PHP", "laravel/framework", "PHP", 187694466, 187695358, 21386237, 21387129, 26172, "entier"], ["github/Python", "django/django", "Python", 8177654, 8179318, 21387144, 21388808, 1315, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44102045, 44102943, 21388823, 21389721, 6215, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 167976729, 168066358, 21389736, 21479365, 22334, "entier"], ["github/Python", "django/django", "Python", 3844647, 3846391, 21479380, 21481124, 683, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210827523, 210829201, 21481139, 21482817, 31096, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 127268125, 127268471, 21482832, 21483178, 16253, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41924527, 41928476, 21483193, 21487142, 5352, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 127268486, 127269804, 21487157, 21488475, 16254, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 119946439, 119948812, 21488490, 21490863, 15587, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204460714, 204463374, 21490878, 21493538, 29223, "entier"], ["github/Python", "psf/requests", "Python", 329178, 334325, 21493553, 21498700, 32, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121204618, 121205704, 21498715, 21499801, 15708, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199759450, 199770590, 21499816, 21510956, 28258, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 199947323, 199947461, 21510971, 21511109, 28277, "entier"], ["github/C++", "nlohmann/json", "C++", 107697930, 107698999, 21511124, 21512193, 14651, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51988450, 51992912, 21512208, 21516670, 7705, "entier"], ["github/Java", "google/guava", "Java", 129053821, 129079769, 21516685, 21542633, 16561, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212676569, 212679942, 21542648, 21546021, 31458, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 119718901, 119724586, 21546036, 21551721, 15562, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85396895, 85397997, 21551736, 21552838, 11936, "entier"], ["github/C", "libuv/libuv", "C", 100851796, 100856167, 21552853, 21557224, 13809, "entier"], ["github/Python", "django/django", "Python", 3979156, 3984740, 21557239, 21562823, 718, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176798546, 176819179, 21562838, 21583471, 23818, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210870331, 210872334, 21583486, 21585489, 31107, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 125358856, 125360859, 21585504, 21587507, 16074, "entier"], ["github/Python", "django/django", "Python", 5503486, 5503913, 21587522, 21587949, 950, "entier"], ["github/C++", "opencv/opencv", "C++", 116692647, 116694400, 21587964, 21589717, 15343, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209733188, 209734595, 21589732, 21591139, 30707, "entier"], ["github/C++", "fmtlib/fmt", "C++", 110026948, 110028285, 21591154, 21592491, 14780, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209993174, 209994337, 21592506, 21593669, 30811, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192765996, 192775202, 21593684, 21602890, 27051, "entier"], ["github/Java", "google/guava", "Java", 130953505, 130955146, 21602905, 21604546, 16799, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75417169, 75429137, 21604561, 21616529, 11149, "entier"], ["github/Java", "square/okhttp", "Java", 145154288, 145157989, 21616544, 21620245, 19461, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34152155, 34194278, 21620260, 21662383, 4380, "entier"], ["github/Java", "google/guava", "Java", 132242631, 132245839, 21662398, 21665606, 16918, "entier"], ["github/C", "libuv/libuv", "C", 101619016, 101628521, 21665621, 21675126, 13921, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206485242, 206493402, 21675141, 21683301, 29950, "entier"], ["github/Python", "django/django", "Python", 4190664, 4207378, 21683316, 21700030, 738, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 122756841, 122776829, 21700045, 21720033, 15902, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75402729, 75407582, 21720048, 21724901, 11146, "entier"], ["github/PHP", "laravel/framework", "PHP", 184505630, 184521870, 21724916, 21741156, 25374, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138613398, 138637487, 21741171, 21765260, 18192, "entier"], ["github/Scala", "scala/scala", "Scala", 221203864, 221204654, 21765275, 21766065, 32509, "entier"], ["github/Scala", "sbt/sbt", "Scala", 239012716, 239014621, 21766080, 21767985, 36839, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211111189, 211117576, 21768000, 21774387, 31146, "entier"], ["github/C++", "opencv/opencv", "C++", 116754455, 116755612, 21774402, 21775559, 15365, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 49146108, 49195270, 21775574, 21824736, 7124, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78184084, 78187672, 21824751, 21828339, 11373, "entier"], ["github/Python", "django/django", "Python", 3971566, 3973202, 21828354, 21829990, 714, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229703485, 229703659, 21830005, 21830179, 33913, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 119366602, 119367064, 21830194, 21830656, 15539, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178886840, 178888214, 21830671, 21832045, 24215, "entier"], ["github/C++", "nlohmann/json", "C++", 107180395, 107181641, 21832060, 21833306, 14623, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 127268034, 127268110, 21833321, 21833397, 16252, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9437364, 9438634, 21833412, 21834682, 1487, "entier"], ["github/C", "libuv/libuv", "C", 101787748, 101795972, 21834697, 21842921, 13935, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178187723, 178188891, 21842936, 21844104, 24130, "entier"], ["github/Python", "django/django", "Python", 1555555, 1556369, 21844119, 21844933, 270, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89443525, 89445179, 21844948, 21846602, 12478, "entier"], ["github/Python", "django/django", "Python", 1596757, 1597693, 21846617, 21847553, 279, "entier"], ["github/C++", "opencv/opencv", "C++", 116951518, 116958603, 21847568, 21854653, 15405, "entier"], ["github/PHP", "laravel/framework", "PHP", 185906203, 185906600, 21854668, 21855065, 25720, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211158754, 211161635, 21855080, 21857961, 31158, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197727879, 197729249, 21857976, 21859346, 28039, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85611911, 85617272, 21859361, 21864722, 11985, "entier"], ["github/Java", "google/guava", "Java", 134729457, 134736675, 21864737, 21871955, 17191, "entier"], ["github/PHP", "laravel/framework", "PHP", 187643617, 187646246, 21871970, 21874599, 26160, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208005157, 208007204, 21874614, 21876661, 30310, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19010592, 19010634, 21876676, 21876718, 2456, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18990742, 18990770, 21876733, 21876761, 2397, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 16563214, 16572717, 21876776, 21886279, 2100, "entier"], ["github/C++", "opencv/opencv", "C++", 112404540, 112409727, 21886294, 21891481, 15064, "entier"], ["github/C", "curl/curl", "C", 91177578, 91179629, 21891496, 21893547, 12718, "entier"], ["github/PHP", "laravel/framework", "PHP", 187196830, 187198126, 21893562, 21894858, 26076, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174182870, 174189673, 21894873, 21901676, 23470, "entier"], ["github/Java", "google/guava", "Java", 132125716, 132127282, 21901691, 21903257, 16904, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209816759, 209818082, 21903272, 21904595, 30729, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196621428, 196622370, 21904610, 21905552, 27836, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25105486, 25110237, 21905567, 21910318, 3260, "entier"], ["github/Java", "google/guava", "Java", 132497585, 132499161, 21910333, 21911909, 16976, "entier"], ["github/C", "jqlang/jq", "C", 103882829, 103883766, 21911924, 21912861, 14138, "entier"], ["github/Scala", "scala/scala", "Scala", 221553274, 221580132, 21912876, 21939734, 32580, "entier"], ["github/Java", "google/guava", "Java", 128208303, 128209996, 21939749, 21941442, 16383, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139412919, 139413544, 21941457, 21942082, 18318, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193472353, 193476135, 21942097, 21945879, 27231, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144492946, 144494401, 21945894, 21947349, 19277, "entier"], ["github/C", "curl/curl", "C", 98093343, 98096225, 21947364, 21950246, 13365, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205086502, 205090975, 21950261, 21954734, 29526, "entier"], ["github/Java", "square/okhttp", "Java", 144936304, 144937283, 21954749, 21955728, 19410, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137158085, 137158345, 21955743, 21956003, 17864, "entier"], ["github/Python", "encode/httpx", "Python", 17813626, 17816591, 21956018, 21958983, 2151, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63084539, 63129830, 21958998, 22004289, 9772, "entier"], ["github/C++", "google/leveldb", "C++", 110108510, 110124723, 22004304, 22020517, 14787, "entier"], ["github/Java", "apache/commons-lang", "Java", 156391450, 156398777, 22020532, 22027859, 20598, "entier"], ["github/Python", "django/django", "Python", 2480475, 2481969, 22027874, 22029368, 525, "entier"], ["github/PHP", "laravel/framework", "PHP", 182550952, 182556568, 22029383, 22034999, 25022, "entier"], ["github/Python", "django/django", "Python", 9187754, 9187963, 22035014, 22035223, 1430, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11386084, 11386263, 22035238, 22035417, 1807, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174644170, 174646673, 22035432, 22037935, 23518, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10345686, 10349552, 22037950, 22041816, 1656, "entier"], ["github/PHP", "laravel/framework", "PHP", 181562613, 181563320, 22041831, 22042538, 24740, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18595491, 18611063, 22042553, 22058125, 2315, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200582058, 200589953, 22058140, 22066035, 28521, "entier"], ["github/Java", "square/okhttp", "Java", 145925485, 145934577, 22066050, 22075142, 19595, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194762840, 194765114, 22075157, 22077431, 27470, "entier"], ["github/C", "curl/curl", "C", 98075090, 98084909, 22077446, 22087265, 13361, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47559281, 47561716, 22087280, 22089715, 6999, "entier"], ["github/Scala", "scala/scala", "Scala", 222401269, 222403428, 22089730, 22091889, 32698, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162755971, 162757418, 22091904, 22093351, 21611, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230246465, 230247455, 22093366, 22094356, 34111, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75253067, 75281730, 22094371, 22123034, 11131, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238440862, 238441120, 22123049, 22123307, 36613, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45969750, 45974147, 22123322, 22127719, 6817, "entier"], ["github/Java", "square/okhttp", "Java", 145243435, 145247813, 22127734, 22132112, 19485, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229714012, 229714419, 22132127, 22132534, 33929, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161106485, 161108588, 22132549, 22134652, 21355, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238303926, 238304000, 22134667, 22134741, 35947, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238333489, 238333999, 22134756, 22135266, 36084, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200027360, 200028879, 22135281, 22136800, 28328, "entier"], ["github/Java", "square/okhttp", "Java", 146734774, 146737232, 22136815, 22139273, 19715, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52047739, 52048536, 22139288, 22140085, 7740, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204182793, 204183753, 22140100, 22141060, 29158, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177579014, 177588435, 22141075, 22150496, 24033, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43498636, 43499975, 22150511, 22151850, 5839, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138742393, 138743481, 22151865, 22152953, 18211, "entier"], ["github/PHP", "laravel/framework", "PHP", 189023320, 189036636, 22152968, 22166284, 26409, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27756221, 27759194, 22166299, 22169272, 3764, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204815852, 204816345, 22169287, 22169780, 29343, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157092335, 157096506, 22169795, 22173966, 20647, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43509083, 43509387, 22173981, 22174285, 5852, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 36570944, 36570954, 22174300, 22174310, 4729, "entier"], ["github/C", "curl/curl", "C", 98868948, 98871063, 22174325, 22176440, 13587, "entier"], ["github/Scala", "scala/scala", "Scala", 222999340, 223009718, 22176455, 22186833, 32733, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 119734973, 119757766, 22186848, 22209641, 15565, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140480932, 140487208, 22209656, 22215932, 18482, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209356859, 209359866, 22215947, 22218954, 30612, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18466130, 18469094, 22218969, 22221933, 2279, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10284615, 10307386, 22221948, 22244719, 1648, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21919377, 21920578, 22244734, 22245935, 3022, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208177684, 208179666, 22245950, 22247932, 30358, "entier"], ["github/Java", "square/okhttp", "Java", 148959163, 148963449, 22247947, 22252233, 19930, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 40154230, 40165853, 22252248, 22263871, 5180, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238458225, 238458346, 22263886, 22264007, 36676, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27639154, 27641320, 22264022, 22266188, 3721, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196241534, 196242259, 22266203, 22266928, 27740, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235976430, 235978445, 22266943, 22268958, 35508, "entier"], ["github/PHP", "laravel/framework", "PHP", 185994816, 185995220, 22268973, 22269377, 25762, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141634381, 141636491, 22269392, 22271502, 18589, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19012102, 19012127, 22271517, 22271542, 2461, "entier"], ["github/PHP", "laravel/framework", "PHP", 187330824, 187332192, 22271557, 22272925, 26094, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71624909, 71626516, 22272940, 22274547, 10875, "entier"], ["github/Java", "google/guava", "Java", 128686398, 128691474, 22274562, 22279638, 16498, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34221962, 34226329, 22279653, 22284020, 4386, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71572536, 71573201, 22284035, 22284700, 10825, "entier"], ["github/PHP", "laravel/framework", "PHP", 181311931, 181315701, 22284715, 22288485, 24675, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163650485, 163664108, 22288500, 22302123, 21762, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63129845, 63131254, 22302138, 22303547, 9773, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203507446, 203515048, 22303562, 22311164, 28966, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144115347, 144116283, 22311179, 22312115, 19172, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18962564, 18962694, 22312130, 22312260, 2354, "entier"], ["github/Java", "google/guava", "Java", 133819497, 133821038, 22312275, 22313816, 17127, "entier"], ["github/PHP", "laravel/framework", "PHP", 182492791, 182496589, 22313831, 22317629, 24955, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141501169, 141506016, 22317644, 22322491, 18558, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234789634, 234804848, 22322506, 22337720, 35221, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39809764, 39817302, 22337735, 22345273, 5154, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88117002, 88123201, 22345288, 22351487, 12262, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144240787, 144246369, 22351502, 22357084, 19211, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 67566751, 67579610, 22357099, 22369958, 10372, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200102854, 200106572, 22369973, 22373691, 28372, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41886382, 41888298, 22373706, 22375622, 5335, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54517682, 54517948, 22375637, 22375903, 8405, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144403801, 144405466, 22375918, 22377583, 19258, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42916313, 42916655, 22377598, 22377940, 5657, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14854292, 14865198, 22377955, 22388861, 2027, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42449470, 42450050, 22388876, 22389456, 5450, "entier"], ["github/Go", "prometheus/prometheus", "Go", 79042885, 79046560, 22389471, 22393146, 11460, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 166070338, 166072893, 22393161, 22395716, 22228, "entier"], ["github/Java", "apache/commons-lang", "Java", 154105018, 154106184, 22395731, 22396897, 20347, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56376531, 56377570, 22396912, 22397951, 8951, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212887959, 212889345, 22397966, 22399352, 31478, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51317945, 51318996, 22399367, 22400418, 7430, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136846509, 136850951, 22400433, 22404875, 17783, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178447333, 178463860, 22404890, 22421417, 24173, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43013052, 43013839, 22421432, 22422219, 5693, "entier"], ["github/Go", "gohugoio/hugo", "Go", 86683259, 86685139, 22422234, 22424114, 12108, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196170211, 196185973, 22424129, 22439891, 27724, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229074729, 229081310, 22439906, 22446487, 33738, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47836507, 47837718, 22446502, 22447713, 7052, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208969805, 208973774, 22447728, 22451697, 30521, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60238382, 60239621, 22451712, 22452951, 9514, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 65592409, 65593325, 22452966, 22453882, 10193, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11088203, 11089887, 22453897, 22455581, 1787, "entier"], ["github/Python", "django/django", "Python", 9166005, 9166064, 22455596, 22455655, 1426, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168972528, 168981660, 22455670, 22464802, 22727, "entier"], ["github/Python", "django/django", "Python", 1324978, 1325327, 22464817, 22465166, 229, "entier"], ["github/Go", "prometheus/prometheus", "Go", 77939853, 77945646, 22465181, 22470974, 11346, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238772497, 238777090, 22470989, 22475582, 36787, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50955563, 50964975, 22475597, 22485009, 7209, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211578464, 211580668, 22485024, 22487228, 31290, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204695864, 204696661, 22487243, 22488040, 29307, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203777363, 203778000, 22488055, 22488692, 29033, "entier"], ["github/Scala", "scala/scala", "Scala", 217481202, 217483241, 22488707, 22490746, 32243, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209134465, 209134799, 22490761, 22491095, 30579, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136916767, 136942971, 22491110, 22517314, 17821, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234644700, 234645803, 22517329, 22518432, 35187, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208990331, 208991375, 22518447, 22519491, 30526, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227781489, 227781837, 22519506, 22519854, 33534, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45023111, 45024382, 22519869, 22521140, 6578, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207423819, 207424541, 22521155, 22521877, 30133, "entier"], ["github/Scala", "scala/scala", "Scala", 221683087, 221684495, 22521892, 22523300, 32607, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162837187, 162839800, 22523315, 22525928, 21623, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204693274, 204693801, 22525943, 22526470, 29302, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51018891, 51021684, 22526485, 22529278, 7250, "entier"], ["github/PHP", "laravel/framework", "PHP", 189250998, 189259399, 22529293, 22537694, 26435, "entier"], ["github/C++", "nlohmann/json", "C++", 108528205, 108594813, 22537709, 22604317, 14688, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10737058, 10752479, 22604332, 22619753, 1722, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41661984, 41662903, 22619768, 22620687, 5300, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52169321, 52169406, 22620702, 22620787, 7804, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216826941, 216862284, 22620802, 22656145, 32168, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208518548, 208523930, 22656160, 22661542, 30427, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39355756, 39359858, 22661557, 22665659, 5084, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192331868, 192333015, 22665674, 22666821, 26961, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190815557, 190815864, 22666836, 22667143, 26722, "entier"], ["github/Java", "square/okhttp", "Java", 145547896, 145550144, 22667158, 22669406, 19548, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51443513, 51444163, 22669421, 22670071, 7485, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199067316, 199068519, 22670086, 22671289, 28216, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52772765, 52772800, 22671304, 22671339, 7998, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52218878, 52219068, 22671354, 22671544, 7825, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211434467, 211434821, 22671559, 22671913, 31227, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56290697, 56290839, 22671928, 22672070, 8835, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 31615828, 31677215, 22672085, 22733472, 4148, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52013038, 52013679, 22733487, 22734128, 7719, "entier"], ["github/Java", "apache/commons-lang", "Java", 154397446, 154399567, 22734143, 22736264, 20390, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195085807, 195086826, 22736279, 22737298, 27533, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 67913431, 67947001, 22737313, 22770883, 10407, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45974965, 45976278, 22770898, 22772211, 6819, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192426691, 192427349, 22772226, 22772884, 26984, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144109736, 144111254, 22772899, 22774417, 19168, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37690533, 37690655, 22774432, 22774554, 4869, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197595610, 197596522, 22774569, 22775481, 28004, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172833961, 172841180, 22775496, 22782715, 23313, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44945242, 44946782, 22782730, 22784270, 6501, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137364958, 137367188, 22784285, 22786515, 17907, "entier"], ["github/PHP", "laravel/framework", "PHP", 182519192, 182520742, 22786530, 22788080, 24983, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141922880, 141923780, 22788095, 22788995, 18652, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 201372523, 201378469, 22789010, 22794956, 28684, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47868444, 47870930, 22794971, 22797457, 7058, "entier"], ["github/Java", "apache/commons-lang", "Java", 150645661, 150647107, 22797472, 22798918, 20093, "entier"], ["github/PHP", "laravel/framework", "PHP", 189624313, 189625516, 22798933, 22800136, 26484, "entier"], ["github/Python", "django/django", "Python", 4156460, 4163842, 22800151, 22807533, 735, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228423812, 228452152, 22807548, 22835888, 33610, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144324756, 144324999, 22835903, 22836146, 19235, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193602013, 193605664, 22836161, 22839812, 27256, "entier"], ["github/Java", "square/okhttp", "Java", 145665681, 145672619, 22839827, 22846765, 19575, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214160198, 214162283, 22846780, 22848865, 31769, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189865620, 189866509, 22848880, 22849769, 26527, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179236803, 179237418, 22849784, 22850399, 24266, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174784163, 174784393, 22850414, 22850644, 23542, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175848922, 175849145, 22850659, 22850882, 23748, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193458044, 193461472, 22850897, 22854325, 27225, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208147003, 208149430, 22854340, 22856767, 30351, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211414150, 211416813, 22856782, 22859445, 31212, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175733499, 175738626, 22859460, 22864587, 23719, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231391741, 231392051, 22864602, 22864912, 34482, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65399250, 65399390, 22864927, 22865067, 10102, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228706269, 228707504, 22865082, 22866317, 33666, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14689896, 14708857, 22866332, 22885293, 2017, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238321728, 238321737, 22885308, 22885317, 36046, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226749991, 226752091, 22885332, 22887432, 33350, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58474919, 58479246, 22887447, 22891774, 9197, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171878990, 171879654, 22891789, 22892453, 23083, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199906234, 199922125, 22892468, 22908359, 28270, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45457806, 45491268, 22908374, 22941836, 6741, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171875176, 171875514, 22941851, 22942189, 23079, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162325161, 162372223, 22942204, 22989266, 21508, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228488399, 228494756, 22989281, 22995638, 33612, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 180709482, 180711307, 22995653, 22997478, 24534, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89903533, 89967537, 22997493, 23061497, 12554, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238298087, 238298138, 23061512, 23061563, 35897, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60669502, 60679153, 23061578, 23071229, 9544, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230099747, 230101453, 23071244, 23072950, 34002, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238386792, 238387141, 23072965, 23073314, 36249, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203095712, 203113075, 23073329, 23090692, 28904, "entier"], ["github/PHP", "laravel/framework", "PHP", 182590435, 182590514, 23090707, 23090786, 25061, "entier"], ["github/Python", "django/django", "Python", 6542857, 6545208, 23090801, 23093152, 1118, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238652750, 238658346, 23093167, 23098763, 36748, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18996464, 18996600, 23098778, 23098914, 2424, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195052993, 195057265, 23098929, 23103201, 27522, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 62827044, 62828373, 23103216, 23104545, 9737, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120589911, 120627096, 23104560, 23141745, 15655, "entier"], ["github/PHP", "laravel/framework", "PHP", 186351591, 186352331, 23141760, 23142500, 25839, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71585295, 71587587, 23142515, 23144807, 10844, "entier"], ["github/Python", "encode/httpx", "Python", 18047490, 18057797, 23144822, 23155129, 2177, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35050352, 35060457, 23155144, 23165249, 4492, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238139080, 238146228, 23165264, 23172412, 35817, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55506078, 55506130, 23172427, 23172479, 8531, "entier"], ["github/Java", "apache/commons-lang", "Java", 151715112, 151800520, 23172494, 23257902, 20216, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42953984, 42955734, 23257917, 23259667, 5665, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43523800, 43525090, 23259682, 23260972, 5882, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195996609, 196009700, 23260987, 23274078, 27701, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19080649, 19080931, 23274093, 23274375, 2615, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37074249, 37080016, 23274390, 23280157, 4751, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 70277936, 70293314, 23280172, 23295550, 10545, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205765550, 205772684, 23295565, 23302699, 29714, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19545321, 19550588, 23302714, 23307981, 2744, "entier"], ["github/Python", "django/django", "Python", 2762266, 2771051, 23307996, 23316781, 572, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237804445, 237820134, 23316796, 23332485, 35739, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19080247, 19080529, 23332500, 23332782, 2613, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19024291, 19024387, 23332797, 23332893, 2504, "entier"], ["github/PHP", "laravel/framework", "PHP", 185121566, 185121643, 23332908, 23332985, 25499, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19461364, 19461722, 23333000, 23333358, 2727, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 27065979, 27066189, 23333373, 23333583, 3560, "entier"], ["github/C++", "nlohmann/json", "C++", 104104635, 104104856, 23333598, 23333819, 14364, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 50001364, 50007991, 23333834, 23340461, 7146, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25368544, 25370056, 23340476, 23341988, 3322, "entier"], ["github/PHP", "laravel/framework", "PHP", 181602174, 181605039, 23342003, 23344868, 24755, "entier"], ["github/C++", "nlohmann/json", "C++", 108601443, 108606292, 23344883, 23349732, 14690, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189907927, 189910535, 23349747, 23352355, 26541, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71394847, 71396065, 23352370, 23353588, 10687, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206126506, 206133558, 23353603, 23360655, 29847, "entier"], ["github/C++", "google/leveldb", "C++", 110898022, 110900695, 23360670, 23363343, 14906, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58395185, 58399079, 23363358, 23367252, 9173, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189914877, 189918483, 23367267, 23370873, 26544, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10896892, 10908353, 23370888, 23382349, 1753, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65389352, 65389553, 23382364, 23382565, 10065, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58527162, 58527366, 23382580, 23382784, 9228, "entier"], ["github/Scala", "scala/scala", "Scala", 221529003, 221537196, 23382799, 23390992, 32572, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199069764, 199071023, 23391007, 23392266, 28218, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 74304342, 74305192, 23392281, 23393131, 11029, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212985678, 212986050, 23393146, 23393518, 31491, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51696072, 51711910, 23393533, 23409371, 7603, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 74010443, 74012599, 23409386, 23411542, 11015, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165170276, 165181466, 23411557, 23422747, 22037, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205051613, 205052943, 23422762, 23424092, 29508, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176616889, 176652558, 23424107, 23459776, 23804, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192794688, 192799246, 23459791, 23464349, 27055, "entier"], ["github/Scala", "scala/scala", "Scala", 224221569, 224222235, 23464364, 23465030, 32961, "entier"], ["github/C++", "opencv/opencv", "C++", 112370276, 112387823, 23465045, 23482592, 15059, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206413965, 206416126, 23482607, 23484768, 29938, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238316566, 238316633, 23484783, 23484850, 36025, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238403399, 238403488, 23484865, 23484954, 36311, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229751369, 229751998, 23484969, 23485598, 33956, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238316648, 238316679, 23485613, 23485644, 36026, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238426059, 238426084, 23485659, 23485684, 36540, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238311276, 238311403, 23485699, 23485826, 36001, "entier"], ["github/PHP", "symfony/symfony", "PHP", 198046686, 198047217, 23485841, 23486372, 28113, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235399320, 235400864, 23486387, 23487931, 35397, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85585937, 85587705, 23487946, 23489714, 11969, "entier"], ["github/C", "curl/curl", "C", 92941696, 93083959, 23489729, 23631992, 12997, "entier"], ["github/Python", "django/django", "Python", 4671326, 4673880, 23632007, 23634561, 809, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238427576, 238427622, 23634576, 23634622, 36571, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231587526, 231588293, 23634637, 23635404, 34521, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238430301, 238431278, 23635419, 23636396, 36588, "entier"], ["github/Python", "pallets/flask", "Python", 334901, 335003, 23636411, 23636513, 35, "entier"], ["github/Go", "prometheus/prometheus", "Go", 83619161, 83621945, 23636528, 23639312, 11715, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136394678, 136395963, 23639327, 23640612, 17518, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43619255, 43619439, 23640627, 23640811, 5995, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211228671, 211234707, 23640826, 23646862, 31178, "entier"], ["github/Python", "django/django", "Python", 2771066, 2774869, 23646877, 23650680, 573, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51494587, 51495848, 23650695, 23651956, 7529, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228741558, 228746732, 23651971, 23657145, 33678, "entier"], ["github/Java", "google/guava", "Java", 128204226, 128208288, 23657160, 23661222, 16382, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50971666, 50972052, 23661237, 23661623, 7220, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 56989844, 57005759, 23661638, 23677553, 9096, "entier"], ["github/C++", "opencv/opencv", "C++", 111020879, 111022874, 23677568, 23679563, 14971, "entier"], ["github/Python", "django/django", "Python", 2333137, 2333710, 23679578, 23680151, 481, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 37908618, 37911975, 23680166, 23683523, 4929, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238415003, 238415070, 23683538, 23683605, 36413, "entier"], ["github/C++", "opencv/opencv", "C++", 111051182, 111052224, 23683620, 23684662, 14981, "entier"], ["github/C++", "opencv/opencv", "C++", 111010023, 111010109, 23684677, 23684763, 14966, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210401087, 210401377, 23684778, 23685068, 30963, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192600285, 192615533, 23685083, 23700331, 27030, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163784595, 163793162, 23700346, 23708913, 21802, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9848336, 9851919, 23708928, 23712511, 1571, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228218770, 228221922, 23712526, 23715678, 33590, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 123236214, 123240061, 23715693, 23719540, 15947, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142800667, 142810200, 23719555, 23729088, 18916, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42453101, 42454947, 23729103, 23730949, 5456, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52017845, 52018396, 23730964, 23731515, 7725, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238319089, 238320888, 23731530, 23733329, 36036, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56171132, 56171524, 23733344, 23733736, 8707, "entier"], ["github/Go", "prometheus/prometheus", "Go", 79151186, 79163064, 23733751, 23745629, 11468, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 23799037, 23847086, 23745644, 23793693, 3139, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205998671, 206004112, 23793708, 23799149, 29779, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231648990, 231649938, 23799164, 23800112, 34532, "entier"], ["github/C++", "nlohmann/json", "C++", 105923738, 105927338, 23800127, 23803727, 14590, "entier"], ["github/Python", "django/django", "Python", 6041645, 6049400, 23803742, 23811497, 1024, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45357140, 45364341, 23811512, 23818713, 6729, "entier"], ["github/C++", "opencv/opencv", "C++", 116472991, 116475330, 23818728, 23821067, 15292, "entier"], ["github/Scala", "scala/scala", "Scala", 224177741, 224183018, 23821082, 23826359, 32901, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158102028, 158104576, 23826374, 23828922, 20905, "entier"], ["github/C++", "nlohmann/json", "C++", 104032836, 104033491, 23828937, 23829592, 14277, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197895611, 197898156, 23829607, 23832152, 28092, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238420559, 238420577, 23832167, 23832185, 36463, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230567175, 230568430, 23832200, 23833455, 34293, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168463502, 168464881, 23833470, 23834849, 22546, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43573648, 43574081, 23834864, 23835297, 5960, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90551113, 90551215, 23835312, 23835414, 12609, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238453426, 238453494, 23835429, 23835497, 36664, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210865333, 210870316, 23835512, 23840495, 31106, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46932621, 46932945, 23840510, 23840834, 6929, "entier"], ["github/Python", "encode/httpx", "Python", 18083437, 18085187, 23840849, 23842599, 2183, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37552032, 37553887, 23842614, 23844469, 4805, "entier"], ["github/PHP", "laravel/framework", "PHP", 183264849, 183267884, 23844484, 23847519, 25222, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 62660122, 62673875, 23847534, 23861287, 9717, "entier"], ["github/PHP", "laravel/framework", "PHP", 181749463, 181749985, 23861302, 23861824, 24793, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193035035, 193035440, 23861839, 23862244, 27075, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9464955, 9468579, 23862259, 23865883, 1492, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121128897, 121144775, 23865898, 23881776, 15701, "entier"], ["github/Java", "google/guava", "Java", 129971195, 130001267, 23881791, 23911863, 16693, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200181843, 200183231, 23911878, 23913266, 28401, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89802422, 89810660, 23913281, 23921519, 12545, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231265327, 231276380, 23921534, 23932587, 34458, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169235363, 169244458, 23932602, 23941697, 22758, "entier"], ["github/Python", "django/django", "Python", 7582765, 7588729, 23941712, 23947676, 1263, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209425320, 209432245, 23947691, 23954616, 30626, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238803131, 238806297, 23954631, 23957797, 36794, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157788923, 157789207, 23957812, 23958096, 20822, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90812841, 90817244, 23958111, 23962514, 12658, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9989614, 9991634, 23962529, 23964549, 1599, "entier"], ["github/PHP", "laravel/framework", "PHP", 187925535, 187943867, 23964564, 23982896, 26195, "entier"], ["github/Scala", "playframework/playframework", "Scala", 225766194, 225768308, 23982911, 23985025, 33172, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136644292, 136645076, 23985040, 23985824, 17708, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238414463, 238414472, 23985839, 23985848, 36407, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204683657, 204684804, 23985863, 23987010, 29297, "entier"], ["github/Python", "django/django", "Python", 7557475, 7560245, 23987025, 23989795, 1258, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235029455, 235031577, 23989810, 23991932, 35296, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172759798, 172764321, 23991947, 23996470, 23298, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227080547, 227081177, 23996485, 23997115, 33432, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 27071294, 27071377, 23997130, 23997213, 3568, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19014363, 19014952, 23997228, 23997817, 2466, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202641045, 202644883, 23997832, 24001670, 28876, "entier"], ["github/Python", "django/django", "Python", 6551574, 6553866, 24001685, 24003977, 1122, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 166022835, 166032697, 24003992, 24013854, 22216, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231183243, 231185864, 24013869, 24016490, 34433, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19035987, 19036404, 24016505, 24016922, 2518, "entier"], ["github/Go", "prometheus/prometheus", "Go", 82633388, 82640507, 24016937, 24024056, 11664, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 27064914, 27065964, 24024071, 24025121, 3559, "entier"], ["github/Python", "django/django", "Python", 4325437, 4330230, 24025136, 24029929, 755, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 32341399, 32347649, 24029944, 24036194, 4186, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200278150, 200282815, 24036209, 24040874, 28442, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197385989, 197388113, 24040889, 24043013, 27974, "entier"], ["github/Scala", "sbt/sbt", "Scala", 239272811, 239283390, 24043028, 24053607, 36897, "entier"], ["github/Python", "django/django", "Python", 956392, 958166, 24053622, 24055396, 164, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168481542, 168483087, 24055411, 24056956, 22552, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194377513, 194378882, 24056971, 24058340, 27339, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178851098, 178856452, 24058355, 24063709, 24205, "entier"], ["github/Java", "square/okhttp", "Java", 148782629, 148819001, 24063724, 24100096, 19881, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 68425602, 68460138, 24100111, 24134647, 10443, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191798657, 191800687, 24134662, 24136692, 26860, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168530905, 168532473, 24136707, 24138275, 22583, "entier"], ["github/Python", "django/django", "Python", 8700399, 8703544, 24138290, 24141435, 1371, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234231939, 234233972, 24141450, 24143483, 35153, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35633922, 35637758, 24143498, 24147334, 4578, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203927845, 203931928, 24147349, 24151432, 29080, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168127414, 168129115, 24151447, 24153148, 22364, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229917940, 229920751, 24153163, 24155974, 33977, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191056829, 191061125, 24155989, 24160285, 26793, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163544563, 163544921, 24160300, 24160658, 21736, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26611208, 26613013, 24160673, 24162478, 3448, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157999568, 158000427, 24162493, 24163352, 20868, "entier"], ["github/Python", "django/django", "Python", 1895117, 1899286, 24163367, 24167536, 361, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216533238, 216533728, 24167551, 24168041, 32137, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207876438, 207877554, 24168056, 24169172, 30264, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25259570, 25261133, 24169187, 24170750, 3295, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168264467, 168265770, 24170765, 24172068, 22429, "entier"], ["github/PHP", "laravel/framework", "PHP", 185953796, 185954170, 24172083, 24172457, 25744, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205356362, 205356921, 24172472, 24173031, 29593, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177065018, 177068272, 24173046, 24176300, 23890, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235487154, 235492891, 24176315, 24182052, 35411, "entier"], ["github/Python", "django/django", "Python", 1404741, 1405380, 24182067, 24182706, 244, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28393979, 28395277, 24182721, 24184019, 3891, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9522218, 9523026, 24184034, 24184842, 1510, "entier"], ["github/PHP", "laravel/framework", "PHP", 185745073, 185749123, 24184857, 24188907, 25672, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203599574, 203601475, 24188922, 24190823, 28985, "entier"], ["github/Python", "django/django", "Python", 5410341, 5410549, 24190838, 24191046, 919, "entier"], ["github/Python", "pallets/flask", "Python", 769344, 771246, 24191061, 24192963, 98, "entier"], ["github/Scala", "sbt/sbt", "Scala", 239182102, 239182479, 24192978, 24193355, 36866, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25022975, 25026916, 24193370, 24197311, 3241, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214069822, 214070344, 24197326, 24197848, 31747, "entier"], ["github/Python", "django/django", "Python", 8527577, 8527724, 24197863, 24198010, 1352, "entier"], ["github/Python", "django/django", "Python", 5976564, 5976622, 24198025, 24198083, 1010, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200749706, 200750426, 24198098, 24198818, 28568, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41259904, 41336570, 24198833, 24275499, 5270, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215756487, 215757983, 24275514, 24277010, 31949, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161486434, 161494406, 24277025, 24284997, 21398, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210400536, 210401072, 24285012, 24285548, 30962, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207692452, 207692917, 24285563, 24286028, 30228, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180059295, 180062163, 24286043, 24288911, 24395, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226180340, 226187855, 24288926, 24296441, 33281, "entier"], ["github/Python", "django/django", "Python", 9061624, 9067746, 24296456, 24302578, 1406, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205107141, 205109814, 24302593, 24305266, 29533, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179424532, 179424856, 24305281, 24305605, 24300, "entier"], ["github/Scala", "scala/scala", "Scala", 221150552, 221151212, 24305620, 24306280, 32502, "entier"], ["github/Python", "django/django", "Python", 5502885, 5503180, 24306295, 24306590, 948, "entier"], ["github/Scala", "scala/scala", "Scala", 224212013, 224212683, 24306605, 24307275, 32947, "entier"], ["github/Scala", "scala/scala", "Scala", 224186309, 224187109, 24307290, 24308090, 32906, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179051623, 179054005, 24308105, 24310487, 24248, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199313820, 199331478, 24310502, 24328160, 28233, "entier"], ["github/Python", "django/django", "Python", 5118029, 5123825, 24328175, 24333971, 901, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235538791, 235546201, 24333986, 24341396, 35422, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205776785, 205785963, 24341411, 24350589, 29717, "entier"], ["github/Java", "apache/commons-lang", "Java", 152890199, 152930767, 24350604, 24391172, 20286, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215812304, 215814958, 24391187, 24393841, 31967, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227112973, 227113178, 24393856, 24394061, 33444, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 70862484, 70879467, 24394076, 24411059, 10555, "entier"], ["github/Scala", "scala/scala", "Scala", 219209807, 219217200, 24411074, 24418467, 32391, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195095856, 195098631, 24418482, 24421257, 27542, "entier"], ["github/PHP", "laravel/framework", "PHP", 188561998, 188562763, 24421272, 24422037, 26327, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14382880, 14398435, 24422052, 24437607, 1988, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 125882536, 126005015, 24437622, 24560101, 16115, "entier"], ["github/PHP", "laravel/framework", "PHP", 184968744, 184972745, 24560116, 24564117, 25457, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204666237, 204676513, 24564132, 24574408, 29292, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71295956, 71296904, 24574423, 24575371, 10594, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66237396, 66237581, 24575386, 24575571, 10251, "entier"], ["github/PHP", "laravel/framework", "PHP", 186456455, 186459567, 24575586, 24578698, 25867, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58693782, 58696677, 24578713, 24581608, 9263, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216414400, 216415885, 24581623, 24583108, 32094, "entier"], ["github/Java", "google/guava", "Java", 128886099, 128889951, 24583123, 24586975, 16545, "entier"], ["github/Scala", "scala/scala", "Scala", 218520317, 218536664, 24586990, 24603337, 32336, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 64019316, 64020608, 24603352, 24604644, 9935, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19989491, 20044359, 24604659, 24659527, 2792, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178734509, 178755242, 24659542, 24680275, 24191, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234184448, 234187344, 24680290, 24683186, 35139, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136247446, 136249249, 24683201, 24685004, 17421, "entier"], ["github/PHP", "laravel/framework", "PHP", 181429645, 181434996, 24685019, 24690370, 24717, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200822367, 200824256, 24690385, 24692274, 28606, "entier"], ["github/Java", "square/okhttp", "Java", 145288206, 145295750, 24692289, 24699833, 19498, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10075247, 10088842, 24699848, 24713443, 1616, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44942536, 44942699, 24713458, 24713621, 6496, "entier"], ["github/Java", "google/guava", "Java", 131884525, 131887000, 24713636, 24716111, 16873, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159832367, 159882789, 24716126, 24766548, 21171, "entier"], ["github/Scala", "playframework/playframework", "Scala", 225754932, 225758132, 24766563, 24769763, 33165, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46233714, 46237372, 24769778, 24773436, 6856, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71933366, 71951364, 24773451, 24791449, 10911, "entier"], ["github/Java", "google/guava", "Java", 128275284, 128279442, 24791464, 24795622, 16401, "entier"], ["github/Go", "prometheus/prometheus", "Go", 81207141, 81300378, 24795637, 24888874, 11580, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208861855, 208871281, 24888889, 24898315, 30494, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230681460, 230682626, 24898330, 24899496, 34321, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52825996, 52826051, 24899511, 24899566, 8038, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235146607, 235148398, 24899581, 24901372, 35334, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136297825, 136299602, 24901387, 24903164, 17450, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41722469, 41724816, 24903179, 24905526, 5304, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231190217, 231191581, 24905541, 24906905, 34440, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138263144, 138267842, 24906920, 24911618, 18135, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52428041, 52429162, 24911633, 24912754, 7907, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230586029, 230587365, 24912769, 24914105, 34304, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14376620, 14377301, 24914120, 24914801, 1986, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235180498, 235181820, 24914816, 24916138, 35344, "entier"], ["github/Java", "square/okhttp", "Java", 146236806, 146238109, 24916153, 24917456, 19634, "entier"], ["github/Python", "django/django", "Python", 3750031, 3752591, 24917471, 24920031, 670, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229669825, 229670272, 24920046, 24920493, 33900, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42959507, 42963195, 24920508, 24924196, 5670, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216448369, 216452251, 24924211, 24928093, 32106, "entier"], ["github/Java", "square/okhttp", "Java", 144651522, 144653237, 24928108, 24929823, 19325, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136241334, 136242264, 24929838, 24930768, 17415, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209263600, 209267490, 24930783, 24934673, 30599, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52156541, 52159692, 24934688, 24937839, 7787, "entier"], ["github/Python", "django/django", "Python", 1899301, 1904189, 24937854, 24942742, 362, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59333106, 59335282, 24942757, 24944933, 9375, "entier"], ["github/Scala", "scala/scala", "Scala", 222267516, 222278181, 24944948, 24955613, 32678, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41183835, 41185215, 24955628, 24957008, 5253, "entier"], ["github/C", "curl/curl", "C", 92462375, 92464621, 24957023, 24959269, 12909, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214373700, 214374932, 24959284, 24960516, 31826, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41758507, 41759067, 24960531, 24961091, 5315, "entier"], ["github/C", "curl/curl", "C", 91134382, 91134616, 24961106, 24961340, 12705, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59650615, 59656634, 24961355, 24967374, 9417, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53974194, 53977828, 24967389, 24971023, 8275, "entier"], ["github/C", "curl/curl", "C", 98214188, 98217161, 24971038, 24974011, 13405, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200619291, 200625006, 24974026, 24979741, 28542, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235746608, 235748197, 24979756, 24981345, 35477, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136790777, 136817194, 24981360, 25007777, 17772, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37635704, 37637311, 25007792, 25009399, 4825, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53095711, 53096770, 25009414, 25010473, 8134, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19670631, 19671607, 25010488, 25011464, 2762, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42590039, 42590403, 25011479, 25011843, 5503, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233940518, 233941304, 25011858, 25012644, 34980, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28338272, 28341555, 25012659, 25015942, 3874, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236999396, 237007865, 25015957, 25024426, 35651, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 12926076, 12943934, 25024441, 25042299, 1886, "entier"], ["github/PHP", "laravel/framework", "PHP", 182432731, 182486576, 25042314, 25096159, 24949, "entier"], ["github/C", "curl/curl", "C", 91563707, 91568216, 25096174, 25100683, 12824, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61906536, 61917069, 25100698, 25111231, 9665, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21930056, 21931133, 25111246, 25112323, 3032, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179208108, 179222684, 25112338, 25126914, 24262, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21853944, 21855283, 25126929, 25128268, 2984, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50994677, 51006138, 25128283, 25139744, 7247, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21037766, 21038935, 25139759, 25140928, 2862, "entier"], ["github/Java", "google/guava", "Java", 131396193, 131397477, 25140943, 25142227, 16848, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235386215, 235389238, 25142242, 25145265, 35394, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136167342, 136168087, 25145280, 25146025, 17357, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 22078766, 22081492, 25146040, 25148766, 3064, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144454201, 144463164, 25148781, 25157744, 19270, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66437833, 66441783, 25157759, 25161709, 10295, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51167915, 51168964, 25161724, 25162773, 7292, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234181567, 234182079, 25162788, 25163300, 35135, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215767174, 215770841, 25163315, 25166982, 31953, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235126341, 235134521, 25166997, 25175177, 35327, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159019495, 159022704, 25175192, 25178401, 21044, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205327974, 205345859, 25178416, 25196301, 29584, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43727253, 43729908, 25196316, 25198971, 6114, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120627111, 120632599, 25198986, 25204474, 15656, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58643621, 58645146, 25204489, 25206014, 9244, "entier"], ["github/Java", "google/guava", "Java", 134759018, 134761891, 25206029, 25208902, 17194, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11700970, 11706537, 25208917, 25214484, 1826, "entier"], ["github/C", "curl/curl", "C", 97701285, 97713368, 25214499, 25226582, 13298, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162242053, 162243733, 25226597, 25228277, 21490, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139415634, 139417843, 25228292, 25230501, 18320, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230878070, 230878802, 25230516, 25231248, 34387, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63362928, 63366270, 25231263, 25234605, 9824, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28263886, 28277068, 25234620, 25247802, 3860, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141917345, 141918731, 25247817, 25249203, 18649, "entier"], ["github/Scala", "scala/scala", "Scala", 221639712, 221642528, 25249218, 25252034, 32591, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143824355, 143825854, 25252049, 25253548, 19126, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158086589, 158089592, 25253563, 25256566, 20902, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45296856, 45307491, 25256581, 25267216, 6723, "entier"], ["github/Java", "square/okhttp", "Java", 148890747, 148892653, 25267231, 25269137, 19904, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177283036, 177283847, 25269152, 25269963, 23919, "entier"], ["github/C++", "nlohmann/json", "C++", 109122449, 109133159, 25269978, 25280688, 14704, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227069880, 227070827, 25280703, 25281650, 33428, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238305220, 238305269, 25281665, 25281714, 35964, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136207837, 136209075, 25281729, 25282967, 17391, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234067611, 234068311, 25282982, 25283682, 35059, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173858872, 173860231, 25283697, 25285056, 23448, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168649075, 168652075, 25285071, 25288071, 22649, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9372935, 9382354, 25288086, 25297505, 1476, "entier"], ["github/C++", "nlohmann/json", "C++", 103938074, 103939211, 25297520, 25298657, 14173, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229489426, 229499527, 25298672, 25308773, 33825, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168548111, 168550248, 25308788, 25310925, 22594, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204716142, 204718504, 25310940, 25313302, 29313, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59066470, 59082151, 25313317, 25328998, 9340, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121271050, 121275281, 25329013, 25333244, 15714, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 201510032, 201510701, 25333259, 25333928, 28701, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160827200, 160829464, 25333943, 25336207, 21261, "entier"], ["github/Java", "apache/commons-lang", "Java", 149731977, 149754359, 25336222, 25358604, 20018, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 215595038, 215596477, 25358619, 25360058, 31921, "entier"], ["github/C++", "opencv/opencv", "C++", 116524561, 116527168, 25360073, 25362680, 15315, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234898045, 234898658, 25362695, 25363308, 35276, "entier"], ["github/Python", "psf/requests", "Python", 323616, 329163, 25363323, 25368870, 31, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180575500, 180583700, 25368885, 25377085, 24516, "entier"], ["github/C++", "opencv/opencv", "C++", 114173176, 114175542, 25377100, 25379466, 15168, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169125471, 169127715, 25379481, 25381725, 22738, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168288777, 168290122, 25381740, 25383085, 22444, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210368168, 210376661, 25383100, 25391593, 30950, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164206756, 164207331, 25391608, 25392183, 21869, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71361143, 71361971, 25392198, 25393026, 10653, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234133573, 234134522, 25393041, 25393990, 35102, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60288290, 60288404, 25394005, 25394119, 9524, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71269994, 71270336, 25394134, 25394476, 10566, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168546424, 168548096, 25394491, 25396163, 22593, "entier"], ["github/Java", "apache/commons-lang", "Java", 155365422, 155366922, 25396178, 25397678, 20518, "entier"], ["github/Python", "django/django", "Python", 3560050, 3565767, 25397693, 25403410, 647, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 125682417, 125698004, 25403425, 25419012, 16105, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161905900, 161908701, 25419027, 25421828, 21435, "entier"], ["github/PHP", "laravel/framework", "PHP", 181725363, 181743138, 25421843, 25439618, 24779, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142363370, 142370294, 25439633, 25446557, 18830, "entier"], ["github/C", "curl/curl", "C", 94210175, 94230817, 25446572, 25467214, 13064, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 214458685, 214460427, 25467229, 25468971, 31845, "entier"], ["github/Python", "django/django", "Python", 2717891, 2718424, 25468986, 25469519, 564, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235908283, 235932200, 25469534, 25493451, 35500, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160990193, 160990821, 25493466, 25494094, 21325, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 58254481, 58267035, 25494109, 25506663, 9164, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171823663, 171827294, 25506678, 25510309, 23059, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165981287, 165985808, 25510324, 25514845, 22203, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10312859, 10321301, 25514860, 25523302, 1650, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200414727, 200422052, 25523317, 25530642, 28480, "entier"], ["github/C++", "google/leveldb", "C++", 110737313, 110738906, 25530657, 25532250, 14870, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141252547, 141263886, 25532265, 25543604, 18525, "entier"], ["github/C++", "nlohmann/json", "C++", 104120884, 104121152, 25543619, 25543887, 14387, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234029473, 234030038, 25543902, 25544467, 35032, "entier"], ["github/C++", "opencv/opencv", "C++", 116787855, 116793241, 25544482, 25549868, 15387, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158941569, 158944770, 25549883, 25553084, 21040, "entier"], ["github/PHP", "laravel/framework", "PHP", 185861176, 185864410, 25553099, 25556333, 25708, "entier"], ["github/C++", "nlohmann/json", "C++", 103996887, 103997352, 25556348, 25556813, 14238, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56080603, 56136149, 25556828, 25612374, 8692, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126609765, 126611222, 25612389, 25613846, 16159, "entier"], ["github/PHP", "laravel/framework", "PHP", 185114767, 185114849, 25613861, 25613943, 25492, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238324033, 238324842, 25613958, 25614767, 36061, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212171987, 212176084, 25614782, 25618879, 31393, "entier"], ["github/Java", "google/guava", "Java", 135933658, 135943699, 25618894, 25628935, 17322, "entier"], ["github/PHP", "laravel/framework", "PHP", 182402319, 182403939, 25628950, 25630570, 24915, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231985917, 231986587, 25630585, 25631255, 34588, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163961155, 163963656, 25631270, 25633771, 21841, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230435766, 230436135, 25633786, 25634155, 34227, "entier"], ["github/Scala", "scala/scala", "Scala", 224620884, 224622504, 25634170, 25635790, 33057, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238420062, 238420092, 25635805, 25635835, 36454, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216466011, 216468929, 25635850, 25638768, 32112, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200402391, 200403045, 25638783, 25639437, 28472, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21212743, 21273769, 25639452, 25700478, 2890, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168198035, 168199502, 25700493, 25701960, 22411, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233888680, 233889193, 25701975, 25702488, 34945, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157246027, 157246175, 25702503, 25702651, 20685, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 62589122, 62604844, 25702666, 25718388, 9714, "entier"], ["github/Java", "apache/commons-lang", "Java", 154190948, 154194541, 25718403, 25721996, 20361, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204888746, 204891820, 25722011, 25725085, 29441, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228936064, 228944773, 25725100, 25733809, 33719, "entier"], ["github/Java", "google/guava", "Java", 128707088, 128710583, 25733824, 25737319, 16501, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204034673, 204035849, 25737334, 25738510, 29097, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126236191, 126257775, 25738525, 25760109, 16133, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192370479, 192384514, 25760124, 25774159, 26969, "entier"], ["github/Java", "square/okhttp", "Java", 144763896, 144765564, 25774174, 25775842, 19369, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234017987, 234018228, 25775857, 25776098, 35022, "entier"], ["github/Java", "google/guava", "Java", 135515337, 135517731, 25776113, 25778507, 17283, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235039214, 235040423, 25778522, 25779731, 35302, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176865033, 176883811, 25779746, 25798524, 23825, "entier"], ["github/Java", "square/okhttp", "Java", 145836367, 145840762, 25798539, 25802934, 19590, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71752596, 71752911, 25802949, 25803264, 10903, "entier"], ["github/C", "libuv/libuv", "C", 100165593, 100180057, 25803279, 25817743, 13770, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 167000019, 167015009, 25817758, 25832748, 22277, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136190026, 136191599, 25832763, 25834336, 17375, "entier"], ["github/Go", "prometheus/prometheus", "Go", 76360039, 76415104, 25834351, 25889416, 11231, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144506577, 144508713, 25889431, 25891567, 19283, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194464741, 194465169, 25891582, 25892010, 27373, "entier"], ["github/PHP", "laravel/framework", "PHP", 187008884, 187009529, 25892025, 25892670, 26028, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198609359, 198610780, 25892685, 25894106, 28189, "entier"], ["github/C++", "opencv/opencv", "C++", 116694415, 116696164, 25894121, 25895870, 15344, "entier"], ["github/Java", "square/okhttp", "Java", 147746835, 147752486, 25895885, 25901536, 19794, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210330363, 210347888, 25901551, 25919076, 30939, "entier"], ["github/PHP", "laravel/framework", "PHP", 185428040, 185434295, 25919091, 25925346, 25587, "entier"], ["github/Java", "google/guava", "Java", 132954594, 132959867, 25925361, 25930634, 17031, "entier"], ["github/Scala", "scala/scala", "Scala", 217917877, 217943956, 25930649, 25956728, 32307, "entier"], ["github/C++", "nlohmann/json", "C++", 108418457, 108432762, 25956743, 25971048, 14684, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140195570, 140197071, 25971063, 25972564, 18454, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163413781, 163415708, 25972579, 25974506, 21701, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69527473, 69550058, 25974521, 25997106, 10525, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193329591, 193330129, 25997121, 25997659, 27195, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136862885, 136864158, 25997674, 25998947, 17789, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43571194, 43571424, 25998962, 25999192, 5956, "entier"], ["github/Python", "django/django", "Python", 5323324, 5380452, 25999207, 26056335, 910, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142895695, 142901540, 26056350, 26062195, 18932, "entier"], ["github/C", "curl/curl", "C", 91904567, 91911295, 26062210, 26068938, 12861, "entier"], ["github/PHP", "laravel/framework", "PHP", 188976416, 188984928, 26068953, 26077465, 26400, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138707989, 138709815, 26077480, 26079306, 18207, "entier"], ["github/C++", "opencv/opencv", "C++", 111530876, 111534706, 26079321, 26083151, 15003, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172258244, 172260291, 26083166, 26085213, 23222, "entier"], ["github/Java", "google/guava", "Java", 129681291, 129684858, 26085228, 26088795, 16651, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 167361477, 167371466, 26088810, 26098799, 22303, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121312722, 121314752, 26098814, 26100844, 15716, "entier"], ["github/Java", "google/guava", "Java", 130888237, 130891335, 26100859, 26103957, 16787, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171595103, 171595959, 26103972, 26104828, 22969, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52408505, 52428026, 26104843, 26124364, 7906, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33775893, 33776926, 26124379, 26125412, 4344, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238426809, 238426841, 26125427, 26125459, 36556, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230384637, 230385237, 26125474, 26126074, 34209, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238335518, 238335580, 26126089, 26126151, 36086, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238405291, 238405462, 26126166, 26126337, 36322, "entier"], ["github/C++", "opencv/opencv", "C++", 111042507, 111045951, 26126352, 26129796, 14979, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143656288, 143658932, 26129811, 26132455, 19081, "entier"], ["github/Scala", "playframework/playframework", "Scala", 233172488, 233172824, 26132470, 26132806, 34753, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 29229871, 29231356, 26132821, 26134306, 3971, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238449253, 238449843, 26134321, 26134911, 36655, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180072308, 180073841, 26134926, 26136459, 24397, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192018458, 192023964, 26136474, 26141980, 26917, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63172829, 63173975, 26141995, 26143141, 9786, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 125363972, 125365198, 26143156, 26144382, 16077, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207952553, 207961679, 26144397, 26153523, 30298, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71582958, 71584354, 26153538, 26154934, 10842, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234038188, 234041449, 26154949, 26158210, 35038, "entier"], ["github/Java", "google/guava", "Java", 129311771, 129316704, 26158225, 26163158, 16610, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165708741, 165711240, 26163173, 26165672, 22127, "entier"], ["github/Scala", "scala/scala", "Scala", 225362016, 225368897, 26165687, 26172568, 33140, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197867698, 197868479, 26172583, 26173364, 28076, "entier"], ["github/C++", "opencv/opencv", "C++", 115413649, 115419073, 26173379, 26178803, 15226, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141980388, 141981504, 26178818, 26179934, 18693, "entier"], ["github/PHP", "laravel/framework", "PHP", 183436030, 183437031, 26179949, 26180950, 25246, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61575153, 61578835, 26180965, 26184647, 9619, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21155088, 21163016, 26184662, 26192590, 2881, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136892440, 136897121, 26192605, 26197286, 17809, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162458278, 162460643, 26197301, 26199666, 21527, "entier"], ["github/C++", "opencv/opencv", "C++", 116778379, 116780281, 26199681, 26201583, 15380, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 73893091, 73894404, 26201598, 26202911, 11002, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200031983, 200032525, 26202926, 26203468, 28333, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 65453143, 65453986, 26203483, 26204326, 10177, "entier"], ["github/Java", "apache/commons-lang", "Java", 152886020, 152888805, 26204341, 26207126, 20284, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52733269, 52734801, 26207141, 26208673, 7981, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208081891, 208082285, 26208688, 26209082, 30319, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159570600, 159571954, 26209097, 26210451, 21154, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71543537, 71544328, 26210466, 26211257, 10773, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58514192, 58514266, 26211272, 26211346, 9208, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193968761, 193978221, 26211361, 26220821, 27316, "entier"], ["github/Java", "square/okhttp", "Java", 146210612, 146212171, 26220836, 26222395, 19628, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 206018523, 206020587, 26222410, 26224474, 29787, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 64835884, 64837800, 26224489, 26226405, 9992, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168526151, 168527790, 26226420, 26228059, 22580, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 156558150, 156560253, 26228074, 26230177, 20607, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53795368, 53806009, 26230192, 26240833, 8257, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88100887, 88106791, 26240848, 26246752, 12260, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140007710, 140020601, 26246767, 26259658, 18411, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157260656, 157261165, 26259673, 26260182, 20698, "entier"], ["github/C++", "opencv/opencv", "C++", 112436650, 112456286, 26260197, 26279833, 15067, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213861457, 213868246, 26279848, 26286637, 31697, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24624914, 24638633, 26286652, 26300371, 3214, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 66738792, 66748927, 26300386, 26310521, 10334, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 166075050, 166077847, 26310536, 26313333, 22230, "entier"], ["github/PHP", "laravel/framework", "PHP", 181378704, 181384332, 26313348, 26318976, 24689, "entier"], ["github/Java", "apache/commons-lang", "Java", 150729613, 150731053, 26318991, 26320431, 20118, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231276395, 231305944, 26320446, 26349995, 34459, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43434456, 43436788, 26350010, 26352342, 5796, "entier"], ["github/PHP", "laravel/framework", "PHP", 186654677, 186655209, 26352357, 26352889, 25961, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89537895, 89542827, 26352904, 26357836, 12493, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142133674, 142136403, 26357851, 26360580, 18774, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157635727, 157639979, 26360595, 26364847, 20774, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203602667, 203604017, 26364862, 26366212, 28987, "entier"], ["github/PHP", "laravel/framework", "PHP", 187724456, 187726506, 26366227, 26368277, 26181, "entier"], ["github/Java", "apache/commons-lang", "Java", 150502327, 150503880, 26368292, 26369845, 20076, "entier"], ["github/Java", "square/okhttp", "Java", 145519173, 145519768, 26369860, 26370455, 19537, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27234746, 27234845, 26370470, 26370569, 3599, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204680521, 204682098, 26370584, 26372161, 29295, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9395211, 9400772, 26372176, 26377737, 1480, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 65983990, 65986825, 26377752, 26380587, 10218, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136342062, 136343102, 26380602, 26381642, 17479, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175102383, 175126392, 26381657, 26405666, 23645, "entier"], ["github/PHP", "laravel/framework", "PHP", 184086351, 184090077, 26405681, 26409407, 25334, "entier"], ["github/Go", "prometheus/prometheus", "Go", 83689370, 83691665, 26409422, 26411717, 11722, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143587046, 143591912, 26411732, 26416598, 19063, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19072468, 19077025, 26416613, 26421170, 2596, "entier"], ["github/C++", "opencv/opencv", "C++", 112636812, 112643224, 26421185, 26427597, 15094, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205817753, 205821572, 26427612, 26431431, 29728, "entier"], ["github/Java", "square/okhttp", "Java", 145840777, 145841713, 26431446, 26432382, 19591, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162762822, 162768647, 26432397, 26438222, 21614, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191103705, 191105592, 26438237, 26440124, 26805, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19027201, 19027318, 26440139, 26440256, 2510, "entier"], ["github/Java", "square/okhttp", "Java", 148989197, 148991168, 26440271, 26442242, 19946, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 30282819, 30284319, 26442257, 26443757, 4068, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85002371, 85007881, 26443772, 26449282, 11852, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208146148, 208146562, 26449297, 26449711, 30349, "entier"], ["github/PHP", "laravel/framework", "PHP", 183315172, 183317834, 26449726, 26452388, 25231, "entier"], ["github/Java", "google/guava", "Java", 129753130, 129756658, 26452403, 26455931, 16668, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35377343, 35378521, 26455946, 26457124, 4528, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205176414, 205177856, 26457139, 26458581, 29551, "entier"], ["github/PHP", "laravel/framework", "PHP", 185316721, 185317416, 26458596, 26459291, 25554, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143030915, 143032371, 26459306, 26460762, 18981, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207475114, 207475721, 26460777, 26461384, 30150, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168668303, 168669704, 26461399, 26462800, 22660, "entier"], ["github/PHP", "laravel/framework", "PHP", 182545118, 182545365, 26462815, 26463062, 25018, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27645595, 27649213, 26463077, 26466695, 3724, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200033606, 200034064, 26466710, 26467168, 28336, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211691092, 211691961, 26467183, 26468052, 31316, "entier"], ["github/C", "curl/curl", "C", 92318474, 92367893, 26468067, 26517486, 12892, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194825506, 194830151, 26517501, 26522146, 27482, "entier"], ["github/Java", "square/okhttp", "Java", 147082542, 147091148, 26522161, 26530767, 19755, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213383720, 213386728, 26530782, 26533790, 31577, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160664473, 160670883, 26533805, 26540215, 21203, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 73986812, 74010428, 26540230, 26563846, 11014, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191581272, 191582599, 26563861, 26565188, 26833, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136331725, 136332638, 26565203, 26566116, 17472, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26701467, 26709268, 26566131, 26573932, 3464, "entier"], ["github/PHP", "laravel/framework", "PHP", 186467426, 186467731, 26573947, 26574252, 25877, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233492272, 233493726, 26574267, 26575721, 34805, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190388886, 190391852, 26575736, 26578702, 26621, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85567890, 85581391, 26578717, 26592218, 11964, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207659389, 207663576, 26592233, 26596420, 30215, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54847112, 54888503, 26596435, 26637826, 8446, "entier"], ["github/PHP", "laravel/framework", "PHP", 185897307, 185897576, 26637841, 26638110, 25716, "entier"], ["github/C++", "opencv/opencv", "C++", 113063099, 113101546, 26638125, 26676572, 15125, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 32306190, 32308409, 26676587, 26678806, 4184, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161873911, 161878427, 26678821, 26683337, 21429, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194008324, 194012415, 26683352, 26687443, 27322, "entier"], ["github/Python", "django/django", "Python", 4835822, 4871182, 26687458, 26722818, 834, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34907029, 34909605, 26722833, 26725409, 4476, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207110240, 207115080, 26725424, 26730264, 30087, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190537921, 190539285, 26730279, 26731643, 26653, "entier"], ["github/Java", "google/guava", "Java", 133271637, 133298865, 26731658, 26758886, 17073, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168446676, 168449253, 26758901, 26761478, 22536, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28693845, 28695651, 26761493, 26763299, 3929, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236717709, 236752677, 26763314, 26798282, 35613, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88067000, 88068239, 26798297, 26799536, 12253, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19011348, 19011553, 26799551, 26799756, 2459, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18990785, 18990901, 26799771, 26799887, 2398, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71536062, 71537086, 26799902, 26800926, 10765, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202734582, 202734984, 26800941, 26801343, 28883, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180132909, 180136225, 26801358, 26804674, 24415, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168120717, 168121990, 26804689, 26805962, 22359, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213739061, 213739655, 26805977, 26806571, 31669, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211545090, 211546181, 26806586, 26807677, 31279, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159029892, 159030779, 26807692, 26808579, 21049, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33596507, 33603322, 26808594, 26815409, 4305, "entier"], ["github/PHP", "symfony/symfony", "PHP", 198101178, 198113710, 26815424, 26827956, 28124, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157114086, 157116242, 26827971, 26830127, 20653, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168707374, 168708869, 26830142, 26831637, 22682, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144379392, 144380931, 26831652, 26833191, 19251, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 215234602, 215259187, 26833206, 26857791, 31904, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207101253, 207110225, 26857806, 26866778, 30086, "entier"], ["github/Java", "google/guava", "Java", 132115902, 132120057, 26866793, 26870948, 16901, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165541734, 165546054, 26870963, 26875283, 22066, "entier"], ["github/Go", "prometheus/prometheus", "Go", 81070451, 81088914, 26875298, 26893761, 11573, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143571071, 143573192, 26893776, 26895897, 19056, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175816423, 175824580, 26895912, 26904069, 23739, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 36478319, 36488318, 26904084, 26914083, 4693, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 65549969, 65573235, 26914098, 26937364, 10189, "entier"], ["github/PHP", "laravel/framework", "PHP", 186503649, 186508414, 26937379, 26942144, 25889, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138308302, 138314220, 26942159, 26948077, 18138, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163489788, 163491998, 26948092, 26950302, 21715, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43964530, 43971333, 26950317, 26957120, 6190, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233965570, 233967127, 26957135, 26958692, 34989, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205214032, 205215090, 26958707, 26959765, 29566, "entier"], ["github/Scala", "playframework/playframework", "Scala", 233181277, 233182239, 26959780, 26960742, 34763, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193072185, 193072849, 26960757, 26961421, 27110, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158720007, 158721018, 26961436, 26962447, 20998, "entier"], ["github/PHP", "laravel/framework", "PHP", 188549995, 188550559, 26962462, 26963026, 26317, "entier"], ["github/PHP", "laravel/framework", "PHP", 182516871, 182517358, 26963041, 26963528, 24979, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230538617, 230541711, 26963543, 26966637, 34282, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210182108, 210186601, 26966652, 26971145, 30887, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55020475, 55023378, 26971160, 26974063, 8469, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229360312, 229363972, 26974078, 26977738, 33802, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196212358, 196218574, 26977753, 26983969, 27733, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45168825, 45169214, 26983984, 26984373, 6659, "entier"], ["github/Java", "apache/commons-lang", "Java", 152478461, 152494204, 26984388, 27000131, 20266, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158305007, 158311816, 27000146, 27006955, 20946, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237558636, 237559555, 27006970, 27007889, 35707, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 124577223, 124611209, 27007904, 27041890, 16027, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45910962, 45915195, 27041905, 27046138, 6795, "entier"], ["github/PHP", "laravel/framework", "PHP", 186469335, 186469499, 27046153, 27046317, 25883, "entier"], ["github/PHP", "laravel/framework", "PHP", 184606258, 184606614, 27046332, 27046688, 25389, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197159526, 197160042, 27046703, 27047219, 27932, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206366360, 206370140, 27047234, 27051014, 29923, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65408012, 65408217, 27051029, 27051234, 10154, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65397347, 65397470, 27051249, 27051372, 10089, "entier"], ["github/C", "curl/curl", "C", 97726409, 97731080, 27051387, 27056058, 13302, "entier"], ["github/Go", "prometheus/prometheus", "Go", 77357781, 77364169, 27056073, 27062461, 11305, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44972051, 44974479, 27062476, 27064904, 6527, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194378897, 194381589, 27064919, 27067611, 27340, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63601674, 63604179, 27067626, 27070131, 9873, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160807965, 160808888, 27070146, 27071069, 21254, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178606027, 178613137, 27071084, 27078194, 24187, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168553965, 168556004, 27078209, 27080248, 22597, "entier"], ["github/PHP", "laravel/framework", "PHP", 186526847, 186528464, 27080263, 27081880, 25904, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210409310, 210411886, 27081895, 27084471, 30968, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38804218, 38808665, 27084486, 27088933, 5017, "entier"], ["github/Go", "gohugoio/hugo", "Go", 87447146, 87449801, 27088948, 27091603, 12180, "entier"], ["github/PHP", "laravel/framework", "PHP", 189488624, 189492147, 27091618, 27095141, 26474, "entier"], ["github/C", "libuv/libuv", "C", 101583757, 101587042, 27095156, 27098441, 13912, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141111508, 141126190, 27098456, 27113138, 18511, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53763284, 53767241, 27113153, 27117110, 8248, "entier"], ["github/PHP", "laravel/framework", "PHP", 182353416, 182354799, 27117125, 27118508, 24895, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174884327, 174884480, 27118523, 27118676, 23601, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204632687, 204637398, 27118691, 27123402, 29283, "entier"], ["github/Scala", "scala/scala", "Scala", 224874124, 224897730, 27123417, 27147023, 33109, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161817899, 161824743, 27147038, 27153882, 21423, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171939404, 171939532, 27153897, 27154025, 23130, "entier"], ["github/PHP", "laravel/framework", "PHP", 188545365, 188546466, 27154040, 27155141, 26311, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56253746, 56254214, 27155156, 27155624, 8791, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51487237, 51487379, 27155639, 27155781, 7525, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192417508, 192418590, 27155796, 27156878, 26979, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52794568, 52794844, 27156893, 27157169, 8013, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43037237, 43037852, 27157184, 27157799, 5700, "entier"], ["github/Java", "square/okhttp", "Java", 144626084, 144628282, 27157814, 27160012, 19315, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234146170, 234147353, 27160027, 27161210, 35113, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53806024, 53807660, 27161225, 27162861, 8258, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193492601, 193494739, 27162876, 27165014, 27239, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39545183, 39547144, 27165029, 27166990, 5120, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 15518418, 15567221, 27167005, 27215808, 2062, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209570067, 209575093, 27215823, 27220849, 30662, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 166163555, 166166688, 27220864, 27223997, 22247, "entier"], ["github/Java", "apache/commons-lang", "Java", 152508187, 152515858, 27224012, 27231683, 20270, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56003838, 56005083, 27231698, 27232943, 8654, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 124491313, 124503203, 27232958, 27244848, 16020, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174542467, 174550497, 27244863, 27252893, 23502, "entier"], ["github/C", "curl/curl", "C", 95471966, 95484547, 27252908, 27265489, 13153, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205131070, 205131528, 27265504, 27265962, 29538, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139803461, 139805859, 27265977, 27268375, 18381, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52785532, 52790685, 27268390, 27273543, 8003, "entier"], ["github/Go", "gohugoio/hugo", "Go", 86130026, 86150076, 27273558, 27293608, 12058, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230101468, 230102330, 27293623, 27294485, 34003, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208362738, 208364416, 27294500, 27296178, 30390, "entier"], ["github/Java", "google/guava", "Java", 129574135, 129577632, 27296193, 27299690, 16622, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230457146, 230458632, 27299705, 27301191, 34236, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169303345, 169309830, 27301206, 27307691, 22761, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210826776, 210827508, 27307706, 27308438, 31095, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44884144, 44884766, 27308453, 27309075, 6440, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56499054, 56500272, 27309090, 27310308, 9064, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44295463, 44296769, 27310323, 27311629, 6262, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172751398, 172752959, 27311644, 27313205, 23295, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168725300, 168726582, 27313220, 27314502, 22692, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203260880, 203267384, 27314517, 27321021, 28924, "entier"], ["github/Java", "apache/commons-lang", "Java", 150401877, 150416512, 27321036, 27335671, 20067, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162839815, 162840734, 27335686, 27336605, 21624, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44491215, 44498326, 27336620, 27343731, 6326, "entier"], ["github/C", "curl/curl", "C", 98939732, 98942085, 27343746, 27346099, 13605, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 179946463, 179949254, 27346114, 27348905, 24379, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162142387, 162145826, 27348920, 27352359, 21462, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203212626, 203213081, 27352374, 27352829, 28917, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51739696, 51740529, 27352844, 27353677, 7617, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138239899, 138240844, 27353692, 27354637, 18125, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 32045483, 32122006, 27354652, 27431175, 4176, "entier"], ["github/C", "curl/curl", "C", 98223753, 98225729, 27431190, 27433166, 13409, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 62170468, 62229860, 27433181, 27492573, 9698, "entier"], ["github/C++", "nlohmann/json", "C++", 108489582, 108520753, 27492588, 27523759, 14686, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139012919, 139016728, 27523774, 27527583, 18254, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163808243, 163810315, 27527598, 27529670, 21805, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172669938, 172671062, 27529685, 27530809, 23285, "entier"], ["github/Go", "gohugoio/hugo", "Go", 87230374, 87236720, 27530824, 27537170, 12162, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203315341, 203320339, 27537185, 27542183, 28929, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42948277, 42953969, 27542198, 27547890, 5664, "entier"], ["github/Scala", "scala/scala", "Scala", 223249112, 223279605, 27547905, 27578398, 32748, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168710361, 168711792, 27578413, 27579844, 22684, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175065754, 175067155, 27579859, 27581260, 23643, "entier"], ["github/PHP", "laravel/framework", "PHP", 189658731, 189706011, 27581275, 27628555, 26491, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173616509, 173617263, 27628570, 27629324, 23433, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203396958, 203397759, 27629339, 27630140, 28950, "entier"], ["github/Java", "google/guava", "Java", 128048576, 128060848, 27630155, 27642427, 16350, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161057212, 161061269, 27642442, 27646499, 21342, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180205618, 180206278, 27646514, 27647174, 24439, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209824867, 209827536, 27647189, 27649858, 30736, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176883826, 176884325, 27649873, 27650372, 23826, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38205421, 38215980, 27650387, 27660946, 4968, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211777032, 211777892, 27660961, 27661821, 31336, "entier"], ["github/Java", "google/guava", "Java", 135183738, 135185887, 27661836, 27663985, 17235, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88947889, 88959119, 27664000, 27675230, 12398, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214304459, 214309058, 27675245, 27679844, 31811, "entier"], ["github/C++", "opencv/opencv", "C++", 116642091, 116644444, 27679859, 27682212, 15322, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51299591, 51299864, 27682227, 27682500, 7385, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45968767, 45969735, 27682515, 27683483, 6816, "entier"], ["github/C", "curl/curl", "C", 92587487, 92607935, 27683498, 27703946, 12935, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47038044, 47042487, 27703961, 27708404, 6945, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228006787, 228011655, 27708419, 27713287, 33556, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51959495, 51959739, 27713302, 27713546, 7690, "entier"], ["github/Java", "google/guava", "Java", 133875790, 133902165, 27713561, 27739936, 17132, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203382509, 203388974, 27739951, 27746416, 28941, "entier"], ["github/Scala", "scala/scala", "Scala", 219238084, 219239089, 27746431, 27747436, 32396, "entier"], ["github/Python", "django/django", "Python", 1251729, 1279708, 27747451, 27775430, 221, "entier"], ["github/Scala", "scala/scala", "Scala", 217473933, 217475136, 27775445, 27776648, 32238, "entier"], ["github/Scala", "scala/scala", "Scala", 221703448, 221703950, 27776663, 27777165, 32630, "entier"], ["github/Scala", "sbt/sbt", "Scala", 239182494, 239183177, 27777180, 27777863, 36867, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238330905, 238330979, 27777878, 27777952, 36077, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47139049, 47146587, 27777967, 27785505, 6956, "entier"], ["github/Scala", "scala/scala", "Scala", 224497564, 224498353, 27785520, 27786309, 33035, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231392066, 231395301, 27786324, 27789559, 34483, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54452649, 54452943, 27789574, 27789868, 8357, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168837126, 168867923, 27789883, 27820680, 22710, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193044018, 193045561, 27820695, 27822238, 27088, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138552738, 138556648, 27822253, 27826163, 18180, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214073549, 214084653, 27826178, 27837282, 31750, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235991922, 236004229, 27837297, 27849604, 35514, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39866025, 39878874, 27849619, 27862468, 5162, "entier"], ["github/Java", "google/guava", "Java", 128423726, 128434412, 27862483, 27873169, 16426, "entier"], ["github/C", "curl/curl", "C", 91652984, 91658192, 27873184, 27878392, 12844, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61032819, 61041522, 27878407, 27887110, 9562, "entier"], ["github/Python", "django/django", "Python", 6085886, 6086113, 27887125, 27887352, 1041, "entier"], ["github/Python", "django/django", "Python", 2343189, 2345468, 27887367, 27889646, 489, "entier"], ["github/Java", "apache/commons-lang", "Java", 154445541, 154447034, 27889661, 27891154, 20395, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25550044, 25551584, 27891169, 27892709, 3347, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43565163, 43565600, 27892724, 27893161, 5941, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19001200, 19001224, 27893176, 27893200, 2435, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43554973, 43555193, 27893215, 27893435, 5923, "entier"], ["github/Scala", "scala/scala", "Scala", 223683840, 223687992, 27893450, 27897602, 32800, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203343645, 203344970, 27897617, 27898942, 28934, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56497807, 56498496, 27898957, 27899646, 9062, "entier"], ["github/Java", "square/okhttp", "Java", 147581010, 147586824, 27899661, 27905475, 19785, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18487402, 18490381, 27905490, 27908469, 2288, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 124699052, 124767989, 27908484, 27977421, 16030, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 16391432, 16397813, 27977436, 27983817, 2092, "entier"], ["github/Go", "prometheus/prometheus", "Go", 76864429, 76905908, 27983832, 28025311, 11258, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44511780, 44515854, 28025326, 28029400, 6332, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210895870, 210898802, 28029415, 28032347, 31114, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230709311, 230711759, 28032362, 28034810, 34325, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33586459, 33587551, 28034825, 28035917, 4300, "entier"], ["github/C", "curl/curl", "C", 91465862, 91472943, 28035932, 28043013, 12790, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238426254, 238426293, 28043028, 28043067, 36545, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238001154, 238001895, 28043082, 28043823, 35789, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43667067, 43667849, 28043838, 28044620, 6043, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226337280, 226339266, 28044635, 28046621, 33297, "entier"], ["github/Python", "django/django", "Python", 4834062, 4835807, 28046636, 28048381, 833, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230501610, 230502099, 28048396, 28048885, 34270, "entier"], ["github/Scala", "scala/scala", "Scala", 223248507, 223249097, 28048900, 28049490, 32747, "entier"], ["github/Python", "pallets/flask", "Python", 776939, 777419, 28049505, 28049985, 101, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 62976049, 62991604, 28050000, 28065555, 9748, "entier"], ["github/Java", "apache/commons-lang", "Java", 152725059, 152739382, 28065570, 28079893, 20274, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163546922, 163548129, 28079908, 28081115, 21738, "entier"], ["github/Scala", "scala/scala", "Scala", 217467927, 217469775, 28081130, 28082978, 32235, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238416693, 238416715, 28082993, 28083015, 36428, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203247175, 203255825, 28083030, 28091680, 28922, "entier"], ["github/Scala", "scala/scala", "Scala", 224863469, 224866265, 28091695, 28094491, 33106, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9915439, 9923291, 28094506, 28102358, 1585, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26780594, 26796447, 28102373, 28118226, 3480, "entier"], ["github/Java", "square/okhttp", "Java", 146928730, 146930398, 28118241, 28119909, 19749, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237893988, 237899002, 28119924, 28124938, 35756, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136287879, 136289453, 28124953, 28126527, 17444, "entier"], ["github/C", "curl/curl", "C", 98601291, 98607950, 28126542, 28133201, 13515, "entier"], ["github/Java", "square/okhttp", "Java", 145295765, 145298602, 28133216, 28136053, 19499, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216738155, 216745581, 28136068, 28143494, 32165, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71578537, 71578843, 28143509, 28143815, 10835, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55425521, 55447668, 28143830, 28165977, 8505, "entier"], ["github/Python", "django/django", "Python", 2994802, 2995921, 28165992, 28167111, 588, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209519803, 209521057, 28167126, 28168380, 30650, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229184267, 229192033, 28168395, 28176161, 33758, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19056090, 19056455, 28176176, 28176541, 2561, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193700363, 193761386, 28176556, 28237579, 27271, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19550603, 19552469, 28237594, 28239460, 2745, "entier"], ["github/C", "curl/curl", "C", 98661627, 98665102, 28239475, 28242950, 13535, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207162016, 207169264, 28242965, 28250213, 30104, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230381830, 230382337, 28250228, 28250735, 34204, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228614322, 228617288, 28250750, 28253716, 33648, "entier"], ["github/C", "madler/zlib", "C", 102257339, 102258903, 28253731, 28255295, 14016, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63472393, 63491629, 28255310, 28274546, 9850, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229380655, 229381026, 28274561, 28274932, 33808, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43746482, 43747118, 28274947, 28275583, 6131, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208902314, 208902635, 28275598, 28275919, 30499, "entier"], ["github/Python", "django/django", "Python", 1345845, 1365668, 28275934, 28295757, 237, "entier"], ["github/C", "curl/curl", "C", 93953446, 93954732, 28295772, 28297058, 13051, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85074372, 85077024, 28297073, 28299725, 11875, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204882500, 204883536, 28299740, 28300776, 29436, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42502131, 42505828, 28300791, 28304488, 5474, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200816856, 200817223, 28304503, 28304870, 28597, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210571098, 210572957, 28304885, 28306744, 31032, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43229559, 43230473, 28306759, 28307673, 5719, "entier"], ["github/C", "curl/curl", "C", 91360140, 91363734, 28307688, 28311282, 12756, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52908475, 52909162, 28311297, 28311984, 8082, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45612802, 45613199, 28311999, 28312396, 6763, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126750676, 126758243, 28312411, 28319978, 16203, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43508570, 43508883, 28319993, 28320306, 5850, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200677958, 200679179, 28320321, 28321542, 28553, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37385484, 37386335, 28321557, 28322408, 4783, "entier"], ["github/Java", "apache/commons-lang", "Java", 153823585, 153876890, 28322423, 28375728, 20324, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45960111, 45961969, 28375743, 28377601, 6811, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238528080, 238547623, 28377616, 28397159, 36727, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37695188, 37696015, 28397174, 28398001, 4877, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28924714, 28950933, 28398016, 28424235, 3952, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47960736, 47961295, 28424250, 28424809, 7074, "entier"], ["github/C++", "opencv/opencv", "C++", 112536807, 112540743, 28424824, 28428760, 15080, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58669554, 58671620, 28428775, 28430841, 9253, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53440865, 53441708, 28430856, 28431699, 8203, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54425314, 54425758, 28431714, 28432158, 8326, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56418834, 56419670, 28432173, 28433009, 8988, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71606506, 71607906, 28433024, 28434424, 10860, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52743926, 52745070, 28434439, 28435583, 7990, "entier"], ["github/Python", "django/django", "Python", 2094961, 2097837, 28435598, 28438474, 399, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120777742, 120781387, 28438489, 28442134, 15666, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61874437, 61876976, 28442149, 28444688, 9656, "entier"], ["github/Python", "django/django", "Python", 4657836, 4658413, 28444703, 28445280, 806, "entier"], ["github/C++", "opencv/opencv", "C++", 116674234, 116677844, 28445295, 28448905, 15334, "entier"], ["github/Python", "django/django", "Python", 8252884, 8256901, 28448920, 28452937, 1322, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 122133270, 122134887, 28452952, 28454569, 15855, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230475198, 230477214, 28454584, 28456600, 34254, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 166926852, 166985148, 28456615, 28514911, 22275, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 119394183, 119395062, 28514926, 28515805, 15542, "entier"], ["github/Python", "django/django", "Python", 9161945, 9162980, 28515820, 28516855, 1417, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213497410, 213517113, 28516870, 28536573, 31617, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227752438, 227753417, 28536588, 28537567, 33519, "entier"], ["github/Python", "django/django", "Python", 5496964, 5497604, 28537582, 28538222, 939, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126841473, 126844217, 28538237, 28540981, 16206, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231456871, 231458375, 28540996, 28542500, 34495, "entier"], ["github/Python", "django/django", "Python", 5004335, 5004902, 28542515, 28543082, 862, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238367107, 238367151, 28543097, 28543141, 36182, "entier"], ["github/C++", "nlohmann/json", "C++", 104073179, 104073602, 28543156, 28543579, 14330, "entier"], ["github/Python", "django/django", "Python", 3954272, 3955614, 28543594, 28544936, 710, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63888388, 63901823, 28544951, 28558386, 9917, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47169734, 47189760, 28558401, 28578427, 6962, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 31988442, 31989663, 28578442, 28579663, 4170, "entier"], ["github/Scala", "scala/scala", "Scala", 223866672, 223871370, 28579678, 28584376, 32824, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28369427, 28373509, 28584391, 28588473, 3886, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140555871, 140559538, 28588488, 28592155, 18489, "entier"], ["github/PHP", "laravel/framework", "PHP", 184863907, 184867061, 28592170, 28595324, 25433, "entier"], ["github/Scala", "playframework/playframework", "Scala", 232594205, 232598494, 28595339, 28599628, 34668, "entier"], ["github/Java", "apache/commons-lang", "Java", 153822424, 153823570, 28599643, 28600789, 20323, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 18994896, 18995033, 28600804, 28600941, 2416, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33563106, 33564462, 28600956, 28602312, 4291, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137646712, 137650930, 28602327, 28606545, 17973, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60172399, 60174297, 28606560, 28608458, 9493, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 27062116, 27062357, 28608473, 28608714, 3555, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227312919, 227313457, 28608729, 28609267, 33498, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231986602, 231987207, 28609282, 28609887, 34589, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33583570, 33584404, 28609902, 28610736, 4297, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215861451, 215866841, 28610751, 28616141, 31979, "entier"], ["github/Python", "django/django", "Python", 9076513, 9093483, 28616156, 28633126, 1410, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71508963, 71510375, 28633141, 28634553, 10739, "entier"], ["github/Go", "prometheus/prometheus", "Go", 83262717, 83312682, 28634568, 28684533, 11697, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195174140, 195180047, 28684548, 28690455, 27563, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65400497, 65400601, 28690470, 28690574, 10111, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71290463, 71291142, 28690589, 28691268, 10588, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200400386, 200401479, 28691283, 28692376, 28470, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141350949, 141360266, 28692391, 28701708, 18537, "entier"], ["github/Scala", "scala/scala", "Scala", 225685317, 225693302, 28701723, 28709708, 33162, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45328354, 45335497, 28709723, 28716866, 6726, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207482005, 207485921, 28716881, 28720797, 30153, "entier"], ["github/C", "curl/curl", "C", 94958237, 94999058, 28720812, 28761633, 13119, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172946806, 173048164, 28761648, 28863006, 23336, "entier"], ["github/PHP", "laravel/framework", "PHP", 187523048, 187528613, 28863021, 28868586, 26139, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230381574, 230381815, 28868601, 28868842, 34203, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138316595, 138320354, 28868857, 28872616, 18140, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234889996, 234890708, 28872631, 28873343, 35266, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213965122, 213966992, 28873358, 28875228, 31721, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46505056, 46509084, 28875243, 28879271, 6878, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235157455, 235161678, 28879286, 28883509, 35337, "entier"], ["github/PHP", "laravel/framework", "PHP", 186697824, 186697949, 28883524, 28883649, 25975, "entier"], ["github/Python", "django/django", "Python", 5459898, 5461124, 28883664, 28884890, 924, "entier"], ["github/Python", "django/django", "Python", 2187512, 2187601, 28884905, 28884994, 435, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138948966, 138955517, 28885009, 28891560, 18246, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233477310, 233492257, 28891575, 28906522, 34804, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69477698, 69496954, 28906537, 28925793, 10517, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229019243, 229020618, 28925808, 28927183, 33732, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231356268, 231357199, 28927198, 28928129, 34474, "entier"], ["github/C++", "nlohmann/json", "C++", 106929969, 106987517, 28928144, 28985692, 14613, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9681297, 9686791, 28985707, 28991201, 1544, "entier"], ["github/PHP", "laravel/framework", "PHP", 189305696, 189313399, 28991216, 28998919, 26441, "entier"], ["github/Java", "google/guava", "Java", 130835188, 130838356, 28998934, 29002102, 16781, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230646915, 230648663, 29002117, 29003865, 34316, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46422257, 46428752, 29003880, 29010375, 6872, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213597401, 213603786, 29010390, 29016775, 31644, "entier"], ["github/Java", "square/okhttp", "Java", 148899340, 148901032, 29016790, 29018482, 19908, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25607585, 25638795, 29018497, 29049707, 3355, "entier"], ["github/Python", "django/django", "Python", 9188654, 9188951, 29049722, 29050019, 1433, "entier"], ["github/Java", "google/guava", "Java", 129636198, 129638059, 29050034, 29051895, 16638, "entier"], ["github/Python", "django/django", "Python", 6566911, 6567292, 29051910, 29052291, 1129, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144073021, 144076465, 29052306, 29055750, 19156, "entier"], ["github/PHP", "laravel/framework", "PHP", 186252416, 186255335, 29055765, 29058684, 25815, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43898318, 43904462, 29058699, 29064843, 6176, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204749325, 204752690, 29064858, 29068223, 29323, "entier"], ["github/Python", "psf/requests", "Python", 58969, 66121, 29068238, 29075390, 8, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192165453, 192166671, 29075405, 29076623, 26930, "entier"], ["github/Java", "square/okhttp", "Java", 146907357, 146913617, 29076638, 29082898, 19742, "entier"], ["github/Scala", "playframework/playframework", "Scala", 232861210, 232876771, 29082913, 29098474, 34718, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215726755, 215728202, 29098489, 29099936, 31942, "entier"], ["github/PHP", "laravel/framework", "PHP", 188105421, 188108129, 29099951, 29102659, 26230, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206080013, 206080320, 29102674, 29102981, 29820, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63715734, 63720389, 29102996, 29107651, 9899, "entier"], ["github/PHP", "laravel/framework", "PHP", 188128617, 188128753, 29107666, 29107802, 26237, "entier"], ["github/Java", "google/guava", "Java", 129181343, 129185893, 29107817, 29112367, 16591, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46297446, 46304263, 29112382, 29119199, 6862, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207663591, 207668587, 29119214, 29124210, 30216, "entier"], ["github/Java", "google/guava", "Java", 131984572, 131985837, 29124225, 29125490, 16883, "entier"], ["github/Python", "django/django", "Python", 3211140, 3218134, 29125505, 29132499, 614, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138587295, 138590664, 29132514, 29135883, 18183, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237844091, 237844725, 29135898, 29136532, 35741, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51733901, 51734322, 29136547, 29136968, 7609, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234842114, 234842931, 29136983, 29137800, 35240, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213024519, 213025047, 29137815, 29138343, 31503, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43309113, 43309679, 29138358, 29138924, 5732, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141164203, 141166923, 29138939, 29141659, 18513, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228519485, 228519986, 29141674, 29142175, 33616, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51314034, 51314478, 29142190, 29142634, 7420, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158286517, 158297964, 29142649, 29154096, 20943, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41982933, 41983361, 29154111, 29154539, 5369, "entier"], ["github/Python", "django/django", "Python", 5001840, 5002446, 29154554, 29155160, 855, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42525731, 42527649, 29155175, 29157093, 5484, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42646153, 42646452, 29157108, 29157407, 5544, "entier"], ["github/Python", "django/django", "Python", 6088593, 6090636, 29157422, 29159465, 1051, "entier"], ["github/Go", "prometheus/prometheus", "Go", 83126204, 83133428, 29159480, 29166704, 11687, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230781293, 230787759, 29166719, 29173185, 34350, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 36566646, 36567207, 29173200, 29173761, 4721, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51639714, 51639997, 29173776, 29174059, 7579, "entier"], ["github/Java", "google/guava", "Java", 132293949, 132302594, 29174074, 29182719, 16938, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42772024, 42772887, 29182734, 29183597, 5607, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10829821, 10831360, 29183612, 29185151, 1740, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51329409, 51330577, 29185166, 29186334, 7444, "entier"], ["github/Python", "django/django", "Python", 7205192, 7206024, 29186349, 29187181, 1213, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37577483, 37578264, 29187196, 29187977, 4813, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51299879, 51300161, 29187992, 29188274, 7386, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9513707, 9514035, 29188289, 29188617, 1504, "entier"], ["github/C", "curl/curl", "C", 93760842, 93762116, 29188632, 29189906, 13043, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 119724601, 119728662, 29189921, 29193982, 15563, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 72204068, 72226395, 29193997, 29216324, 10927, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25760105, 25772348, 29216339, 29228582, 3377, "entier"], ["github/Java", "square/okhttp", "Java", 146674308, 146678224, 29228597, 29232513, 19699, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46855031, 46857816, 29232528, 29235313, 6907, "entier"], ["github/Scala", "scala/scala", "Scala", 223626348, 223631314, 29235328, 29240294, 32792, "entier"], ["github/Python", "django/django", "Python", 8152046, 8155510, 29240309, 29243773, 1308, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136689327, 136690623, 29243788, 29245084, 17739, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230886035, 230886428, 29245099, 29245492, 34391, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52576059, 52579952, 29245507, 29249400, 7955, "entier"], ["github/Scala", "scala/scala", "Scala", 221645000, 221646451, 29249415, 29250866, 32594, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 13245146, 13247735, 29250881, 29253470, 1902, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120924029, 120932321, 29253485, 29261777, 15680, "entier"], ["github/Scala", "playframework/playframework", "Scala", 233343732, 233344334, 29261792, 29262394, 34780, "entier"], ["github/C", "libuv/libuv", "C", 101469978, 101476701, 29262409, 29269132, 13890, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228749545, 228750241, 29269147, 29269843, 33681, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 201274905, 201295595, 29269858, 29290548, 28675, "entier"], ["github/Java", "apache/commons-lang", "Java", 150980183, 150990937, 29290563, 29301317, 20167, "entier"], ["github/Scala", "scala/scala", "Scala", 224217481, 224218151, 29301332, 29302002, 32955, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238822938, 238824494, 29302017, 29303573, 36799, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39382225, 39386243, 29303588, 29307606, 5089, "entier"], ["github/Python", "django/django", "Python", 1817719, 1821525, 29307621, 29311427, 348, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27722640, 27725538, 29311442, 29314340, 3753, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238412622, 238412658, 29314355, 29314391, 36374, "entier"], ["github/C++", "opencv/opencv", "C++", 111001774, 111001917, 29314406, 29314549, 14953, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159971106, 159984824, 29314564, 29328282, 21177, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52050102, 52050721, 29328297, 29328916, 7744, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56320521, 56320755, 29328931, 29329165, 8878, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53208324, 53208692, 29329180, 29329548, 8168, "entier"], ["github/C", "curl/curl", "C", 91133255, 91134065, 29329563, 29330373, 12703, "entier"], ["github/Java", "apache/commons-lang", "Java", 154962397, 154967055, 29330388, 29335046, 20497, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42781081, 42783937, 29335061, 29337917, 5613, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236966193, 236976521, 29337932, 29348260, 35649, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58591239, 58595040, 29348275, 29352076, 9238, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10632284, 10639686, 29352091, 29359493, 1711, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142257742, 142264236, 29359508, 29366002, 18814, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216550667, 216558592, 29366017, 29373942, 32145, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71371160, 71371968, 29373957, 29374765, 10663, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 29737420, 29749879, 29374780, 29387239, 4006, "entier"], ["github/C", "libuv/libuv", "C", 99611905, 99619880, 29387254, 29395229, 13710, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230878817, 230879502, 29395244, 29395929, 34388, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14139078, 14139383, 29395944, 29396249, 1934, "entier"], ["github/Python", "django/django", "Python", 5385122, 5385275, 29396264, 29396417, 915, "entier"], ["github/Java", "apache/commons-lang", "Java", 155818863, 155822185, 29396432, 29399754, 20561, "entier"], ["github/PHP", "laravel/framework", "PHP", 185650265, 185712265, 29399769, 29461769, 25665, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235134536, 235137839, 29461784, 29465087, 35328, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 40863112, 40878773, 29465102, 29480763, 5218, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9360501, 9366266, 29480778, 29486543, 1473, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137875831, 137881961, 29486558, 29492688, 18022, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214227718, 214232216, 29492703, 29497201, 31787, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28306873, 28307871, 29497216, 29498214, 3866, "entier"], ["github/Scala", "scala/scala", "Scala", 224611948, 224617501, 29498229, 29503782, 33055, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27585440, 27586590, 29503797, 29504947, 3697, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58565307, 58582586, 29504962, 29522241, 9233, "entier"], ["github/C", "libuv/libuv", "C", 101679801, 101682223, 29522256, 29524678, 13925, "entier"], ["github/Python", "django/django", "Python", 2101635, 2103987, 29524693, 29527045, 403, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 206026206, 206027611, 29527060, 29528465, 29791, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227205475, 227207267, 29528480, 29530272, 33479, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161936336, 161952835, 29530287, 29546786, 21437, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 34063382, 34070844, 29546801, 29554263, 4373, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138384650, 138400535, 29554278, 29570163, 18149, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43538469, 43540096, 29570178, 29571805, 5903, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 201806958, 201810264, 29571820, 29575126, 28721, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42450937, 42451267, 29575141, 29575471, 5452, "entier"], ["github/Python", "django/django", "Python", 4745570, 4752373, 29575486, 29582289, 821, "entier"], ["github/C", "curl/curl", "C", 91363749, 91368033, 29582304, 29586588, 12757, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43314002, 43314659, 29586603, 29587260, 5739, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 42425124, 42427895, 29587275, 29590046, 5437, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35378536, 35382558, 29590061, 29594083, 4529, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61853207, 61854146, 29594098, 29595037, 9649, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142884057, 142886801, 29595052, 29597796, 18927, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71300103, 71301037, 29597811, 29598745, 10598, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143724074, 143725205, 29598760, 29599891, 19098, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 67633886, 67637482, 29599906, 29603502, 10382, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52717992, 52727351, 29603517, 29612876, 7978, "entier"], ["github/C", "curl/curl", "C", 99008669, 99015410, 29612891, 29619632, 13624, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143462306, 143468118, 29619647, 29625459, 19026, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164540484, 164541205, 29625474, 29626195, 21928, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71603544, 71604339, 29626210, 29627005, 10857, "entier"], ["github/Go", "gohugoio/hugo", "Go", 86691911, 86761988, 29627020, 29697097, 12112, "entier"], ["github/Java", "google/guava", "Java", 132400951, 132402725, 29697112, 29698886, 16944, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 29110107, 29119547, 29698901, 29708341, 3960, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 57142419, 57144172, 29708356, 29710109, 9106, "entier"], ["github/Python", "django/django", "Python", 1046283, 1064704, 29710124, 29728545, 211, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214375428, 214393448, 29728560, 29746580, 31828, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44741590, 44744519, 29746595, 29749524, 6386, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159180103, 159187868, 29749539, 29757304, 21082, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143204818, 143215452, 29757319, 29767953, 19002, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28363829, 28367875, 29767968, 29772014, 3884, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136154073, 136155572, 29772029, 29773528, 17347, "entier"], ["github/C++", "fmtlib/fmt", "C++", 109306031, 109409127, 29773543, 29876639, 14718, "entier"], ["github/C", "libuv/libuv", "C", 100507800, 100516191, 29876654, 29885045, 13791, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142246505, 142249695, 29885060, 29888250, 18807, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199922140, 199923576, 29888265, 29889701, 28271, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159397752, 159400310, 29889716, 29892274, 21117, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60128585, 60145128, 29892289, 29908832, 9483, "entier"], ["github/Python", "django/django", "Python", 7285036, 7285177, 29908847, 29908988, 1220, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168638070, 168639616, 29909003, 29910549, 22645, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164011639, 164012306, 29910564, 29911231, 21845, "entier"], ["github/Java", "square/okhttp", "Java", 145555865, 145565826, 29911246, 29921207, 19553, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53727269, 53748404, 29921222, 29942357, 8245, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164670017, 164674069, 29942372, 29946424, 21969, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35121448, 35136686, 29946439, 29961677, 4503, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212481776, 212486690, 29961692, 29966606, 31430, "entier"], ["github/Java", "apache/commons-lang", "Java", 152888820, 152890184, 29966621, 29967985, 20285, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136224617, 136226402, 29968000, 29969785, 17403, "entier"], ["github/Java", "square/okhttp", "Java", 148966524, 148968144, 29969800, 29971420, 19933, "entier"], ["github/PHP", "laravel/framework", "PHP", 185631264, 185650122, 29971435, 29990293, 25663, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168114168, 168115724, 29990308, 29991864, 22355, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 65415778, 65421289, 29991879, 29997390, 10163, "entier"], ["github/Java", "apache/commons-lang", "Java", 155191695, 155195843, 29997405, 30001553, 20508, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206190660, 206192507, 30001568, 30003415, 29865, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162960940, 162962867, 30003430, 30005357, 21647, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 15397202, 15417487, 30005372, 30025657, 2055, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160869616, 160870874, 30025672, 30026930, 21287, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163951345, 163951928, 30026945, 30027528, 21835, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168392044, 168393478, 30027543, 30028977, 22504, "entier"], ["github/C", "libuv/libuv", "C", 99778516, 99795061, 30028992, 30045537, 13739, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45622790, 45630099, 30045552, 30052861, 6766, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158076181, 158076516, 30052876, 30053211, 20896, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175849160, 175853099, 30053226, 30057165, 23749, "entier"], ["github/Scala", "scala/scala", "Scala", 222480357, 222573587, 30057180, 30150410, 32710, "entier"], ["github/Java", "square/okhttp", "Java", 144765579, 144783821, 30150425, 30168667, 19370, "entier"], ["github/PHP", "laravel/framework", "PHP", 186661827, 186663571, 30168682, 30170426, 25965, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58904453, 58919249, 30170441, 30185237, 9320, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189887408, 189890556, 30185252, 30188400, 26531, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19082974, 19098949, 30188415, 30204390, 2624, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197872138, 197872564, 30204405, 30204831, 28080, "entier"], ["github/PHP", "laravel/framework", "PHP", 185098420, 185098663, 30204846, 30205089, 25488, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55979637, 55988441, 30205104, 30213908, 8638, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172781667, 172785179, 30213923, 30217435, 23303, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216143818, 216154551, 30217450, 30228183, 32035, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197394952, 197401777, 30228198, 30235023, 27977, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170984841, 171002295, 30235038, 30252492, 22895, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179434212, 179434607, 30252507, 30252902, 24303, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38661177, 38661313, 30252917, 30253053, 4998, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52377518, 52377717, 30253068, 30253267, 7894, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179240452, 179241367, 30253282, 30254197, 24268, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90769752, 90770815, 30254212, 30255275, 12651, "entier"], ["github/Python", "django/django", "Python", 3041959, 3056935, 30255290, 30270266, 597, "entier"], ["github/C", "libuv/libuv", "C", 101512093, 101514995, 30270281, 30273183, 13899, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46609251, 46614477, 30273198, 30278424, 6890, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177110250, 177111851, 30278439, 30280040, 23896, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196238728, 196240137, 30280055, 30281464, 27737, "entier"], ["github/Java", "square/okhttp", "Java", 145810902, 145836352, 30281479, 30306929, 19589, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173267459, 173267866, 30306944, 30307351, 23377, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52230579, 52232914, 30307366, 30309701, 7842, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33680631, 33690522, 30309716, 30319607, 4326, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 40832543, 40833097, 30319622, 30320176, 5213, "entier"], ["github/PHP", "laravel/framework", "PHP", 185843128, 185851451, 30320191, 30328514, 25704, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 57123675, 57142404, 30328529, 30347258, 9105, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10025168, 10028226, 30347273, 30350331, 1607, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 201551569, 201595875, 30350346, 30394652, 28709, "entier"], ["github/Java", "square/okhttp", "Java", 148216346, 148217388, 30394667, 30395709, 19836, "entier"], ["github/C++", "opencv/opencv", "C++", 111986303, 111995589, 30395724, 30405010, 15030, "entier"], ["github/Python", "django/django", "Python", 5567657, 5568796, 30405025, 30406164, 961, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170436942, 170441914, 30406179, 30411151, 22836, "entier"], ["github/PHP", "laravel/framework", "PHP", 183979109, 183981324, 30411166, 30413381, 25317, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139227911, 139233833, 30413396, 30419318, 18291, "entier"], ["github/Python", "django/django", "Python", 1530382, 1533068, 30419333, 30422019, 261, "entier"], ["github/PHP", "laravel/framework", "PHP", 189486818, 189488609, 30422034, 30423825, 26473, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177770900, 177781868, 30423840, 30434808, 24065, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33230661, 33241120, 30434823, 30445282, 4246, "entier"], ["github/C++", "nlohmann/json", "C++", 104101126, 104102248, 30445297, 30446419, 14359, "entier"], ["github/Java", "square/okhttp", "Java", 146898034, 146899025, 30446434, 30447425, 19739, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169133005, 169135255, 30447440, 30449690, 22743, "entier"], ["github/C++", "nlohmann/json", "C++", 105810808, 105812611, 30449705, 30451508, 14571, "entier"], ["github/PHP", "laravel/framework", "PHP", 184366918, 184371820, 30451523, 30456425, 25354, "entier"], ["github/Go", "prometheus/prometheus", "Go", 76685293, 76714870, 30456440, 30486017, 11254, "entier"], ["github/C++", "opencv/opencv", "C++", 117037797, 117039520, 30486032, 30487755, 15415, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 73469264, 73471451, 30487770, 30489957, 10966, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14225268, 14232150, 30489972, 30496854, 1952, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65405794, 65405901, 30496869, 30496976, 10142, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71326077, 71326813, 30496991, 30497727, 10622, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233613568, 233614638, 30497742, 30498812, 34857, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 125014341, 125019876, 30498827, 30504362, 16048, "entier"], ["github/PHP", "laravel/framework", "PHP", 186435101, 186439282, 30504377, 30508558, 25863, "entier"], ["github/Java", "apache/commons-lang", "Java", 150482259, 150502312, 30508573, 30528626, 20075, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69340250, 69346321, 30528641, 30534712, 10500, "entier"], ["github/C++", "nlohmann/json", "C++", 104066598, 104067515, 30534727, 30535644, 14319, "entier"], ["github/C++", "fmtlib/fmt", "C++", 110002374, 110002488, 30535659, 30535773, 14776, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 20825643, 20832404, 30535788, 30542549, 2830, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195258174, 195258771, 30542564, 30543161, 27585, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158160171, 158171152, 30543176, 30554157, 20922, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198814424, 198816334, 30554172, 30556082, 28207, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180613684, 180615079, 30556097, 30557492, 24524, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193406550, 193406932, 30557507, 30557889, 27212, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 62334160, 62338977, 30557904, 30562721, 9702, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136607048, 136608119, 30562736, 30563807, 17678, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142252807, 142254706, 30563822, 30565721, 18811, "entier"], ["github/Java", "square/okhttp", "Java", 147884412, 147885952, 30565736, 30567276, 19807, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 179956029, 179960838, 30567291, 30572100, 24381, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168679199, 168680578, 30572115, 30573494, 22667, "entier"], ["github/Java", "apache/commons-lang", "Java", 154447049, 154448924, 30573509, 30575384, 20396, "entier"], ["github/Java", "google/guava", "Java", 133248388, 133251097, 30575399, 30578108, 17068, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75534239, 75536141, 30578123, 30580025, 11172, "entier"], ["github/Java", "apache/commons-lang", "Java", 153500826, 153503804, 30580040, 30583018, 20313, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 214623861, 214626007, 30583033, 30585179, 31862, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 29977029, 29995872, 30585194, 30604037, 4028, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136590912, 136592210, 30604052, 30605350, 17667, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78907881, 78909593, 30605365, 30607077, 11445, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 124662850, 124699037, 30607092, 30643279, 16029, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141371006, 141372363, 30643294, 30644651, 18544, "entier"], ["github/Scala", "scala/scala", "Scala", 223772221, 223793940, 30644666, 30666385, 32814, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 68724255, 68739353, 30666400, 30681498, 10456, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85592340, 85592727, 30681513, 30681900, 11977, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209458426, 209460758, 30681915, 30684247, 30631, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 161500730, 161516141, 30684262, 30699673, 21400, "entier"], ["github/Go", "spf13/cobra", "Go", 75701349, 75708405, 30699688, 30706744, 11187, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233725088, 233726961, 30706759, 30708632, 34924, "entier"], ["github/C", "curl/curl", "C", 99135507, 99192445, 30708647, 30765585, 13654, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210643546, 210648152, 30765600, 30770206, 31047, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172843511, 172853747, 30770221, 30780457, 23315, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216536147, 216536803, 30780472, 30781128, 32140, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19015885, 19015910, 30781143, 30781168, 2470, "entier"], ["github/Java", "google/guava", "Java", 132372106, 132397319, 30781183, 30806396, 16942, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63470162, 63472378, 30806411, 30808627, 9849, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85720194, 85721763, 30808642, 30810211, 12007, "entier"], ["github/PHP", "laravel/framework", "PHP", 189492162, 189536701, 30810226, 30854765, 26475, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 56582756, 56585463, 30854780, 30857487, 9081, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238065203, 238073189, 30857502, 30865488, 35799, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160684620, 160686898, 30865503, 30867781, 21209, "entier"], ["github/Python", "django/django", "Python", 6215360, 6276910, 30867796, 30929346, 1068, "entier"], ["github/C++", "opencv/opencv", "C++", 117018252, 117022868, 30929361, 30933977, 15412, "entier"], ["github/Java", "apache/commons-lang", "Java", 155285626, 155286940, 30933992, 30935306, 20515, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142075911, 142076940, 30935321, 30936350, 18750, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215935302, 215937923, 30936365, 30938986, 31998, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162579331, 162582524, 30939001, 30942194, 21560, "entier"], ["github/C++", "google/leveldb", "C++", 110351653, 110354545, 30942209, 30945101, 14805, "entier"], ["github/Java", "apache/commons-lang", "Java", 155499867, 155501619, 30945116, 30946868, 20530, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234639904, 234644685, 30946883, 30951664, 35186, "entier"], ["github/Java", "square/okhttp", "Java", 144934499, 144935149, 30951679, 30952329, 19407, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 73065883, 73078682, 30952344, 30965143, 10944, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121421308, 121423342, 30965158, 30967192, 15726, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143247106, 143249879, 30967207, 30969980, 19009, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238427693, 238427715, 30969995, 30970017, 36573, "entier"], ["github/Scala", "scala/scala", "Scala", 224190393, 224190921, 30970032, 30970560, 32911, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159025309, 159027329, 30970575, 30972595, 21046, "entier"], ["github/Java", "square/okhttp", "Java", 145602724, 145605849, 30972610, 30975735, 19565, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172752974, 172759258, 30975750, 30982034, 23296, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160906009, 160907496, 30982049, 30983536, 21306, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236846087, 236850792, 30983551, 30988256, 35631, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 123289456, 123296708, 30988271, 30995523, 15953, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202667436, 202689721, 30995538, 31017823, 28879, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 49340109, 49461128, 31017838, 31138857, 7134, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233941319, 233942008, 31138872, 31139561, 34981, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71584369, 71585280, 31139576, 31140487, 10843, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65398194, 65398335, 31140502, 31140643, 10095, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 32900902, 32938224, 31140658, 31177980, 4222, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228622313, 228626064, 31177995, 31181746, 33652, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75503482, 75534224, 31181761, 31212503, 11171, "entier"], ["github/Scala", "scala/scala", "Scala", 223726936, 223729034, 31212518, 31214616, 32805, "entier"], ["github/C++", "opencv/opencv", "C++", 112711110, 112721622, 31214631, 31225143, 15101, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63153129, 63162333, 31225158, 31234362, 9781, "entier"], ["github/Scala", "scala/scala", "Scala", 217432542, 217435230, 31234377, 31237065, 32226, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 166327376, 166341443, 31237080, 31251147, 22251, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189910550, 189912725, 31251162, 31253337, 26542, "entier"], ["github/Java", "google/guava", "Java", 129793095, 129826372, 31253352, 31286629, 16676, "entier"], ["github/C++", "opencv/opencv", "C++", 110987068, 110987232, 31286644, 31286808, 14926, "entier"], ["github/Scala", "scala/scala", "Scala", 223443806, 223448023, 31286823, 31291040, 32767, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233903198, 233903744, 31291055, 31291601, 34960, "entier"], ["github/PHP", "laravel/framework", "PHP", 186210969, 186216533, 31291616, 31297180, 25793, "entier"], ["github/C++", "google/leveldb", "C++", 110562168, 110570584, 31297195, 31305611, 14834, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172379264, 172390008, 31305626, 31316370, 23250, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226814851, 226819053, 31316385, 31320587, 33360, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216657949, 216662034, 31320602, 31324687, 32159, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202296961, 202299462, 31324702, 31327203, 28827, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59919546, 59927216, 31327218, 31334888, 9460, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235380259, 235380491, 31334903, 31335135, 35389, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238423526, 238423552, 31335150, 31335176, 36497, "entier"], ["github/Scala", "scala/scala", "Scala", 221525895, 221527108, 31335191, 31336404, 32569, "entier"], ["github/C++", "nlohmann/json", "C++", 104100319, 104101111, 31336419, 31337211, 14358, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213925056, 213926148, 31337226, 31338318, 31713, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168161168, 168162572, 31338333, 31339737, 22387, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120299945, 120301200, 31339752, 31341007, 15624, "entier"], ["github/C++", "nlohmann/json", "C++", 108144997, 108146117, 31341022, 31342142, 14667, "entier"], ["github/C++", "opencv/opencv", "C++", 110989213, 110989539, 31342157, 31342483, 14933, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 203848861, 203851082, 31342498, 31344719, 29054, "entier"], ["github/C++", "opencv/opencv", "C++", 117039535, 117040157, 31344734, 31345356, 15416, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170364822, 170366921, 31345371, 31347470, 22819, "entier"], ["github/Java", "apache/commons-lang", "Java", 153821400, 153822409, 31347485, 31348494, 20322, "entier"], ["github/Scala", "scala/scala", "Scala", 220658142, 220667209, 31348509, 31357576, 32484, "entier"], ["github/Java", "apache/commons-lang", "Java", 150106274, 150108569, 31357591, 31359886, 20038, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24360886, 24362007, 31359901, 31361022, 3192, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142063489, 142064607, 31361037, 31362155, 18737, "entier"], ["github/Go", "gohugoio/hugo", "Go", 86677947, 86683244, 31362170, 31367467, 12107, "entier"], ["github/C", "libuv/libuv", "C", 101531010, 101533428, 31367482, 31369900, 13903, "entier"], ["github/Java", "google/guava", "Java", 128825738, 128829106, 31369915, 31373283, 16526, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212534303, 212539368, 31373298, 31378363, 31438, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191686863, 191704283, 31378378, 31395798, 26847, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 180786982, 180788271, 31395813, 31397102, 24565, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 35595212, 35602726, 31397117, 31404631, 4570, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 13633715, 13642396, 31404646, 31413327, 1913, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173133646, 173134044, 31413342, 31413740, 23348, "entier"], ["github/C", "libuv/libuv", "C", 102157572, 102159700, 31413755, 31415883, 14001, "entier"], ["github/Scala", "scala/scala", "Scala", 224536121, 224541428, 31415898, 31421205, 33040, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238427758, 238427799, 31421220, 31421261, 36575, "entier"], ["github/C", "curl/curl", "C", 91414988, 91416559, 31421276, 31422847, 12776, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228034623, 228035731, 31422862, 31423970, 33558, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90716711, 90724225, 31423985, 31431499, 12643, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204007101, 204012999, 31431514, 31437412, 29090, "entier"], ["github/C++", "opencv/opencv", "C++", 114793516, 114825566, 31437427, 31469477, 15220, "entier"], ["github/Python", "django/django", "Python", 5622476, 5626114, 31469492, 31473130, 974, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138718120, 138742378, 31473145, 31497403, 18210, "entier"], ["github/C", "curl/curl", "C", 98138189, 98141366, 31497418, 31500595, 13380, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234924162, 234930820, 31500610, 31507268, 35280, "entier"], ["github/Ruby", "rails/rails", "Ruby", 172710052, 172717616, 31507283, 31514847, 23288, "entier"], ["github/PHP", "laravel/framework", "PHP", 185582567, 185584058, 31514862, 31516353, 25641, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157314306, 157335404, 31516368, 31537466, 20713, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194621986, 194622810, 31537481, 31538305, 27432, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200350374, 200351230, 31538320, 31539176, 28454, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195138635, 195139261, 31539191, 31539817, 27554, "entier"], ["github/C", "curl/curl", "C", 93597850, 93599461, 31539832, 31541443, 13029, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28245126, 28260296, 31541458, 31556628, 3858, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205968660, 205971771, 31556643, 31559754, 29768, "entier"], ["github/Go", "prometheus/prometheus", "Go", 80456759, 80462722, 31559769, 31565732, 11541, "entier"], ["github/Python", "encode/httpx", "Python", 17716734, 17725281, 31565747, 31574294, 2138, "entier"], ["github/C", "curl/curl", "C", 98103873, 98107984, 31574309, 31578420, 13368, "entier"], ["github/Java", "square/okhttp", "Java", 144567023, 144568384, 31578435, 31579796, 19308, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178915361, 178916436, 31579811, 31580886, 24236, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233758813, 233762309, 31580901, 31584397, 34931, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141901473, 141904066, 31584412, 31587005, 18643, "entier"], ["github/Go", "prometheus/prometheus", "Go", 84448724, 84449705, 31587020, 31588001, 11763, "entier"], ["github/Scala", "scala/scala", "Scala", 220453408, 220471367, 31588016, 31605975, 32480, "entier"], ["github/C++", "nlohmann/json", "C++", 104109939, 104110756, 31605990, 31606807, 14373, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 12604358, 12608750, 31606822, 31611214, 1870, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21944206, 21945257, 31611229, 31612280, 3043, "entier"], ["github/JavaScript", "expressjs/express", "JavaScript", 18265960, 18266766, 31612295, 31613101, 2260, "entier"], ["github/Java", "apache/commons-lang", "Java", 151670344, 151681261, 31613116, 31624033, 20211, "entier"], ["github/C", "libuv/libuv", "C", 100960348, 100964655, 31624048, 31628355, 13830, "entier"], ["github/C++", "opencv/opencv", "C++", 114531826, 114536991, 31628370, 31633535, 15196, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171801073, 171805968, 31633550, 31638445, 23044, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60681447, 60738608, 31638460, 31695621, 9547, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193502823, 193528183, 31695636, 31720996, 27241, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 19562461, 19568039, 31721011, 31726589, 2752, "entier"], ["github/Python", "django/django", "Python", 5730766, 5736325, 31726604, 31732163, 991, "entier"], ["github/Java", "square/okhttp", "Java", 145522444, 145523074, 31732178, 31732808, 19541, "entier"], ["github/Java", "google/guava", "Java", 128139611, 128142712, 31732823, 31735924, 16367, "entier"], ["github/C++", "opencv/opencv", "C++", 112520651, 112528647, 31735939, 31743935, 15077, "entier"], ["github/Scala", "playframework/playframework", "Scala", 225872599, 225873517, 31743950, 31744868, 33203, "entier"], ["github/Scala", "scala/scala", "Scala", 224236580, 224237251, 31744883, 31745554, 32983, "entier"], ["github/Java", "square/okhttp", "Java", 144921031, 144923784, 31745569, 31748322, 19401, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230333024, 230333856, 31748337, 31749169, 34181, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212029650, 212052212, 31749184, 31771746, 31377, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10448715, 10451403, 31771761, 31774449, 1680, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90331342, 90352851, 31774464, 31795973, 12586, "entier"], ["github/C++", "nlohmann/json", "C++", 104018098, 104018453, 31795988, 31796343, 14254, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54561658, 54562412, 31796358, 31797112, 8423, "entier"], ["github/Python", "django/django", "Python", 4822793, 4822895, 31797127, 31797229, 828, "entier"], ["github/Python", "django/django", "Python", 2334244, 2335080, 31797244, 31798080, 483, "entier"], ["github/C++", "opencv/opencv", "C++", 116495165, 116497341, 31798095, 31800271, 15302, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236407434, 236412664, 31800286, 31805516, 35578, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174563703, 174569761, 31805531, 31811589, 23504, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138681739, 138693606, 31811604, 31823471, 18202, "entier"], ["github/Python", "django/django", "Python", 3083686, 3086779, 31823486, 31826579, 600, "entier"], ["github/C", "libuv/libuv", "C", 100438271, 100451031, 31826594, 31839354, 13786, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163963671, 163986271, 31839369, 31861969, 21842, "entier"], ["github/Python", "django/django", "Python", 3202687, 3204731, 31861984, 31864028, 611, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196844152, 196845055, 31864043, 31864946, 27864, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 39599226, 39612030, 31864961, 31877765, 5137, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141811910, 141814986, 31877780, 31880856, 18613, "entier"], ["github/PHP", "laravel/framework", "PHP", 187957631, 187959833, 31880871, 31883073, 26198, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235389253, 235399099, 31883088, 31892934, 35395, "entier"], ["github/Python", "django/django", "Python", 5490005, 5494980, 31892949, 31897924, 934, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193055930, 193057058, 31897939, 31899067, 27098, "entier"], ["github/Java", "google/guava", "Java", 127951406, 127953864, 31899082, 31901540, 16315, "entier"], ["github/Java", "google/guava", "Java", 129556473, 129558356, 31901555, 31903438, 16616, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142064622, 142065843, 31903453, 31904674, 18738, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190987317, 190991387, 31904689, 31908759, 26769, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142941148, 142942655, 31908774, 31910281, 18947, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43325035, 43325638, 31910296, 31910899, 5754, "entier"], ["github/Scala", "scala/scala", "Scala", 219986706, 219988770, 31910914, 31912978, 32450, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38751617, 38752477, 31912993, 31913853, 5010, "entier"], ["github/C", "libuv/libuv", "C", 99639868, 99641317, 31913868, 31915317, 13713, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200083166, 200085245, 31915332, 31917411, 28359, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9339593, 9345089, 31917426, 31922922, 1469, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44758692, 44761093, 31922937, 31925338, 6395, "entier"], ["github/C", "libuv/libuv", "C", 100123986, 100125522, 31925353, 31926889, 13767, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56463773, 56464306, 31926904, 31927437, 9026, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42912619, 42912937, 31927452, 31927770, 5652, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208851798, 208854913, 31927785, 31930900, 30491, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75486036, 75496789, 31930915, 31941668, 11169, "entier"], ["github/Python", "django/django", "Python", 7015861, 7018227, 31941683, 31944049, 1205, "entier"], ["github/Scala", "playframework/playframework", "Scala", 232530133, 232543386, 31944064, 31957317, 34651, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139164030, 139184808, 31957332, 31978110, 18280, "entier"], ["github/C", "curl/curl", "C", 98973751, 98977556, 31978125, 31981930, 13614, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 180998068, 181011792, 31981945, 31995669, 24617, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207939908, 207941120, 31995684, 31996896, 30285, "entier"], ["github/Python", "django/django", "Python", 3556382, 3558749, 31996911, 31999278, 645, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60123072, 60124234, 31999293, 32000455, 9481, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204816360, 204816739, 32000470, 32000849, 29344, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71545120, 71545758, 32000864, 32001502, 10776, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196674252, 196691604, 32001517, 32018869, 27844, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233500742, 233501844, 32018884, 32019986, 34808, "entier"], ["github/Python", "django/django", "Python", 980771, 982291, 32020001, 32021521, 180, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 50866793, 50880444, 32021536, 32035187, 7186, "entier"], ["github/Rust", "alacritty/alacritty", "Rust", 73828557, 73829753, 32035202, 32036398, 10990, "entier"], ["github/C", "curl/curl", "C", 98862406, 98864080, 32036413, 32038087, 13584, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10433856, 10435284, 32038102, 32039530, 1675, "entier"], ["github/Swift", "apple/swift-nio", "Swift", 215604711, 215621131, 32039545, 32055965, 31925, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210445475, 210452619, 32055980, 32063124, 30988, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69429313, 69434359, 32063139, 32068185, 10511, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236766765, 236768717, 32068200, 32070152, 35618, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162053260, 162065979, 32070167, 32082886, 21447, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 16957220, 16961547, 32082901, 32087228, 2114, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141595900, 141598452, 32087243, 32089795, 18581, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230315497, 230315856, 32089810, 32090169, 34157, "entier"], ["github/C", "curl/curl", "C", 98723549, 98727186, 32090184, 32093821, 13551, "entier"], ["github/Scala", "scala/scala", "Scala", 224211326, 224211998, 32093836, 32094508, 32946, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238476514, 238476541, 32094523, 32094550, 36710, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136463242, 136464359, 32094565, 32095682, 17566, "entier"], ["github/Scala", "scala/scala", "Scala", 224059981, 224061219, 32095697, 32096935, 32860, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238464593, 238464821, 32096950, 32097178, 36693, "entier"], ["github/Scala", "scala/scala", "Scala", 224242062, 224242736, 32097193, 32097867, 32991, "entier"], ["github/Scala", "scala/scala", "Scala", 221694268, 221694733, 32097882, 32098347, 32619, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138052693, 138057839, 32098362, 32103508, 18063, "entier"], ["github/Python", "django/django", "Python", 5321076, 5323309, 32103523, 32105756, 909, "entier"], ["github/Scala", "scala/scala", "Scala", 224193664, 224194194, 32105771, 32106301, 32917, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41055213, 41059138, 32106316, 32110241, 5241, "entier"], ["github/PHP", "laravel/framework", "PHP", 182221986, 182223878, 32110256, 32112148, 24862, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200201901, 200204182, 32112163, 32114444, 28414, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236172623, 236175556, 32114459, 32117392, 35537, "entier"], ["github/Python", "django/django", "Python", 4509614, 4510809, 32117407, 32118602, 786, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234025822, 234025953, 32118617, 32118748, 35028, "entier"], ["github/C", "curl/curl", "C", 95397256, 95400630, 32118763, 32122137, 13147, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63333319, 63342180, 32122152, 32131013, 9818, "entier"], ["github/PHP", "laravel/framework", "PHP", 181747830, 181748589, 32131028, 32131787, 24790, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44920431, 44921594, 32131802, 32132965, 6465, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194482518, 194482930, 32132980, 32133392, 27390, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43575465, 43575829, 32133407, 32133771, 5962, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230379448, 230381559, 32133786, 32135897, 34202, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 9264988, 9268793, 32135912, 32139717, 1449, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176936535, 176938890, 32139732, 32142087, 23836, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238367223, 238367267, 32142102, 32142146, 36184, "entier"], ["github/C", "libuv/libuv", "C", 99567590, 99568378, 32142161, 32142949, 13696, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191786841, 191791351, 32142964, 32147474, 26857, "entier"], ["github/Java", "apache/commons-lang", "Java", 152325450, 152340522, 32147489, 32162561, 20255, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233558674, 233559260, 32162576, 32163162, 34829, "entier"], ["github/Scala", "scala/scala", "Scala", 219068342, 219075557, 32163177, 32170392, 32368, "entier"], ["github/C", "curl/curl", "C", 98825729, 98829149, 32170407, 32173827, 13573, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 68392490, 68396818, 32173842, 32178170, 10437, "entier"], ["github/Python", "django/django", "Python", 6350210, 6356779, 32178185, 32184754, 1090, "entier"], ["github/Ruby", "rails/rails", "Ruby", 176165372, 176168974, 32184769, 32188371, 23791, "entier"], ["github/PHP", "symfony/symfony", "PHP", 197613766, 197619648, 32188386, 32194268, 28011, "entier"], ["github/C", "libuv/libuv", "C", 99573787, 99575430, 32194283, 32195926, 13700, "entier"], ["github/Java", "google/guava", "Java", 129618956, 129622410, 32195941, 32199395, 16632, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233548448, 233548548, 32199410, 32199510, 34824, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205407282, 205422694, 32199525, 32214937, 29622, "entier"], ["github/Python", "pallets/flask", "Python", 356066, 356096, 32214952, 32214982, 52, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233942757, 233942821, 32214997, 32215061, 34985, "entier"], ["github/Java", "apache/commons-lang", "Java", 154760690, 154762804, 32215076, 32217190, 20463, "entier"], ["github/PHP", "laravel/framework", "PHP", 184922169, 184923688, 32217205, 32218724, 25444, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140206594, 140208199, 32218739, 32220344, 18458, "entier"], ["github/PHP", "symfony/symfony", "PHP", 189900981, 189902454, 32220359, 32221832, 26537, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55398686, 55425506, 32221847, 32248667, 8504, "entier"], ["github/Python", "django/django", "Python", 8242379, 8248889, 32248682, 32255192, 1320, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 171154805, 171175134, 32255207, 32275536, 22910, "entier"], ["github/Java", "square/okhttp", "Java", 146142256, 146146255, 32275551, 32279550, 19621, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143803587, 143804896, 32279565, 32280874, 19121, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136246561, 136247431, 32280889, 32281759, 17420, "entier"], ["github/C", "curl/curl", "C", 91422346, 91431285, 32281774, 32290713, 12780, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193135657, 193141873, 32290728, 32296944, 27139, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136678311, 136679454, 32296959, 32298102, 17732, "entier"], ["github/Go", "prometheus/prometheus", "Go", 80950959, 80999188, 32298117, 32346346, 11567, "entier"], ["github/Python", "django/django", "Python", 9010123, 9012607, 32346361, 32348845, 1399, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136210883, 136212236, 32348860, 32350213, 17393, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141873375, 141874250, 32350228, 32351103, 18627, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24442719, 24554091, 32351118, 32462490, 3204, "entier"], ["github/Java", "square/okhttp", "Java", 148979073, 148980741, 32462505, 32464173, 19940, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59222733, 59246300, 32464188, 32487755, 9361, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208109785, 208110754, 32487770, 32488739, 30330, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192228350, 192229591, 32488754, 32489995, 26946, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193869102, 193870986, 32490010, 32491894, 27296, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204915279, 204917874, 32491909, 32494504, 29450, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138932040, 138940510, 32494519, 32502989, 18244, "entier"], ["github/PHP", "laravel/framework", "PHP", 188720568, 188721501, 32503004, 32503937, 26348, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 16196501, 16205845, 32503952, 32513296, 2082, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206070475, 206072291, 32513311, 32515127, 29814, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226238632, 226278117, 32515142, 32554627, 33289, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 125497955, 125647558, 32554642, 32704245, 16101, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44277138, 44278891, 32704260, 32706013, 6259, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168149409, 168150956, 32706028, 32707575, 22379, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139008913, 139012904, 32707590, 32711581, 18253, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207543354, 207544367, 32711596, 32712609, 30168, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195565125, 195571586, 32712624, 32719085, 27648, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43557845, 43557996, 32719100, 32719251, 5932, "entier"], ["github/C", "curl/curl", "C", 92635304, 92642169, 32719266, 32726131, 12941, "entier"], ["github/Java", "apache/commons-lang", "Java", 154232421, 154233609, 32726146, 32727334, 20371, "entier"], ["github/Python", "django/django", "Python", 5832288, 5832655, 32727349, 32727716, 1004, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207137091, 207138894, 32727731, 32729534, 30100, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 40855535, 40859032, 32729549, 32733046, 5216, "entier"], ["github/Python", "django/django", "Python", 6586982, 6587294, 32733061, 32733373, 1138, "entier"], ["github/Python", "django/django", "Python", 6619951, 6622555, 32733388, 32735992, 1152, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175614698, 175636409, 32736007, 32757718, 23702, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 156673692, 156679056, 32757733, 32763097, 20620, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 199752647, 199755077, 32763112, 32765542, 28256, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71567621, 71568509, 32765557, 32766445, 10815, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190235255, 190240622, 32766460, 32771827, 26591, "entier"], ["github/C", "madler/zlib", "C", 102189713, 102193352, 32771842, 32775481, 14007, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163463494, 163467528, 32775496, 32779530, 21713, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47567001, 47580325, 32779545, 32792869, 7002, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206803327, 206814509, 32792884, 32804066, 30009, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 12422993, 12434956, 32804081, 32816044, 1861, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193286101, 193287062, 32816059, 32817020, 27171, "entier"], ["github/C", "libuv/libuv", "C", 101907017, 101909038, 32817035, 32819056, 13963, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59110501, 59124502, 32819071, 32833072, 9349, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160730448, 160733512, 32833087, 32836151, 21228, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193265998, 193271758, 32836166, 32841926, 27168, "entier"], ["github/C", "libuv/libuv", "C", 102076204, 102079294, 32841941, 32845031, 13983, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168324498, 168325783, 32845046, 32846331, 22464, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229974197, 229976470, 32846346, 32848619, 33985, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51794117, 51796041, 32848634, 32850558, 7660, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159500587, 159501155, 32850573, 32851141, 21141, "entier"], ["github/PHP", "laravel/framework", "PHP", 183694456, 183694559, 32851156, 32851259, 25282, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204844837, 204845875, 32851274, 32852312, 29384, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230263683, 230264948, 32852327, 32853592, 34128, "entier"], ["github/Java", "apache/commons-lang", "Java", 151476841, 151529719, 32853607, 32906485, 20194, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168143702, 168145242, 32906500, 32908040, 22375, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 10831375, 10836131, 32908055, 32912811, 1741, "entier"], ["github/PHP", "symfony/symfony", "PHP", 191858472, 191862051, 32912826, 32916405, 26882, "entier"], ["github/Scala", "scala/scala", "Scala", 219921907, 219924212, 32916420, 32918725, 32446, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233618092, 233622575, 32918740, 32923223, 34862, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65405916, 65406049, 32923238, 32923371, 10143, "entier"], ["github/C", "curl/curl", "C", 99058862, 99060768, 32923386, 32925292, 13635, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53193513, 53199135, 32925307, 32930929, 8155, "entier"], ["github/Scala", "sbt/sbt", "Scala", 237574170, 237576448, 32930944, 32933222, 35711, "entier"], ["github/C", "libuv/libuv", "C", 101597953, 101599597, 32933237, 32934881, 13914, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230207605, 230209464, 32934896, 32936755, 34075, "entier"], ["github/Ruby", "sinatra/sinatra", "Ruby", 181163425, 181163589, 32936770, 32936934, 24641, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 63224384, 63232819, 32936949, 32945384, 9800, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56473247, 56477254, 32945399, 32949406, 9040, "entier"], ["github/Scala", "playframework/playframework", "Scala", 225924930, 225926376, 32949421, 32950867, 33219, "entier"], ["github/Go", "gohugoio/hugo", "Go", 87129177, 87141876, 32950882, 32963581, 12149, "entier"], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 201708923, 201719423, 32963596, 32974096, 28713, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175016128, 175017435, 32974111, 32975418, 23627, "entier"], ["github/C", "curl/curl", "C", 91384609, 91386830, 32975433, 32977654, 12764, "entier"], ["github/Python", "django/django", "Python", 2039134, 2045844, 32977669, 32984379, 384, "entier"], ["github/C", "curl/curl", "C", 91134080, 91134367, 32984394, 32984681, 12704, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42528719, 42530143, 32984696, 32986120, 5486, "entier"], ["github/Scala", "sbt/sbt", "Scala", 234668459, 234672830, 32986135, 32990506, 35200, "entier"], ["github/C", "curl/curl", "C", 92513214, 92514439, 32990521, 32991746, 12924, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179503096, 179505067, 32991761, 32993732, 24320, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 12602974, 12604343, 32993747, 32995116, 1869, "entier"], ["github/C", "curl/curl", "C", 97143971, 97145619, 32995131, 32996779, 13234, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53497851, 53504226, 32996794, 33003169, 8211, "entier"], ["github/Scala", "scala/scala", "Scala", 225455424, 225458449, 33003184, 33006209, 33151, "entier"], ["github/PHP", "laravel/framework", "PHP", 183570270, 183589679, 33006224, 33025633, 25260, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 65434837, 65440936, 33025648, 33031747, 10167, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170413350, 170432834, 33031762, 33051246, 22834, "entier"], ["github/Ruby", "rails/rails", "Ruby", 179387921, 179389854, 33051261, 33053194, 24288, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230033300, 230033712, 33053209, 33053621, 33991, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216862299, 216866992, 33053636, 33058329, 32169, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 14485000, 14491638, 33058344, 33064982, 2003, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43749267, 43749549, 33064997, 33065279, 6137, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88993027, 88998306, 33065294, 33070573, 12405, "entier"], ["github/C", "curl/curl", "C", 92578794, 92584240, 33070588, 33076034, 12933, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206060661, 206066761, 33076049, 33082149, 29808, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229326463, 229334325, 33082164, 33090026, 33794, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177550509, 177554371, 33090041, 33093903, 24023, "entier"], ["github/Python", "django/django", "Python", 6344373, 6345928, 33093918, 33095473, 1087, "entier"], ["github/Scala", "scala/scala", "Scala", 217402923, 217404130, 33095488, 33096695, 32222, "entier"], ["github/Scala", "playframework/playframework", "Scala", 233167134, 233167748, 33096710, 33097324, 34746, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174882577, 174882646, 33097339, 33097408, 23593, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196452106, 196453521, 33097423, 33098838, 27797, "entier"], ["github/Ruby", "jekyll/jekyll", "Ruby", 180528310, 180529584, 33098853, 33100127, 24508, "entier"], ["github/PHP", "laravel/framework", "PHP", 185766670, 185766983, 33100142, 33100455, 25679, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53271144, 53289067, 33100470, 33118393, 8184, "entier"], ["github/PHP", "symfony/symfony", "PHP", 196261866, 196262321, 33118408, 33118863, 27750, "entier"], ["github/Java", "apache/commons-lang", "Java", 155848250, 155870370, 33118878, 33140998, 20567, "entier"], ["github/PHP", "laravel/framework", "PHP", 181446613, 181447623, 33141013, 33142023, 24720, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 57529911, 57547802, 33142038, 33159929, 9125, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163493450, 163494042, 33159944, 33160536, 21717, "entier"], ["github/PHP", "laravel/framework", "PHP", 188722260, 188724184, 33160551, 33162475, 26350, "entier"], ["github/Python", "django/django", "Python", 4698983, 4712521, 33162490, 33176028, 817, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213194318, 213203374, 33176043, 33185099, 31538, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169215077, 169217093, 33185114, 33187130, 22751, "entier"], ["github/PHP", "laravel/framework", "PHP", 186612555, 186612932, 33187145, 33187522, 25946, "entier"], ["github/Scala", "scala/scala", "Scala", 218153354, 218165355, 33187537, 33199538, 32318, "entier"], ["github/PHP", "symfony/symfony", "PHP", 195249216, 195250423, 33199553, 33200760, 27580, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 167811130, 167815435, 33200775, 33205080, 22327, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192787971, 192794673, 33205095, 33211797, 27054, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56198780, 56201174, 33211812, 33214206, 8741, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21686043, 21694656, 33214221, 33222834, 2940, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200195120, 200196587, 33222849, 33224316, 28407, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 139203669, 139211223, 33224331, 33231885, 18286, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52531782, 52533138, 33231900, 33233256, 7947, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206217563, 206218250, 33233271, 33233958, 29879, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44103980, 44104564, 33233973, 33234557, 6217, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59328900, 59332982, 33234572, 33238654, 9373, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52964407, 52964448, 33238669, 33238710, 8086, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43530922, 43531083, 33238725, 33238886, 5893, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211519737, 211521546, 33238901, 33240710, 31264, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170687951, 170692882, 33240725, 33245656, 22872, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136554586, 136555917, 33245671, 33247002, 17643, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136316035, 136317406, 33247017, 33248388, 17463, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21926204, 21926893, 33248403, 33249092, 3028, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 38440260, 38444727, 33249107, 33253574, 4981, "entier"], ["github/C++", "nlohmann/json", "C++", 104132537, 104132960, 33253589, 33254012, 14406, "entier"], ["github/Ruby", "rails/rails", "Ruby", 175023719, 175038342, 33254027, 33268650, 23630, "entier"], ["github/C++", "fmtlib/fmt", "C++", 110002217, 110002359, 33268665, 33268807, 14775, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210042482, 210044122, 33268822, 33270462, 30835, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126646386, 126647740, 33270477, 33271831, 16180, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 60175500, 60178428, 33271846, 33274774, 9495, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229277708, 229292847, 33274789, 33289928, 33778, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 126619999, 126621836, 33289943, 33291780, 16165, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162594088, 162595487, 33291795, 33293194, 21566, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206257371, 206258675, 33293209, 33294513, 29897, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43697863, 43698845, 33294528, 33295510, 6094, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71320952, 71320953, 33295525, 33295526, 10615, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71318630, 71319794, 33295541, 33296705, 10612, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207123371, 207123603, 33296720, 33296952, 30094, "entier"], ["github/Swift", "Alamofire/Alamofire", "Swift", 214894003, 214897962, 33296967, 33300926, 31879, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44865844, 44867356, 33300941, 33302453, 6425, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210490066, 210491184, 33302468, 33303586, 31002, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71359175, 71360109, 33303601, 33304535, 10651, "entier"], ["github/Python", "django/django", "Python", 2608853, 2626194, 33304550, 33321891, 547, "entier"], ["github/C++", "opencv/opencv", "C++", 116923978, 116928476, 33321906, 33326404, 15396, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56013948, 56014671, 33326419, 33327142, 8661, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170630152, 170633113, 33327157, 33330118, 22863, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45001095, 45001292, 33330133, 33330330, 6558, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44929870, 44930188, 33330345, 33330663, 6475, "entier"], ["github/Java", "google/guava", "Java", 130639333, 130657093, 33330678, 33348438, 16754, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213034181, 213035665, 33348453, 33349937, 31506, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52431702, 52433740, 33349952, 33351990, 7912, "entier"], ["github/C++", "opencv/opencv", "C++", 116959273, 116961543, 33352005, 33354275, 15407, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168130734, 168132101, 33354290, 33355657, 22366, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51711925, 51714298, 33355672, 33358045, 7604, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160892439, 160893439, 33358060, 33359060, 21300, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207812820, 207816866, 33359075, 33363121, 30256, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238335595, 238340952, 33363136, 33368493, 36087, "entier"], ["github/PHP", "laravel/framework", "PHP", 188667908, 188694708, 33368508, 33395308, 26340, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143236549, 143238863, 33395323, 33397637, 19007, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206041295, 206042369, 33397652, 33398726, 29800, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144411557, 144413067, 33398741, 33400251, 19263, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51006153, 51014751, 33400266, 33408864, 7248, "entier"], ["github/Python", "django/django", "Python", 2322817, 2324463, 33408879, 33410525, 474, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141957636, 141958722, 33410540, 33411626, 18674, "entier"], ["github/Go", "gohugoio/hugo", "Go", 90879966, 90938120, 33411641, 33469795, 12667, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210040447, 210042467, 33469810, 33471830, 30834, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142043016, 142044776, 33471845, 33473605, 18729, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 120118261, 120137228, 33473620, 33492587, 15607, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230751765, 230759050, 33492602, 33499887, 34334, "entier"], ["github/Java", "apache/commons-lang", "Java", 152016294, 152019798, 33499902, 33503406, 20227, "entier"], ["github/Ruby", "rails/rails", "Ruby", 171860980, 171865161, 33503421, 33507602, 23072, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215809498, 215810059, 33507617, 33508178, 31964, "entier"], ["github/Python", "django/django", "Python", 3984755, 3991233, 33508193, 33514671, 719, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136633086, 136633981, 33514686, 33515581, 17699, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142776463, 142779478, 33515596, 33518611, 18912, "entier"], ["github/Scala", "scala/scala", "Scala", 221831362, 221832911, 33518626, 33520175, 32642, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236169366, 236171101, 33520190, 33521925, 35535, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234209743, 234212726, 33521940, 33524923, 35143, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46211549, 46221154, 33524938, 33534543, 6854, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174013528, 174014067, 33534558, 33535097, 23460, "entier"], ["github/Python", "django/django", "Python", 6302980, 6304422, 33535112, 33536554, 1075, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207567260, 207577218, 33536569, 33546527, 30176, "entier"], ["github/Scala", "sbt/sbt", "Scala", 235505844, 235507306, 33546542, 33548004, 35416, "entier"], ["github/C++", "nlohmann/json", "C++", 103929981, 103930745, 33548019, 33548783, 14166, "entier"], ["github/Java", "apache/commons-lang", "Java", 152125156, 152134523, 33548798, 33558165, 20243, "entier"], ["github/C++", "opencv/opencv", "C++", 112926792, 112927596, 33558180, 33558984, 15115, "entier"], ["github/C++", "nlohmann/json", "C++", 104070043, 104070915, 33558999, 33559871, 14324, "entier"], ["github/Scala", "playframework/playframework", "Scala", 230849399, 230853690, 33559886, 33564177, 34377, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54453496, 54453696, 33564192, 33564392, 8360, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177013913, 177018196, 33564407, 33568690, 23863, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55863563, 55863596, 33568705, 33568738, 8610, "entier"], ["github/PHP", "laravel/framework", "PHP", 181751656, 181758502, 33568753, 33575599, 24796, "entier"], ["github/C++", "nlohmann/json", "C++", 105391188, 105399524, 33575614, 33583950, 14517, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27159130, 27215222, 33583965, 33640057, 3594, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 143972597, 143979984, 33640072, 33647459, 19149, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43300929, 43305982, 33647474, 33652527, 5725, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 156966819, 156999049, 33652542, 33684772, 20629, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209962714, 209964092, 33684787, 33686165, 30800, "entier"], ["github/Ruby", "rails/rails", "Ruby", 177064452, 177064569, 33686180, 33686297, 23886, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 206098729, 206099644, 33686312, 33687227, 29831, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193051800, 193053041, 33687242, 33688483, 27094, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 59958023, 60011371, 33688498, 33741846, 9469, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44967216, 44968349, 33741861, 33742994, 6523, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190817662, 190818145, 33743009, 33743492, 26725, "entier"], ["github/Ruby", "rails/rails", "Ruby", 173180464, 173182338, 33743507, 33745381, 23354, "entier"], ["github/Scala", "playframework/playframework", "Scala", 231375126, 231388570, 33745396, 33758840, 34480, "entier"], ["github/PHP", "symfony/symfony", "PHP", 192972863, 192975121, 33758855, 33761113, 27065, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 123721705, 123728070, 33761128, 33767493, 15982, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51632197, 51635928, 33767508, 33771239, 7573, "entier"], ["github/PHP", "laravel/framework", "PHP", 185547262, 185547597, 33771254, 33771589, 25618, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 199996556, 200001975, 33771604, 33777023, 28306, "entier"], ["github/C", "curl/curl", "C", 96359367, 96433715, 33777038, 33851386, 13199, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42618758, 42619836, 33851401, 33852479, 5522, "entier"], ["github/Java", "square/okhttp", "Java", 146486851, 146505050, 33852494, 33870693, 19680, "entier"], ["github/C++", "opencv/opencv", "C++", 113537117, 113542302, 33870708, 33875893, 15143, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205186469, 205187936, 33875908, 33877375, 29553, "entier"], ["github/Ruby", "rails/rails", "Ruby", 178345541, 178352045, 33877390, 33883894, 24156, "entier"], ["github/C++", "nlohmann/json", "C++", 103995109, 103995744, 33883909, 33884544, 14235, "entier"], ["github/C++", "nlohmann/json", "C++", 104104086, 104104392, 33884559, 33884865, 14362, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211447156, 211448226, 33884880, 33885950, 31236, "entier"], ["github/PHP", "guzzle/guzzle", "PHP", 198346235, 198359150, 33885965, 33898880, 28168, "entier"], ["github/C++", "opencv/opencv", "C++", 115909636, 115911950, 33898895, 33901209, 15242, "entier"], ["github/Python", "django/django", "Python", 5794231, 5831299, 33901224, 33938292, 1000, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41574404, 41586771, 33938307, 33950674, 5290, "entier"], ["github/C++", "nlohmann/json", "C++", 103939226, 103939716, 33950689, 33951179, 14174, "entier"], ["github/Java", "square/okhttp", "Java", 148933850, 148936029, 33951194, 33953373, 19923, "entier"], ["github/Scala", "playframework/playframework", "Scala", 227805954, 227817824, 33953388, 33965258, 33538, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 138149537, 138149816, 33965273, 33965552, 18100, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 212539383, 212545025, 33965567, 33971209, 31439, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 140137467, 140144874, 33971224, 33978631, 18439, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88752356, 88753605, 33978646, 33979895, 12366, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52894762, 52896754, 33979910, 33981902, 8078, "entier"], ["github/Java", "square/okhttp", "Java", 146432909, 146437145, 33981917, 33986153, 19668, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209964107, 209967757, 33986168, 33989818, 30801, "entier"], ["github/Scala", "playframework/playframework", "Scala", 228141336, 228146198, 33989833, 33994695, 33576, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234030479, 234031285, 33994710, 33995516, 35034, "entier"], ["github/C++", "nlohmann/json", "C++", 105467868, 105494761, 33995531, 34022424, 14523, "entier"], ["github/Java", "google/guava", "Java", 135468123, 135472974, 34022439, 34027290, 17274, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202282647, 202284560, 34027305, 34029218, 28812, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 40786155, 40796506, 34029233, 34039584, 5208, "entier"], ["github/PHP", "symfony/symfony", "PHP", 190664239, 190679321, 34039599, 34054681, 26680, "entier"], ["github/Swift", "vapor/vapor", "Swift", 215977298, 215988647, 34054696, 34066045, 32006, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 157987280, 157999553, 34066060, 34078333, 20867, "entier"], ["github/Scala", "scala/scala", "Scala", 221580147, 221589921, 34078348, 34088122, 32581, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207411352, 207414941, 34088137, 34091726, 30129, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233997565, 233997685, 34091741, 34091861, 35012, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43751018, 43751844, 34091876, 34092702, 6140, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 204859283, 204859694, 34092717, 34093128, 29403, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 24998695, 25007499, 34093143, 34101947, 3238, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52821820, 52824068, 34101962, 34104210, 8034, "entier"], ["github/Go", "prometheus/prometheus", "Go", 80569618, 80592575, 34104225, 34127182, 11552, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211597011, 211598751, 34127197, 34128937, 31299, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238413626, 238413643, 34128952, 34128969, 36390, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238302894, 238302918, 34128984, 34129008, 35932, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47622125, 47622647, 34129023, 34129545, 7013, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236137074, 236138345, 34129560, 34130831, 35529, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 67845801, 67855844, 34130846, 34140889, 10404, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55997185, 55997883, 34140904, 34141602, 8651, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 234082590, 234083045, 34141617, 34142072, 35071, "entier"], ["github/PHP", "laravel/framework", "PHP", 185423114, 185424502, 34142087, 34143475, 25584, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 211426598, 211427667, 34143490, 34144559, 31217, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43620728, 43621419, 34144574, 34145265, 5998, "entier"], ["github/PHP", "laravel/framework", "PHP", 187925442, 187925520, 34145280, 34145358, 26194, "entier"], ["github/Python", "django/django", "Python", 8090541, 8097378, 34145373, 34152210, 1295, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 121035567, 121037331, 34152225, 34153989, 15689, "entier"], ["github/PHP", "laravel/framework", "PHP", 185573960, 185574727, 34154004, 34154771, 25633, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45121865, 45122781, 34154786, 34155702, 6626, "entier"], ["github/Scala", "playframework/playframework", "Scala", 226381283, 226385589, 34155717, 34160023, 33301, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 171006630, 171008681, 34160038, 34162089, 22899, "entier"], ["github/C++", "nlohmann/json", "C++", 103955874, 103956693, 34162104, 34162923, 14193, "entier"], ["github/Java", "square/okhttp", "Java", 145486682, 145519158, 34162938, 34195414, 19536, "entier"], ["github/PHP", "laravel/framework", "PHP", 182745222, 182747202, 34195429, 34197409, 25122, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 21901981, 21903431, 34197424, 34198874, 3014, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 123137027, 123138471, 34198889, 34200333, 15933, "entier"], ["github/PHP", "laravel/framework", "PHP", 182423335, 182423466, 34200348, 34200479, 24945, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 160862898, 160863617, 34200494, 34201213, 21279, "entier"], ["github/C++", "fmtlib/fmt", "C++", 109686069, 109686487, 34201228, 34201646, 14741, "entier"], ["github/PHP", "laravel/framework", "PHP", 185994394, 185994801, 34201661, 34202068, 25761, "entier"], ["github/C++", "nlohmann/json", "C++", 104122287, 104122836, 34202083, 34202632, 14391, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51265242, 51270641, 34202647, 34208046, 7323, "entier"], ["github/Scala", "playframework/playframework", "Scala", 229554326, 229556241, 34208061, 34209976, 33847, "entier"], ["github/Python", "django/django", "Python", 983606, 984534, 34209991, 34210919, 182, "entier"], ["github/C++", "fmtlib/fmt", "C++", 110029596, 110031416, 34210934, 34212754, 14782, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159251992, 159253697, 34212769, 34214474, 21103, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 25153051, 25157571, 34214489, 34219009, 3270, "entier"], ["github/C++", "nlohmann/json", "C++", 104034694, 104035250, 34219024, 34219580, 14279, "entier"], ["github/PHP", "laravel/framework", "PHP", 189231353, 189235179, 34219595, 34223421, 26430, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 58582601, 58585958, 34223436, 34226793, 9234, "entier"], ["github/PHP", "laravel/framework", "PHP", 186612947, 186613326, 34226808, 34227187, 25947, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193080003, 193080778, 34227202, 34227977, 27121, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 55842016, 55846751, 34227992, 34232727, 8604, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213163126, 213175586, 34232742, 34245202, 31532, "entier"], ["github/JavaScript", "axios/axios", "JavaScript", 27312880, 27315741, 34245217, 34248078, 3627, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193189301, 193190472, 34248093, 34249264, 27149, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163021899, 163029429, 34249279, 34256809, 21653, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51316471, 51316725, 34256824, 34257078, 7427, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51957153, 51958700, 34257093, 34258640, 7687, "entier"], ["github/Scala", "playframework/playframework", "Scala", 232349443, 232365129, 34258655, 34274341, 34635, "entier"], ["github/Java", "google/guava", "Java", 128861825, 128864416, 34274356, 34276947, 16536, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28343109, 28348770, 34276962, 34282623, 3876, "entier"], ["github/PHP", "laravel/framework", "PHP", 186951341, 186958435, 34282638, 34289732, 26014, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42777765, 42781066, 34289747, 34293048, 5612, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137629195, 137630224, 34293063, 34294092, 17970, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78370935, 78377523, 34294107, 34300695, 11409, "entier"], ["github/Python", "django/django", "Python", 7330059, 7349941, 34300710, 34320592, 1226, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56286563, 56288261, 34320607, 34322305, 8830, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163544936, 163546907, 34322320, 34324291, 21737, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 142266343, 142273012, 34324306, 34330975, 18816, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 53052349, 53053454, 34330990, 34332095, 8115, "entier"], ["github/PHP", "laravel/framework", "PHP", 189351262, 189353741, 34332110, 34334589, 26449, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 56381251, 56381710, 34334604, 34335063, 8958, "entier"], ["github/Scala", "sbt/sbt", "Scala", 238425382, 238425414, 34335078, 34335110, 36528, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 163445882, 163448148, 34335125, 34337391, 21710, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 206012848, 206016639, 34337406, 34341197, 29785, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 136474818, 136475559, 34341212, 34341953, 17578, "entier"], ["github/PHP", "laravel/framework", "PHP", 182563059, 182563207, 34341968, 34342116, 25032, "entier"], ["github/PHP", "laravel/framework", "PHP", 187031639, 187032040, 34342131, 34342532, 26051, "entier"], ["github/Java", "apache/commons-lang", "Java", 150701823, 150703124, 34342547, 34343848, 20106, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89434306, 89436700, 34343863, 34346257, 12475, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 37272718, 37276519, 34346272, 34350073, 4763, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162902827, 162903462, 34350088, 34350723, 21639, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137959432, 137961943, 34350738, 34353249, 18045, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 202289069, 202289619, 34353264, 34353814, 28817, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45934096, 45935858, 34353829, 34355591, 6803, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 169683341, 169686516, 34355606, 34358781, 22770, "entier"], ["github/Go", "gohugoio/hugo", "Go", 88708586, 88712226, 34358796, 34362436, 12353, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 213389060, 213390899, 34362451, 34364290, 31581, "entier"], ["github/Java", "square/okhttp", "Java", 145952043, 145959557, 34364305, 34371819, 19598, "entier"], ["github/PHP", "symfony/symfony", "PHP", 198074353, 198084352, 34371834, 34381833, 28119, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 42312068, 42316350, 34381848, 34386130, 5406, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28904718, 28924699, 34386145, 34406126, 3951, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 164509563, 164511700, 34406141, 34408278, 21921, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 11006039, 11008213, 34408293, 34410467, 1773, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65244951, 65282912, 34410482, 34448443, 10031, "entier"], ["github/Java", "square/okhttp", "Java", 148977120, 148979058, 34448458, 34450396, 19939, "entier"], ["github/Go", "gohugoio/hugo", "Go", 85459243, 85462740, 34450411, 34453908, 11948, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44474040, 44475525, 34453923, 34455408, 6314, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141714601, 141717447, 34455423, 34458269, 18601, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52825937, 52825981, 34458284, 34458328, 8037, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 158933405, 158936133, 34458343, 34461071, 21037, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207080010, 207087500, 34461086, 34468576, 30076, "entier"], ["github/Python", "django/django", "Python", 1976641, 1980656, 34468591, 34472606, 375, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44952390, 44953403, 34472621, 34473634, 6506, "entier"], ["github/C", "curl/curl", "C", 98779406, 98784505, 34473649, 34478748, 13566, "entier"], ["github/Java", "apache/commons-lang", "Java", 154200400, 154201702, 34478763, 34480065, 20365, "entier"], ["github/Java", "apache/commons-lang", "Java", 154664085, 154665343, 34480080, 34481338, 20424, "entier"], ["github/PHP", "laravel/framework", "PHP", 182827609, 182830342, 34481353, 34484086, 25144, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 43376116, 43380441, 34484101, 34488426, 5788, "entier"], ["github/Go", "gohugoio/hugo", "Go", 89076437, 89081210, 34488441, 34493214, 12418, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165687322, 165690177, 34493229, 34496084, 22119, "entier"], ["github/Java", "square/okhttp", "Java", 149009156, 149013469, 34496099, 34500412, 19951, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233701534, 233705339, 34500427, 34504232, 34913, "entier"], ["github/PHP", "laravel/framework", "PHP", 184870048, 184872105, 34504247, 34506304, 25435, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 54445663, 54446572, 34506319, 34507228, 8342, "entier"], ["github/PHP", "laravel/framework", "PHP", 186603645, 186604126, 34507243, 34507724, 25927, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159208848, 159209953, 34507739, 34508844, 21090, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51061751, 51063286, 34508859, 34510394, 7261, "entier"], ["github/C", "libuv/libuv", "C", 101601300, 101604184, 34510409, 34513293, 13916, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162690384, 162690517, 34513308, 34513441, 21591, "entier"], ["github/Ruby", "rails/rails", "Ruby", 174041765, 174099177, 34513456, 34570868, 23464, "entier"], ["github/PHP", "laravel/framework", "PHP", 183026749, 183028713, 34570883, 34572847, 25204, "entier"], ["github/Python", "django/django", "Python", 4030792, 4039661, 34572862, 34581731, 727, "entier"], ["github/Go", "prometheus/prometheus", "Go", 78219264, 78222185, 34581746, 34584667, 11380, "entier"], ["github/C++", "fmtlib/fmt", "C++", 109179560, 109259405, 34584682, 34664527, 14715, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 44123971, 44126078, 34664542, 34666649, 6230, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 20990940, 20993633, 34666664, 34669357, 2854, "entier"], ["github/Java", "square/okhttp", "Java", 145784340, 145794891, 34669372, 34679923, 19586, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159315145, 159319631, 34679938, 34684424, 21110, "entier"], ["github/C", "libuv/libuv", "C", 101002815, 101005233, 34684439, 34686857, 13842, "entier"], ["github/TypeScript", "vuejs/core", "TypeScript", 41730636, 41733892, 34686872, 34690128, 5307, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 27059124, 27062101, 34690143, 34693120, 3554, "entier"], ["github/Python", "django/django", "Python", 5080096, 5081162, 34693135, 34694201, 896, "entier"], ["github/Java", "google/guava", "Java", 132756005, 132757654, 34694216, 34695865, 17011, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 159245551, 159246380, 34695880, 34696709, 21098, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47193698, 47195192, 34696724, 34698218, 6966, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137460996, 137461272, 34698233, 34698509, 17932, "entier"], ["github/Go", "gohugoio/hugo", "Go", 91120703, 91128588, 34698524, 34706409, 12697, "entier"], ["github/Java", "google/guava", "Java", 132745724, 132747521, 34706424, 34708221, 17007, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52041644, 52043375, 34708236, 34709967, 7737, "entier"], ["github/C", "curl/curl", "C", 98429272, 98432112, 34709982, 34712822, 13452, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214168384, 214183174, 34712837, 34727627, 31772, "entier"], ["github/Python", "django/django", "Python", 3207239, 3211125, 34727642, 34731528, 613, "entier"], ["github/Java", "apache/commons-lang", "Java", 149114806, 149119950, 34731543, 34736687, 19985, "entier"], ["github/Swift", "vapor/vapor", "Swift", 216502564, 216507623, 34736702, 34741761, 32130, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 46044459, 46047237, 34741776, 34744554, 6835, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165949433, 165955294, 34744569, 34750430, 22194, "entier"], ["github/Python", "django/django", "Python", 6009613, 6011339, 34750445, 34752171, 1022, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61185783, 61186972, 34752186, 34753375, 9575, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 33970486, 33981487, 34753390, 34764391, 4364, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 42967416, 42969437, 34764406, 34766427, 5673, "entier"], ["github/Go", "prometheus/prometheus", "Go", 80521368, 80522913, 34766442, 34767987, 11549, "entier"], ["github/PHP", "symfony/symfony", "PHP", 193152382, 193175452, 34768002, 34791072, 27143, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 52279221, 52279258, 34791087, 34791124, 7869, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45440530, 45443506, 34791139, 34794115, 6738, "entier"], ["github/C#", "dotnet/aspnetcore", "C#", 162315006, 162318229, 34794130, 34797353, 21506, "entier"], ["github/TypeScript", "nestjs/nest", "TypeScript", 51735187, 51736173, 34797368, 34798354, 7612, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 69157555, 69167539, 34798369, 34808353, 10476, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205965405, 205966343, 34808368, 34809306, 29763, "entier"], ["github/Scala", "sbt/sbt", "Scala", 236006096, 236086312, 34809321, 34889537, 35516, "entier"], ["github/Go", "prometheus/prometheus", "Go", 76463741, 76473227, 34889552, 34899038, 11237, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 144338324, 144362511, 34899053, 34923240, 19243, "entier"], ["github/Python", "encode/httpx", "Python", 17858156, 17873154, 34923255, 34938253, 2155, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207138909, 207141072, 34938268, 34940431, 30101, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 36376368, 36384289, 34940446, 34948367, 4683, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 207124552, 207125354, 34948382, 34949184, 30096, "entier"], ["github/Rust", "BurntSushi/ripgrep", "Rust", 56530544, 56534808, 34949199, 34953463, 9070, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47264512, 47280121, 34953478, 34969087, 6980, "entier"], ["github/PHP", "laravel/framework", "PHP", 186468980, 186469320, 34969102, 34969442, 25882, "entier"], ["github/C", "curl/curl", "C", 95376956, 95397241, 34969457, 34989742, 13146, "entier"], ["github/Go", "gin-gonic/gin", "Go", 75231531, 75234531, 34989757, 34992757, 11122, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 170658949, 170671799, 34992772, 35005622, 22869, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28397236, 28398571, 35005637, 35006972, 3893, "entier"], ["github/PHP", "laravel/framework", "PHP", 187048738, 187051435, 35006987, 35009684, 26055, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 214153321, 214160183, 35009699, 35016561, 31768, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 68463204, 68465415, 35016576, 35018787, 10445, "entier"], ["github/Go", "prometheus/prometheus", "Go", 79697182, 79697939, 35018802, 35019559, 11500, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 64286483, 64287057, 35019574, 35020148, 9959, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141907623, 141912263, 35020163, 35024803, 18647, "entier"], ["github/Rust", "serde-rs/serde", "Rust", 65396183, 65396319, 35024818, 35024954, 10081, "entier"], ["github/Rust", "rust-lang/cargo", "Rust", 71427152, 71427458, 35024969, 35025275, 10712, "entier"], ["github/JavaScript", "webpack/webpack", "JavaScript", 26367252, 26372461, 35025290, 35030499, 3412, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233754456, 233754716, 35030514, 35030774, 34929, "entier"], ["github/Python", "django/django", "Python", 5472177, 5477121, 35030789, 35035733, 926, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 137682742, 137682900, 35035748, 35035906, 17984, "entier"], ["github/Java", "apache/commons-lang", "Java", 150703139, 150704454, 35035921, 35037236, 20107, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 47969311, 47971146, 35037251, 35039086, 7077, "entier"], ["github/C++", "nlohmann/json", "C++", 104075160, 104075555, 35039101, 35039496, 14333, "entier"], ["github/Python", "django/django", "Python", 1657260, 1657439, 35039511, 35039690, 301, "entier"], ["github/Python", "django/django", "Python", 1328565, 1329339, 35039705, 35040479, 231, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 208634789, 208637464, 35040494, 35043169, 30445, "entier"], ["github/Python", "django/django", "Python", 5007693, 5007741, 35043184, 35043232, 877, "entier"], ["github/PHP", "symfony/symfony", "PHP", 194888417, 194900115, 35043247, 35054945, 27499, "entier"], ["github/TypeScript", "angular/angular", "TypeScript", 45096181, 45096762, 35054960, 35055541, 6610, "entier"], ["github/C++", "opencv/opencv", "C++", 117072613, 117075564, 35055556, 35058507, 15422, "entier"], ["github/Python", "scikit-learn/scikit-learn", "Python", 12206237, 12207824, 35058522, 35060109, 1847, "entier"], ["github/Rust", "tokio-rs/tokio", "Rust", 61591720, 61602703, 35060124, 35071107, 9625, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 168256615, 168258309, 35071122, 35072816, 22424, "entier"], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 200014564, 200015245, 35072831, 35073512, 28312, "entier"], ["github/Java", "spring-projects/spring-framework", "Java", 141682072, 141697645, 35073527, 35089100, 18598, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 209521072, 209521961, 35089115, 35090004, 30651, "entier"], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 28950948, 28959456, 35090019, 35098527, 3953, "entier"], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 205054202, 205054615, 35098542, 35098955, 29511, "entier"], ["github/Python", "django/django", "Python", 1597708, 1602036, 35098970, 35103298, 280, "entier"], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 165584719, 165587298, 35103313, 35105892, 22081, "entier"], ["github/TypeScript", "microsoft/vscode", "TypeScript", 36794262, 36802702, 35105907, 35114347, 4738, "entier"], ["github/Kotlin", "ktorio/ktor", "Kotlin", 210059265, 210060008, 35114362, 35115105, 30849, "entier"], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 233880739, 233881601, 35115120, 35115982, 34938, "entier"], ["github/C++", "protocolbuffers/protobuf", "C++", 124807165, 124820119, 35115997, 35128951, 16035, "tete_12954_de_28117"]]
\ No newline at end of file
diff --git a/results/hashing/m8_ml1/sample/ml1_sample_manifest.json b/results/hashing/m8_ml1/sample/ml1_sample_manifest.json
new file mode 100644
index 0000000000000000000000000000000000000000..346f59911b68ada2a856fc25374e3893b9ecdfb1
--- /dev/null
+++ b/results/hashing/m8_ml1/sample/ml1_sample_manifest.json
@@ -0,0 +1,294 @@
+{
+ "author": "SPIRA Hashing",
+ "script": "/workspace/spira_shared/hashing_gen/m8_ml1/code/make_sample_ml1.py",
+ "script_sha256": "75c237d285db800a807db6420fe5aa3a09f95c483b15261b1efc21b3aa9238c0",
+ "method_ref": {
+ "make_sample_v1b.py": "b9a72c14958e82db7585d50aa7e1c0de5e927e9171b3bc64482157fe003db595",
+ "make_sample_cs1.py (taille exacte)": "3b3637679042898896eec10bc3363f9ca801434ad9bd35a056fa591d33bb55d0"
+ },
+ "source": {
+ "path": "/workspace/spira_shared/multi_lang_v1/train.bin",
+ "bytes": 239327199,
+ "sha256": "feef51d5f72cfa4345867005f0a044c852e3453ad9b7cb3bd015729d02ee2363",
+ "build_stage1_sha256": "9c1f250db5fa09e2133fad42be0cba64499fde9f223fd6090ad9bee396611c42",
+ "files": 36910,
+ "doc_bytes": 238773564
+ },
+ "seed": 20261024,
+ "target_bytes": 35128951,
+ "adjust": {
+ "natural_bytes": 35292906,
+ "excess_bytes": 163955,
+ "dropped_whole_docs_at_end": 56,
+ "filler": {
+ "stratum": "github/C++",
+ "doc_id": 16035,
+ "repo": "protocolbuffers/protobuf",
+ "head_bytes": 12954,
+ "doc_bytes": 28117
+ }
+ },
+ "sample": {
+ "path": "/workspace/spira_shared/hashing_gen/m8_ml1/sample/ml1_sample.bin",
+ "bytes": 35128951,
+ "sha256": "a7ffb34f099f32430a011872bda22b8eb0167db57ace02961383e739b422a678",
+ "n_docs": 5438
+ },
+ "strata": {
+ "github/C": {
+ "pool_doc_bytes": 12733317,
+ "pool_docs": 1440,
+ "target_bytes": 1873357,
+ "taken_bytes": 1865694,
+ "taken_docs": 195,
+ "share_pool": 0.0533280015873114,
+ "stratum_seed": 14283510491181467334
+ },
+ "github/C#": {
+ "pool_doc_bytes": 15067399,
+ "pool_docs": 2346,
+ "target_bytes": 2216753,
+ "taken_bytes": 2205823,
+ "taken_docs": 358,
+ "share_pool": 0.06310329647715943,
+ "stratum_seed": 7737383756452390325
+ },
+ "github/C++": {
+ "pool_doc_bytes": 23817694,
+ "pool_docs": 2142,
+ "target_bytes": 3504117,
+ "taken_bytes": 3481723,
+ "taken_docs": 298,
+ "share_pool": 0.09975012979242542,
+ "stratum_seed": 7608485171363292603
+ },
+ "github/Go": {
+ "pool_doc_bytes": 16196854,
+ "pool_docs": 1619,
+ "target_bytes": 2382921,
+ "taken_bytes": 2370351,
+ "taken_docs": 208,
+ "share_pool": 0.0678335311860571,
+ "stratum_seed": 17824132401647747497
+ },
+ "github/Java": {
+ "pool_doc_bytes": 28602620,
+ "pool_docs": 4320,
+ "target_bytes": 4208087,
+ "taken_bytes": 4188592,
+ "taken_docs": 671,
+ "share_pool": 0.11978972680576984,
+ "stratum_seed": 12360241391214572767
+ },
+ "github/JavaScript": {
+ "pool_doc_bytes": 18386958,
+ "pool_docs": 2514,
+ "target_bytes": 2705134,
+ "taken_bytes": 2691800,
+ "taken_docs": 373,
+ "share_pool": 0.07700583637475043,
+ "stratum_seed": 572986652431508505
+ },
+ "github/Kotlin": {
+ "pool_doc_bytes": 14474338,
+ "pool_docs": 3571,
+ "target_bytes": 2129500,
+ "taken_bytes": 2117402,
+ "taken_docs": 501,
+ "share_pool": 0.06061951648885217,
+ "stratum_seed": 2144189299031221718
+ },
+ "github/PHP": {
+ "pool_doc_bytes": 18564115,
+ "pool_docs": 3599,
+ "target_bytes": 2731198,
+ "taken_bytes": 2716343,
+ "taken_docs": 577,
+ "share_pool": 0.07774778199482753,
+ "stratum_seed": 7404096481332877269
+ },
+ "github/Python": {
+ "pool_doc_bytes": 18063016,
+ "pool_docs": 2186,
+ "target_bytes": 2657475,
+ "taken_bytes": 2646008,
+ "taken_docs": 407,
+ "share_pool": 0.07564914514573313,
+ "stratum_seed": 7560286162629868552
+ },
+ "github/Ruby": {
+ "pool_doc_bytes": 9780569,
+ "pool_docs": 1727,
+ "target_bytes": 1438941,
+ "taken_bytes": 1459597,
+ "taken_docs": 269,
+ "share_pool": 0.040961691219719785,
+ "stratum_seed": 13915400743702225250
+ },
+ "github/Rust": {
+ "pool_doc_bytes": 18371402,
+ "pool_docs": 2013,
+ "target_bytes": 2702846,
+ "taken_bytes": 2693147,
+ "taken_docs": 294,
+ "share_pool": 0.07694068678390209,
+ "stratum_seed": 11215015281825474505
+ },
+ "github/Scala": {
+ "pool_doc_bytes": 20768508,
+ "pool_docs": 4326,
+ "target_bytes": 3055514,
+ "taken_bytes": 3089660,
+ "taken_docs": 558,
+ "share_pool": 0.08697993049180268,
+ "stratum_seed": 9435559635142962257
+ },
+ "github/Shell": {
+ "pool_doc_bytes": 1170475,
+ "pool_docs": 381,
+ "target_bytes": 172203,
+ "taken_bytes": 171858,
+ "taken_docs": 71,
+ "share_pool": 0.004902029271548671,
+ "stratum_seed": 8982329160359006428
+ },
+ "github/Swift": {
+ "pool_doc_bytes": 2856150,
+ "pool_docs": 359,
+ "target_bytes": 420204,
+ "taken_bytes": 417506,
+ "taken_docs": 55,
+ "share_pool": 0.011961751343628644,
+ "stratum_seed": 16332281041098519257
+ },
+ "github/TypeScript": {
+ "pool_doc_bytes": 19920149,
+ "pool_docs": 4367,
+ "target_bytes": 2930701,
+ "taken_bytes": 2918938,
+ "taken_docs": 602,
+ "share_pool": 0.08342694503651166,
+ "stratum_seed": 15714588800719988091
+ }
+ },
+ "prefix_composition": {
+ "60000": {
+ "github/C": 0.0652,
+ "github/C#": 0.0566,
+ "github/C++": 0.076,
+ "github/Go": 0.1087,
+ "github/Java": 0.1514,
+ "github/JavaScript": 0.0343,
+ "github/Kotlin": 0.023,
+ "github/PHP": 0.1025,
+ "github/Python": 0.1092,
+ "github/Ruby": 0.0029,
+ "github/Rust": 0.0047,
+ "github/Scala": 0.1109,
+ "github/TypeScript": 0.1546
+ },
+ "200000": {
+ "github/C": 0.0521,
+ "github/C#": 0.081,
+ "github/C++": 0.0664,
+ "github/Go": 0.0577,
+ "github/Java": 0.1784,
+ "github/JavaScript": 0.0724,
+ "github/Kotlin": 0.0699,
+ "github/PHP": 0.0651,
+ "github/Python": 0.0327,
+ "github/Ruby": 0.0388,
+ "github/Rust": 0.0799,
+ "github/Scala": 0.1465,
+ "github/TypeScript": 0.0591
+ },
+ "2000000": {
+ "github/C": 0.0507,
+ "github/C#": 0.0575,
+ "github/C++": 0.0981,
+ "github/Go": 0.0593,
+ "github/Java": 0.1178,
+ "github/JavaScript": 0.0662,
+ "github/Kotlin": 0.0901,
+ "github/PHP": 0.0731,
+ "github/Python": 0.0727,
+ "github/Ruby": 0.0531,
+ "github/Rust": 0.0733,
+ "github/Scala": 0.0884,
+ "github/Shell": 0.0049,
+ "github/Swift": 0.0129,
+ "github/TypeScript": 0.082
+ },
+ "2400000": {
+ "github/C": 0.051,
+ "github/C#": 0.0584,
+ "github/C++": 0.0906,
+ "github/Go": 0.0494,
+ "github/Java": 0.1166,
+ "github/JavaScript": 0.0825,
+ "github/Kotlin": 0.0751,
+ "github/PHP": 0.0763,
+ "github/Python": 0.0811,
+ "github/Ruby": 0.0442,
+ "github/Rust": 0.0671,
+ "github/Scala": 0.0847,
+ "github/Shell": 0.0048,
+ "github/Swift": 0.0117,
+ "github/TypeScript": 0.1064
+ },
+ "2800000": {
+ "github/C": 0.0507,
+ "github/C#": 0.06,
+ "github/C++": 0.1009,
+ "github/Go": 0.073,
+ "github/Java": 0.1145,
+ "github/JavaScript": 0.0809,
+ "github/Kotlin": 0.0644,
+ "github/PHP": 0.076,
+ "github/Python": 0.0742,
+ "github/Ruby": 0.0396,
+ "github/Rust": 0.076,
+ "github/Scala": 0.0841,
+ "github/Shell": 0.0044,
+ "github/Swift": 0.0101,
+ "github/TypeScript": 0.0912
+ },
+ "5600000": {
+ "github/C": 0.0557,
+ "github/C#": 0.0625,
+ "github/C++": 0.0999,
+ "github/Go": 0.0703,
+ "github/Java": 0.1214,
+ "github/JavaScript": 0.0765,
+ "github/Kotlin": 0.061,
+ "github/PHP": 0.0786,
+ "github/Python": 0.0763,
+ "github/Ruby": 0.0426,
+ "github/Rust": 0.0773,
+ "github/Scala": 0.0793,
+ "github/Shell": 0.0036,
+ "github/Swift": 0.0124,
+ "github/TypeScript": 0.0827
+ },
+ "35128951": {
+ "github/C": 0.0532,
+ "github/C#": 0.0629,
+ "github/C++": 0.0997,
+ "github/Go": 0.0676,
+ "github/Java": 0.1195,
+ "github/JavaScript": 0.0768,
+ "github/Kotlin": 0.0604,
+ "github/PHP": 0.0775,
+ "github/Python": 0.0755,
+ "github/Ruby": 0.0416,
+ "github/Rust": 0.0768,
+ "github/Scala": 0.0882,
+ "github/Shell": 0.0049,
+ "github/Swift": 0.0119,
+ "github/TypeScript": 0.0833
+ }
+ },
+ "docs_file": "/workspace/spira_shared/hashing_gen/m8_ml1/sample/ml1_sample_docs.json",
+ "peak_rss_MB": 274,
+ "elapsed_s": 0.5
+}
\ No newline at end of file
diff --git a/results/hashing/m8_ml1/sample/rerun_check_sha.txt b/results/hashing/m8_ml1/sample/rerun_check_sha.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ce441072cff32a07930895d4b1374a2ec3b0c507
--- /dev/null
+++ b/results/hashing/m8_ml1/sample/rerun_check_sha.txt
@@ -0,0 +1,2 @@
+a7ffb34f099f32430a011872bda22b8eb0167db57ace02961383e739b422a678 sample/ml1_sample.bin
+a7ffb34f099f32430a011872bda22b8eb0167db57ace02961383e739b422a678 tmp/rerun/ml1_sample.bin
diff --git a/results/hashing/m8_ml1/step1/overlap_step1.json b/results/hashing/m8_ml1/step1/overlap_step1.json
new file mode 100644
index 0000000000000000000000000000000000000000..308125db4ce34ac078edc0578764b12a084840b3
--- /dev/null
+++ b/results/hashing/m8_ml1/step1/overlap_step1.json
@@ -0,0 +1,32 @@
+{
+ "multi_lang_v1": {
+ "bytes": 239327199,
+ "sha256": "feef51d5f72cfa4345867005f0a044c852e3453ad9b7cb3bd015729d02ee2363",
+ "files": 36910,
+ "content_bytes": 238773564,
+ "dup_files_within": 0
+ },
+ "v1b_segment": {
+ "range": [
+ 281458684,
+ 520785883
+ ],
+ "sha256": "feef51d5f72cfa4345867005f0a044c852e3453ad9b7cb3bd015729d02ee2363",
+ "byte_equal_to_multi_lang_v1": true,
+ "share_of_v1b_bytes": 0.4595500892254408
+ },
+ "code_scale_v1_train": {
+ "files_index_rows": 94262,
+ "ml1_files_identical": 34285,
+ "ml1_bytes_identical": 218904510,
+ "share_files": 0.9288810620428068,
+ "share_bytes": 0.9167870443145038
+ },
+ "code_scale_v1_delta": {
+ "files": 59977,
+ "ml1_files_identical": 0,
+ "ml1_bytes_identical": 0
+ },
+ "peak_rss_MB": 293,
+ "elapsed_s": 2.3
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/GO_CHECKER_PASS b/results/hashing/m8_v1b/GO_CHECKER_PASS
new file mode 100644
index 0000000000000000000000000000000000000000..a7fc875b8ef86b013bdece667313c90df4315355
--- /dev/null
+++ b/results/hashing/m8_v1b/GO_CHECKER_PASS
@@ -0,0 +1,43 @@
+# GO_CHECKER_PASS — M8 v1b — posé à la main par SPIRA Hashing le 2026-10-24 13:05:24 EDT
+
+## Décision écrite de Philippe-Antoine, 24 oct, 13 h 00 (Toronto), mot pour mot
+« on fige la règle B pour M8 v1b (recommandée par Checker). Procède avec ça. Continue code_scale_v1 et le reste vers la généralisation. Push les artefacts validés. »
+(Plage fusion.scale [0,03 ; 0,11] non tranchée : PROVISOIRE, en dur.)
+
+## 1) Checker — recompte 64 o corpus_diverse_v1b : PASS (spira_relay.md l. 7465-7466, entrée « SPIRA Checker — 11 h 41 (Toronto) »)
+### SPIRA Checker — 11 h 41 (Toronto) — réponse Relay 11 h 36 / Hashing 11 h 35
+- **1) Recompte indépendant 64 o corpus_diverse_v1b : PASS — validé par Checker.**
+ - train.bin 520 785 883 o (taille disque = octets lus), sha256 recalculé ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3 ✔ ; manifest_corpus_diverse_v1b.json 269 579 o, sha256 cb6398ca62f8f0003afd4d5505d59ecea7a8a13814091b358d93368c14f2494f ✔ ; le manifest décrit bien ce train.bin (path = hashing_gen/corpus_v1b/train.bin, output.bytes 520 785 883, output.sha256 ddf67ffb… identiques) ✔.
+
+## 2) Checker — PASS d'audit du brouillon r3B (spira_relay.md l. 7917-7923, « PASS d'audit — Checker — 13 h 01 »)
+### PASS d'audit — Checker — 13 h 01
+- verdict_M8v1b_r3B_DRAFT.py sha256 cb27a4a57e1d97456ef7a2691ba6a7a64a3a6ac026798900f34533c580ed4f93 : **PASS d'audit (validé par Checker)**. Pré-audit fait à 12 h 53 (checker/recount/preaudit_r3_1252/).
+ - Contrôles : bornes en dur, refus de --scale-hi/--scale-lo (rc 2), smoke NON MESURABLE identique, tests synthétiques B ADOPTÉ / NON MESURABLE / REJETÉ conformes.
+- Hashing : figer CE fichier, octet pour octet, comme code/verdict_M8v1b.py (r3). Seule retouche tolérée : la docstring l.13 (« défauts ajustables »). Si elle est modifiée, publier le nouveau sha256 complet : je ne vérifierai que ce diff.
+- Mettre à jour PREDECL.md §6 (règle B + bornes) avant tout résultat dans runs/. GO_CHECKER_PASS peut être posé dès que le sha256 figé = cb27a4a5… ou que le diff docstring seul est validé.
+- Push HF du r3 figé : PASS, après le gel. train_m8v1b.py b2b12c8c… : déjà PASS.
+Lu/appliqué — Checker — 13 h 01
+
+## 3) Checker — PASS d'audit de GEL r3B (spira_relay.md l. 7951-7960, « Audit de gel r3 — PASS — Checker — 13 h 04 »)
+### Audit de gel r3 — PASS — Checker — 13 h 04 (heure de Toronto)
+- **code/verdict_M8v1b.py figé : sha256 b3db0875b6e01d2c2192d9e307d337a3fb908f524f7be5e3a9a5b380eec7d7dc, 17 727 o** (gel détecté à 13 h 02 ; r2 aa66889b… remplacée).
+- diff contre le brouillon r3B pré-audité (cb27a4a57e1d97456ef7a2691ba6a7a64a3a6ac026798900f34533c580ed4f93, 17 638 o) : **une seule ligne, l. 13, dans la docstring** (l. 2-17). Le texte « BROUILLON r3-B (NON FIGÉ) … défaut 0,03/0,11 » devient « Révision 3-B (figée …) … bornes en dur [0,03 ; 0,11] ». **Aucune ligne de code modifiée.** Ce diff concorde avec code/drafts_r3/r3B_FROZEN_vs_cb27a4a5.diff (5669789b627d7907b0721b7826676e3432de3b9a80ed89b38e6b6a1da8c44af7).
+- grep : l. 21 « SCALE_LO = 0.03; SCALE_HI = 0.11 » est en dur. Seuls les arguments --runs et --outdir existent. --scale-lo et --scale-hi sont refusés par argparse (rc 2, vérifié sur une copie). l. 142 : « dec = "ADOPTÉ" if (GF and not L) else "REJETÉ" ».
+- test20k : le script de verdict ne lit pas la fenêtre ; il exige que window_sha256 = recompte = masque. Les évaluateurs (train_m8v1b.py l. 113, smoke_evalonly.py l. 18) lisent spira_m7/windows/test20k.bin. Ce fichier n'est pas un lien, mais une copie octet pour octet de broad/old_local_v1/test.bin : tous deux font 319 940 o et ont le sha256 **ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22**. Les sorties donnent aussi window_sha256 test20k = ce0526c6…a6b22.
+- hashing_gen/m8_v1b/runs/ : **vide** au moment de l'audit (ls -A, aucun résultat d'éval). GO_CHECKER_PASS : absent.
+- PREDECL.md §10 (révision 13 h 03) remplace explicitement §6 et §8. Il énonce la **règle B** (gain significatif sur au moins 1 fraîche valide, aucune perte significative, gain sur seen non exigé) et **fusion.scale hors [0,03 ; 0,11] ⇒ NON MESURABLE**, en dur. Il cite le sha figé b3db0875…. Remarque non bloquante : l'ancien texte de §6 (gain sur seen exigé) est resté en place, barré seulement par §10. Le commentaire l. 21 dit encore « plage PROVISOIRE, en attente de la décision ». C'est un commentaire, pas du code, et c'est cohérent avec §10 (plage non tranchée).
+- Rejeu d'une COPIE (sha b3db0875…) sur smoke vtest et vtest2 (checker/recount/m8v1b_freeze_audit_1303/) : **NON MESURABLE** dans les deux cas, avec les mêmes motifs. Par fenêtre, md, log et json sont **identiques** aux sorties du pré-audit preaudit_r3_1252/B. Seule différence : la ligne script_sha256 (cb27a4a5… → b3db0875…), ce qui est attendu.
+- **Verdict : PASS d'audit de gel (validé par Checker) pour b3db0875b6e01d2c2192d9e307d337a3fb908f524f7be5e3a9a5b380eec7d7dc. Hashing peut poser GO_CHECKER_PASS.** Checker ne l'a pas posé. La porte 218845 et gate_m8v1b.sh (d8287108…, inchangé) n'ont pas été touchées.
+Lu/appliqué — Checker — 13 h 04
+
+## sha256 (vérifiés au moment de la pose)
+b3db0875b6e01d2c2192d9e307d337a3fb908f524f7be5e3a9a5b380eec7d7dc hashing_gen/m8_v1b/code/verdict_M8v1b.py
+aa66889b53e9566bedebd1e66679ed2c08b07f1fecff7d9a2e79d2e42a9fa8d3 hashing_gen/m8_v1b/code/verdict_M8v1b.r2.py
+cb27a4a57e1d97456ef7a2691ba6a7a64a3a6ac026798900f34533c580ed4f93 hashing_gen/m8_v1b/code/drafts_r3/verdict_M8v1b_r3B_DRAFT.py
+b2b12c8c6beb4b76954b6da99b0f273ca5eefad11268355786b8c3d420719e3c hashing_gen/m8_v1b/code/train_m8v1b.py
+d82871083e9cf1cab82dd209aff399599b9e8bdbe7a9e3699813f30fda52d617 hashing_gen/m8_v1b/gate_m8v1b.sh
+a1941e571c476d1ed7cc39977751de64850fae530061430b584eb627b1095f31 hashing_gen/m8_v1b/PREDECL.md
+9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b hashing_gen/m8_v1b/sample/v1b_sample.bin
+ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3 hashing_gen/corpus_v1b/train.bin
+Note : PREDECL.md audité par Checker à f57722be… ; une seule ligne « REMPLACÉ par §10 » ajoutée ensuite sous l'en-tête §6 (rien effacé) ⇒ a1941e57…, signalé à Checker.
+runs/ : vide à la pose. — SPIRA Hashing
diff --git a/results/hashing/m8_v1b/PREDECL.md b/results/hashing/m8_v1b/PREDECL.md
new file mode 100644
index 0000000000000000000000000000000000000000..7ff3d90a509ce0014816d497367fc3d63a8dd023
--- /dev/null
+++ b/results/hashing/m8_v1b/PREDECL.md
@@ -0,0 +1,78 @@
+# PRÉ-DÉCLARATION — M8 v1b (cm vs ctl) sur échantillon déterministe de corpus_diverse_v1b — SPIRA Hashing
+
+Rédigée le 2026-10-24 (Toronto), AVANT tout run M8 v1b. Plan source : hashing_gen/m8_v1b_plan.md (sha256 c370ca15eb901c09df2e475b89d39762ba64f662e3dde7656e12c69c3801382d), option (A) §4.
+Aucun bras lancé. La porte (gate_m8v1b.sh) attend le drapeau GO_CHECKER_PASS, que Hashing pose À LA MAIN seulement après les DEUX PASS écrits de Checker (recompte v1b — reçu — et audit du script de verdict figé ci-dessous — en attente).
+
+## 0. PASS Checker reçu (recompte 64 o v1b)
+Vérifié dans le texte de Checker lui-même : spira_relay.md, l. 7465 « ### SPIRA Checker — 11 h 41 (Toronto) — réponse Relay 11 h 36 / Hashing 11 h 35 », point 1 (l. 7466-7471) :
+« **1) Recompte indépendant 64 o corpus_diverse_v1b : PASS — validé par Checker.** » — train.bin 520 785 883 o, sha256 ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3 ; manifest_corpus_diverse_v1b.json sha256 cb6398ca62f8f0003afd4d5505d59ecea7a8a13814091b358d93368c14f2494f ; script checker/recount/v1b_dedup_1138/recount64_words.py (effa0860…83b9), sortie recount64_words.json (0107671a…10d5) ; fc2 / fresh_en / fresh_fr / test20k (old_local_v1/test, ce0526c6) / test_v3 = 0/0/0, queries 0/0/0 à part, neither_code exclu.
+Note : l'entrée Checker est titrée 11 h 41 ; Relay et l'entrée Hashing 11 h 42 (l. 7477) l'appellent « PASS Checker 11 h 42 ». Même PASS.
+
+## 1. Échantillon (étape 1)
+- Fichier : m8_v1b/sample/v1b_sample.bin — **35 128 951 o, sha256 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b**, 4 111 documents. Re-tirage : sha identique. Pic RSS 80 Mo, 0,4 s.
+- Source : corpus_v1b/train.bin (520 785 883 o, ddf67ffb…) + manifest cb6398ca….
+- Générateur : code/make_sample_v1b.py (sha256 b9a72c14958e82db7585d50aa7e1c0de5e927e9171b3bc64482157fe003db595) — règle complète dans sa docstring : documents natifs (TinyStories « \n<|endoftext|>\n », livres PG par plages per_source du manifest, stdlib = lacunes entre plages, fichiers multi_lang « \n<|endoffile|>\n » rattachés aux dépôts par files_kept cumulés), strates source/langue (tinystories/en, books/en, books/fr, stdlib/python, github/ ×15), cible par strate T_s = round(35e6 × part en octets v1b), seed de strate = 20261024 XOR sha256(nom)[:16], document pris s'il rapproche le cumul de T_s ; sortie ENTRELACÉE (clé = milieu du rang dans la strate, égalités départagées par seed) pour que tout préfixe soit stratifié ; chaque document suivi de son séparateur natif.
+- Manifeste d'échantillon : sample/v1b_sample_manifest.json (c575541b660511973ab6eb5741fafad4ebbef92e5d0f34b365e9a2dd8ca076de) ; index documents sample/v1b_sample_docs.json (8f82dc0d7c8c37c91d065d54221b9598794e46a281e22261f78dffa0f5db677f).
+- Composition (octets de documents) : échantillon entier books/en 35,8 %, books/fr 13,5 %, github 46,0 %, tinystories 3,7 %, stdlib 1,2 % (smoke/prefix_composition.txt).
+
+## 2. Recompte 64 o de l'échantillon (méthode du build, recount_div1/recount64.py inchangé)
+sample/recount64_v1b_sample.json (sha256 a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c) ; 11 h 42 Toronto, porte OUI (MemAvailable 7,93 Go, lourds 3), pic 856 Mo, 12,8 s.
+Positions de fenêtre confirmées (octet à octet) : fc2 (b052096b) 0 ; fresh_en (67ff20b2) 0 ; fresh_fr (875f0906) 0 ; test20k (ce0526c6) 0 ; test_v3 (a6730bbe) 0 ; queries (5aab38d6) 0 ; neither_code (f1d728dc, exclue) 0. Collisions intra-fenêtre 0.
+Témoins NON visés (exclus au plan) : freshcode m7 (589dbc35) 143 787 ; broad_local_v1/test (e89725bb) 21 086 — contaminés, donc exclus.
+
+## 3. Ce qui est lu (problème du préfixe)
+Couvrir tout l'échantillon (7 739 248 patches) demanderait ~7,7 M ticks/époque (cm 26 t/s ⇒ ~7 jours/époque) : infaisable. Décision : budgets du plan conservés, échantillon entrelacé (préfixes stratifiés), et lecture documentée exactement (mesurée au smoke, identique dans les deux bras, tokenisation identique vérifiée) :
+- EPT : fit sur [0, 2 000 000), calibration [2 000 000, 2 400 000) ; segmentation de TOUT l'échantillon ⇒ vocabulaire top-16384 et registre (count ≥ 2) sur tout l'échantillon ; bras cm : co-occurrences PPMI des neurones CM sur tout l'échantillon.
+- SNN : 600 000 patches = octets **[0, 2 791 343)** (7,9 % de l'échantillon), 2 époques — composition : books/en 31,9 %, books/fr 14,4 %, github 48,7 %, tinystories 4,1 %, stdlib 1,0 %.
+- AM : 1 200 000 patches = octets **[0, 5 554 968)** — books/en 35,1 %, books/fr 16,1 %, github 44,4 %, tinystories 3,4 %, stdlib 1,1 %.
+- Calibration fusion : [0, 60 000).
+- Fenêtre seen = échantillon[0, 200 000) (≈ 44 k patches < 600 k ⇒ entièrement dans le SNN) : github 88,5 %, stdlib 3,5 %, tinystories 8,0 % (pas de livres : fait déclaré, la fenêtre seen est surtout du code).
+
+## 4. Bras, budgets, seeds
+- cm = CMSPIRA.build_cm (code/countmin.py, copie octet-identique de semhash/countmin.py, sha256 caab50405e73eba7981f73a63fb1709139aed55383501c3e830e174cb02b8d3b) — d_in 1024+4096, k_in 12+24, n_state 6656.
+- ctl = SPIRA.build, même cfg, mêmes octets, sans CM — n_state 2560. Seule différence : la classe.
+- cfg commun : SPIRAConfig(vocab_size=16384, d_in=1024, snn_tokens=600 000, am_tokens=1 200 000, epochs=2), seed modèle 20261022 (défaut repo /workspace/SPIRA commit 6923c5191049ee488d9418c7002f108abd9e8ea1) ; seed d'échantillonnage 20261024. maxpos 4000 par fenêtre.
+- Script de bras : code/train_m8v1b.py (sha256 b2b12c8c6beb4b76954b6da99b0f273ca5eefad11268355786b8c3d420719e3c) — boucle = copie de SPIRA.train ; éval = eval_hits exécuté tel quel depuis checker/eval_ref_v3.py (e2c8cd1d…, lecture seule) ; fc2 via checker/windows_v2.py (7d9ed224…). Option --smoke-ticks réservée au smoke (jamais passée par la porte).
+- Points de reprise : par ÉPOQUE (W_rec, W_out, W_outG + historique + clé méta) — seul état appris qui survit à une époque (train_pass appelle core.reset()). **Reprise intra-époque NON faisable** sans modifier train_pass (non fait). Test d'équivalence (smoke/equiv, préfixe 3 Mo, snn 1500, am 20 000, 2 époques) : run arrêté après l'époque 1 puis repris = SPIRA.train original, **bit à bit** (empreintes W_rec/W_out/W_outG/AM keys/vals et historique identiques) pour cm ET ctl.
+
+## 5. Mesures smoke (plein échantillon, budgets réels 600k/1,2M pour build/prepare/AM/save ; passe SNN tronquée à 3000 ticks ; 1 fenêtre seen 500 positions)
+- ctl (11 h 53-11 h 55) : 72,3 t/s ; RSS plat pendant le SNN (601 216 ko de tick 500 à 2500 : pente ≈ 0) ; pic ru_maxrss 1 202,6 Mio (≈ 1,26 Go, à la sauvegarde/relecture) ; AM 16,5 s ; calibration+save ~74 s ; éval 6,0 s/500 positions seen ; ctl.npz 180 940 838 o.
+- cm (11 h 56-12 h 02, PID 184698) : 26,0 t/s ; RSS plat pendant le SNN (952 120 → 952 128 ko sur 3000 ticks) ; pic ru_maxrss 2 040,6 Mio (≈ 2,14 Go, à la sauvegarde/relecture) ; AM 14,2 s ; calibration+save ~185 s ; éval 17,9 s/500 positions seen ; cm.npz 394 081 898 o.
+- Estimations par bras (run complet, 2 × 600 000 ticks, 7 fenêtres × 4000) : ctl ≈ 16 700 s SNN + ~10 min (build/AM/save/éval) ≈ **4,8 h**, pic ≈ 1,3 Go (porte : 1,6 Go) ; cm ≈ 46 200 s SNN + ~25 min ≈ **13,3 h**, pic ≈ 2,1 Go (porte : 2,5 Go). Séquentiel ≈ 18 h ; parallèle (si les deux tiennent) ≈ 13,3 h. Vitesses mesurées avec 3 autres lourds sur la machine.
+
+## 6. Fenêtres et règle (verdict figé)
+- **REMPLACÉ par §10** (révision 24 oct 13 h 03 Toronto, règle B, décision de Philippe-Antoine 13 h 00 ; verdict figé b3db0875…). Le texte ci-dessous (gain sur seen exigé) est conservé pour trace et n'est plus en vigueur. [note ajoutée 13 h 06 Toronto — SPIRA Hashing]
+- Script : **code/verdict_M8v1b.py** — sha256 en §8. Dérivé de lever2_sparse/code/verdict_SP.py (7a6d54145fdabd726d16d0c0f651d5509b561ac82b0b49d1ea1bbf858d9a2deb), chemin v4.2.
+- Fenêtres de la règle : seen (échantillon[:200 000], valide seulement si trained_frac ≥ 0,99 dans les deux bras, sinon NON COMPARABLE ⇒ NON MESURABLE) ; fc2 ; fresh_en ; fresh_fr ; test20k strict (masque lever2/verdict_AH1/mask_oldtest_strict.npz, 50fa08f9…, old_local_v1 ∪ broad_local_v1, recul 64 o ; échantillon : 0 position, vérifié par le recompte) ; test_v3 seulement si propre (recompte échantillon = 0 ET recompte v1b = 0 ET drapeau GO présent).
+- queries : rapportée À PART (hors règle). neither_code : exclue (non évaluée). freshcode m7 et broad_local_v1/test : exclues (contaminées).
+- Positions propres seulement : chaque fenêtre fraîche exige 0 position confirmée au recompte de l'échantillon, sinon exclue.
+- Statistiques : positions in-vocab dans les DEUX bras, taux appariés (même dénominateur), appariement par position (tokenisation identique vérifiée), McNemar exact bilatéral ; bootstrap apparié par blocs de 512 o, B = 10 000, seed 0.
+- Règle : **ADOPTÉ** ssi gain significatif (McNemar p < 0,05 ET c > b ET IC95 bootstrap > 0) sur seen ET sur ≥ 1 fenêtre fraîche valide, ET aucune perte significative (p < 0,05 ET b > c) sur une fenêtre valide (seen + fraîches valides). Sinon **REJETÉ**. **NON MESURABLE** si budgets cm/ctl inégaux (snn_tokens, am_tokens, epochs, ticks/époque, sha des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick ≠ snn_tokens), ou seen non comparable.
+
+## 7. Bogue signalé par Relay 12 h 07 — vérification et correction (révision 2 du verdict)
+- Signalement Relay : vtest (12 h 06) NON MESURABLE alors que budgets « identiques » ; diagnostic proposé : bogue d'unités (ticks 3000 comparés à tokens 600 000).
+- Vérification : dans /workspace/SPIRA/python/spira/spiking.py, SpikingCore.train_pass (l. 471-539) fait UN tick par token SNN (`neurons[t]` = token t, `T = len(cols)`, `"ticks": T`). Donc 1 tick = 1 token ; « 3000 ticks » = 3000 tokens entraînés sur 600 000 déclarés. Le vtest utilisait les modèles du SMOKE, dont la passe SNN était volontairement tronquée (--smoke-ticks 3000). Le NON MESURABLE était donc **correct** (passe incomplète), pas un bogue d'unités ; le diagnostic de Relay ne se vérifie pas. Les champs égaux cm == ctl étaient bien égaux.
+- Vrais défauts trouvés à cette occasion, corrigés : (1) la clause était implicite et le message (« budgets inégaux ou incohérents ») trompeur ⇒ unités rendues explicites (`TOKENS_PER_TICK = 1`, tokens entraînés/époque = ticks × TOKENS_PER_TICK comparés à snn_tokens), égalités cm == ctl gardées séparément (champ par champ), raison précise (« passe SNN incomplète … ») et bloc `budget_check` dans le json ; (2) **audit seen** : trained_frac était calculé avec snn_tokens DÉCLARÉ ; il l'est maintenant avec les tokens RÉELLEMENT entraînés (min sur époques de ticks × 1).
+- Ancienne version conservée : smoke/verdict_M8v1b.v1_69a6a739.py (sha256 69a6a73991458ad8da675190c2ac797311fbe117cb4c7656e441880d474e2da7, jamais soumise ni utilisée sur un run réel).
+- Re-test sur les mêmes entrées tronquées (smoke/vtest/verdict_r2) : toujours NON MESURABLE, raison désormais « passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000 ». Test mesurable : §9.
+- Checker 12 h 10 (spira_relay.md l. 7540-7545) : diagnostic Relay « bug d'unités » invalidé par Checker, clause à conserver, « logique validée » du script r2 (sha256 aa66889b…). Aucune modification depuis : le script de la porte est bien la r2.
+
+## 8. Script de verdict figé (r2)
+**code/verdict_M8v1b.py — sha256 aa66889b53e9566bedebd1e66679ed2c08b07f1fecff7d9a2e79d2e42a9fa8d3** (figé à 12 h 08 Toronto).
+Checker : PASS d'audit écrit demandé sur ce sha complet (relay, Hashing 12 h 17). Le drapeau GO_CHECKER_PASS reste NON posé jusqu'à ce PASS.
+Autres sha : train_m8v1b.py b2b12c8c6beb4b76954b6da99b0f273ca5eefad11268355786b8c3d420719e3c ; gate_m8v1b.sh d82871083e9cf1cab82dd209aff399599b9e8bdbe7a9e3699813f30fda52d617 ; run_guarded.sh f4bf377e601eca804a9383755ba863b3882c9b692624b0f21eb1e60c57076645 ; countmin.py caab5040… ; références : verdict_SP.py 7a6d5414…, train_cm_m8.py 4fa7c2d1… ; masque test20k 50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178 ; eval_ref_v3.py e2c8cd1deabc228faed302bebdb81bf8d10405df63e393b4a8ddb6152401c10e ; windows_v2.py 7d9ed224012184b19723c0254982878bc0a56102ef4722dd3d443ed6486869c1.
+
+## 9. Test mesurable du pipeline (vtest2, non décisionnel)
+Les deux bras ont été lancés sans troncature, avec un budget complet mais petit : snn 3000 (= 3000 ticks), am 1,2M, 1 époque, 7 fenêtres × 300 positions, --no-save. ctl : 12 h 08-12 h 11, pic 1,15 Go. cm : 12 h 11-12 h 17, pic 1,27 Go (min MemAvailable 5,69 Go). Ils ont été suivis du verdict r2, dont la copie ne diffère que par la ligne de chemins.
+Résultat : budget_ok True (ticks × 1 == snn_tokens pour les deux bras), seen COMPARABLE (trained_frac 1,0/1,0), sortie **mesurable** : REJETÉ (pas de gain sur seen ni sur une fenêtre fraîche). C'est un test non décisionnel. test_v3 est exclue parce que le drapeau est absent, comme prévu.
+
+## 10. Révision datée 2026-10-24 13:03 EDT — §6 et §8 remplacés : règle B (r3), verdict r3B figé
+**Décision écrite de Philippe-Antoine, 24 oct, 13 h 00 (Toronto), mot pour mot :** « on fige la règle B pour M8 v1b (recommandée par Checker). Procède avec ça. Continue code_scale_v1 et le reste vers la généralisation. Push les artefacts validés. »
+- **§6, règle (remplace la règle de §6) :** **ADOPTÉ** ssi gain significatif (McNemar exact p < 0,05 ET c > b ET IC95 bootstrap > 0) sur ≥ 1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre), ET aucune perte significative (p < 0,05 ET b > c) sur une fenêtre valide (seen + fraîches valides ; une égalité sur seen saturé est admise). Le gain sur seen n'est plus exigé. Sinon **REJETÉ**.
+- **NON MESURABLE** : budgets cm/ctl inégaux, passe SNN incomplète (ticks × 1 ≠ snn_tokens), seen non comparable (trained_frac < 0,99), **ou fusion.scale (cal.scale dans results.jsonl) d'un bras hors [0,03 ; 0,11]** ou illisible.
+- **Plage [0,03 ; 0,11] : PROVISOIRE**, codée en dur (non surchargeable, --scale-lo/--scale-hi refusés rc 2). Philippe-Antoine ne l'a pas tranchée. Au smoke, ctl 1,0507 et cm 1,1309 étaient hors plage : risque réel de NON MESURABLE sur le vrai run.
+- Fenêtres, positions propres et statistiques : inchangées (§6).
+- **§8, script figé (remplace la r2) :** **code/verdict_M8v1b.py — sha256 b3db0875b6e01d2c2192d9e307d337a3fb908f524f7be5e3a9a5b380eec7d7dc** (17 727 o) = brouillon r3B cb27a4a57e1d97456ef7a2691ba6a7a64a3a6ac026798900f34533c580ed4f93 (pré-audit PASS Checker 12 h 54 / 13 h 01), avec la seule docstring l. 13 reformulée (« bornes en dur »). Diff : code/drafts_r3/r3B_FROZEN_vs_cb27a4a5.diff (5669789b…). Diff vs r2 : code/drafts_r3/r3B_FROZEN_vs_r2.diff (f41ba460…).
+- r2 archivée : code/verdict_M8v1b.r2.py (aa66889b53e9566bedebd1e66679ed2c08b07f1fecff7d9a2e79d2e42a9fa8d3, FAIL d'audit Checker 12 h 20/12 h 23). r3A (389bdcb2…) : REJETÉE par décision (code/drafts_r3/README_r3A_REJETEE.md).
+- Aucun résultat dans runs/ au moment de cette révision (runs/ vide, vérifié). GO_CHECKER_PASS non posé : il le sera seulement après un PASS d'audit de gel écrit par Checker nommant b3db0875…. La porte 218845 (gate_m8v1b.sh d8287108…) appelle code/verdict_M8v1b.py sans contrôle de sha ; elle n'a pas été modifiée.
+— SPIRA Hashing, 2026-10-24 13:03 EDT
diff --git a/results/hashing/m8_v1b/STATUS b/results/hashing/m8_v1b/STATUS
new file mode 100644
index 0000000000000000000000000000000000000000..5be29fffa1a7fb0ac9b415a4bac05041a6d87b73
--- /dev/null
+++ b/results/hashing/m8_v1b/STATUS
@@ -0,0 +1 @@
+2026-10-25 01:35:34 EDT ÉCHEC (3 essais) — voir /workspace/spira_shared/hashing_gen/m8_v1b/logs/gate_m8v1b.log | ctl=done(try 1) cm=failed(try 3) | gate pid 218845
diff --git a/results/hashing/m8_v1b/code/countmin.py b/results/hashing/m8_v1b/code/countmin.py
new file mode 100644
index 0000000000000000000000000000000000000000..8145f656cc4dbf2db38840ef4f9bbaf5cdc508e8
--- /dev/null
+++ b/results/hashing/m8_v1b/code/countmin.py
@@ -0,0 +1,129 @@
+"""RECONSTRUIT, À RE-VÉRIFIER (Hashing, 2026-10-23, après la perte de /tmp).
+Projection sémantique Count-Min MinHash, figée et déterministe, sans backprop.
+- Co-occurrences des colonnes de vocabulaire dans une fenêtre de ±W (W=2), comptées sur le train.
+- PPMI, puis les top-K (K=16) contextes par colonne.
+- d=24 fonctions MinHash sur cet ensemble de contextes -> 24 neurons dans un bloc sémantique
+ de largeur 4096, décalé après les d_in de base (v3 : 1024). Ligne finale = 12 neurones v3 + 24.
+Les choix de mise en page (bloc décalé, d_in total = 1024+4096) sont des HYPOTHÈSES :
+la mise en page de l'original n'est pas connue.
+"""
+from __future__ import annotations
+import json, sys
+import numpy as np
+sys.path.insert(0, "/workspace/SPIRA/python")
+from spira import SPIRA, SPIRAConfig
+from spira.hashing import splitmix64
+
+M64 = 0xFFFFFFFFFFFFFFFF
+
+def cooc_ppmi_topk(cols: np.ndarray, V: int, window: int = 2, topk: int = 16) -> np.ndarray:
+ """cols: (T,) vocab cols, V == UNK (masked). Returns (V, topk) int64 context cols, -1 pad."""
+ keys = []
+ for o in range(1, window + 1):
+ a, b = cols[:-o], cols[o:]
+ ok = (a < V) & (b < V)
+ a, b = a[ok], b[ok]
+ keys.append(a * V + b); keys.append(b * V + a)
+ k, c = np.unique(np.concatenate(keys), return_counts=True)
+ w, ctx = k // V, k % V
+ c = c.astype(np.float64)
+ tot = c.sum()
+ rw = np.bincount(w, weights=c, minlength=V); rc = np.bincount(ctx, weights=c, minlength=V)
+ pmi = np.log(c * tot / (rw[w] * rc[ctx]))
+ pp = np.maximum(pmi, 0.0)
+ order = np.lexsort((ctx, -pp, w)) # par mot, PPMI décroissante, départage déterministe
+ w, ctx, pp = w[order], ctx[order], pp[order]
+ out = np.full((V, topk), -1, dtype=np.int64)
+ start = np.searchsorted(w, np.arange(V))
+ end = np.searchsorted(w, np.arange(V), side="right")
+ for v in range(V):
+ s, e = start[v], min(end[v], start[v] + topk)
+ sel = ctx[s:e][pp[s:e] > 0]
+ out[v, :len(sel)] = sel
+ return out
+
+def minhash_rows(top: np.ndarray, d: int = 24, width: int = 4096, offset: int = 1024) -> np.ndarray:
+ """(V, d) neurons in [offset, offset+width). Colonne sans contexte -> -1 (pas de neurone sémantique)."""
+ V = top.shape[0]
+ out = np.full((V, d), -1, dtype=np.int32)
+ for v in range(V):
+ ctx = [int(x) for x in top[v] if x >= 0]
+ if not ctx:
+ continue
+ for j in range(d):
+ salt = (0xC0FFEE ^ (j * 0x9E3779B97F4A7C15)) & M64
+ out[v, j] = offset + int(min(splitmix64((x ^ salt) & M64) for x in ctx) % width)
+ return out
+
+def attach(model: SPIRA, sem: np.ndarray) -> None:
+ """Remplace neuron_rows : ligne v3 (12) + 24 neurones sémantiques (UNK/sans contexte -> repli v3 dupliqué)."""
+ base = model.neuron_rows
+ def rows(ids, patches=None):
+ r = base(ids, patches)
+ cols = model.cols_of(ids)
+ V = model.cfg.vocab_size
+ s = np.where((cols < V)[:, None], sem[np.minimum(cols, V - 1)], -1)
+ s = np.where(s < 0, r[:, :1], s) # repli : neurone v3 déjà actif (pas de nouveau neurone)
+ return np.concatenate([r, s.astype(np.int32)], axis=1)
+ model.neuron_rows = rows
+
+def save_with_calibration(model: SPIRA, path: str, calib_bytes: bytes, n_tokens: int = 3000) -> dict:
+ """calibrate_fusion est appelé AVANT save ; on vérifie ensuite que l'échelle est bien dans le checkpoint."""
+ fus = model.calibrate_fusion(calib_bytes, n_tokens=n_tokens)
+ model.save(path)
+ z = np.load(path, allow_pickle=False)
+ saved = json.loads(str(z["fusion"]))
+ assert abs(saved["scale"] - fus["scale"]) < 1e-12 and saved["sigma_fast"] is not None, saved
+ return saved
+
+
+# ---------------------------------------------------------------------------
+# RECONSTRUIT, À RE-VÉRIFIER — modèle CM qui se recharge seul (correctif 8 h 38)
+import dataclasses
+
+class CMSPIRA(SPIRA):
+ """cfg.d_in / cfg.k_in = tailles TOTALES (base + CM) : le cœur et la config
+ sauvegardée concordent. La table CM et ses paramètres vont dans le ckpt (cm_sem, cm_params)."""
+ def __init__(self, cfg, base_d_in: int = 1024, base_k: int = 12, cm_d: int = 24, cm_width: int = 4096):
+ super().__init__(cfg)
+ self.cm = {"base_d_in": base_d_in, "base_k": base_k, "d": cm_d, "width": cm_width}
+ self.cm_sem = None
+
+ @classmethod
+ def build_cm(cls, data, cfg, window=2, topk=16, base_d_in=1024, base_k=12, d=24, width=4096, log=print):
+ cfg = dataclasses.replace(cfg, d_in=base_d_in + width, k_in=base_k + d)
+ m = cls.build(data, cfg, log=log)
+ m.cm = {"base_d_in": base_d_in, "base_k": base_k, "d": d, "width": width, "window": window, "topk": topk}
+ top = cooc_ppmi_topk(m.cols_of(m._ids_train), cfg.vocab_size, window, topk)
+ m.cm_sem = minhash_rows(top, d, width, base_d_in)
+ m._row_cache = {}
+ return m
+
+ def _structured_row(self, pid, pbytes):
+ c, full = self.cm, self.cfg
+ self.cfg = dataclasses.replace(full, d_in=c["base_d_in"], k_in=c["base_k"])
+ try:
+ base = SPIRA._structured_row(self, pid, pbytes)
+ finally:
+ self.cfg = full
+ col = int(self.cols_of(np.array([pid], dtype=np.uint64))[0])
+ s = self.cm_sem[col] if col < full.vocab_size else np.full(c["d"], -1, np.int32)
+ s = np.where(s < 0, base[0], s)
+ return np.concatenate([base, s]).astype(np.int32)
+
+ def save(self, path, am_cap=1_500_000):
+ super().save(path, am_cap)
+ z = dict(np.load(path, allow_pickle=False))
+ z["cm_sem"] = self.cm_sem
+ z["cm_params"] = np.array(json.dumps(self.cm))
+ with open(path, "wb") as f:
+ np.savez_compressed(f, **z)
+
+ @classmethod
+ def load(cls, path):
+ m = super().load.__func__(cls, path)
+ z = np.load(path, allow_pickle=False)
+ m.cm = json.loads(str(z["cm_params"]))
+ m.cm_sem = z["cm_sem"].astype(np.int32)
+ m._row_cache = {}
+ return m
diff --git a/results/hashing/m8_v1b/code/drafts_r3/PREDECL.pre_note6_f57722be.md b/results/hashing/m8_v1b/code/drafts_r3/PREDECL.pre_note6_f57722be.md
new file mode 100644
index 0000000000000000000000000000000000000000..e1850a23c233e49dd6ce7e9136dfcec3c3b3766a
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/PREDECL.pre_note6_f57722be.md
@@ -0,0 +1,77 @@
+# PRÉ-DÉCLARATION — M8 v1b (cm vs ctl) sur échantillon déterministe de corpus_diverse_v1b — SPIRA Hashing
+
+Rédigée le 2026-10-24 (Toronto), AVANT tout run M8 v1b. Plan source : hashing_gen/m8_v1b_plan.md (sha256 c370ca15eb901c09df2e475b89d39762ba64f662e3dde7656e12c69c3801382d), option (A) §4.
+Aucun bras lancé. La porte (gate_m8v1b.sh) attend le drapeau GO_CHECKER_PASS, que Hashing pose À LA MAIN seulement après les DEUX PASS écrits de Checker (recompte v1b — reçu — et audit du script de verdict figé ci-dessous — en attente).
+
+## 0. PASS Checker reçu (recompte 64 o v1b)
+Vérifié dans le texte de Checker lui-même : spira_relay.md, l. 7465 « ### SPIRA Checker — 11 h 41 (Toronto) — réponse Relay 11 h 36 / Hashing 11 h 35 », point 1 (l. 7466-7471) :
+« **1) Recompte indépendant 64 o corpus_diverse_v1b : PASS — validé par Checker.** » — train.bin 520 785 883 o, sha256 ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3 ; manifest_corpus_diverse_v1b.json sha256 cb6398ca62f8f0003afd4d5505d59ecea7a8a13814091b358d93368c14f2494f ; script checker/recount/v1b_dedup_1138/recount64_words.py (effa0860…83b9), sortie recount64_words.json (0107671a…10d5) ; fc2 / fresh_en / fresh_fr / test20k (old_local_v1/test, ce0526c6) / test_v3 = 0/0/0, queries 0/0/0 à part, neither_code exclu.
+Note : l'entrée Checker est titrée 11 h 41 ; Relay et l'entrée Hashing 11 h 42 (l. 7477) l'appellent « PASS Checker 11 h 42 ». Même PASS.
+
+## 1. Échantillon (étape 1)
+- Fichier : m8_v1b/sample/v1b_sample.bin — **35 128 951 o, sha256 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b**, 4 111 documents. Re-tirage : sha identique. Pic RSS 80 Mo, 0,4 s.
+- Source : corpus_v1b/train.bin (520 785 883 o, ddf67ffb…) + manifest cb6398ca….
+- Générateur : code/make_sample_v1b.py (sha256 b9a72c14958e82db7585d50aa7e1c0de5e927e9171b3bc64482157fe003db595) — règle complète dans sa docstring : documents natifs (TinyStories « \n<|endoftext|>\n », livres PG par plages per_source du manifest, stdlib = lacunes entre plages, fichiers multi_lang « \n<|endoffile|>\n » rattachés aux dépôts par files_kept cumulés), strates source/langue (tinystories/en, books/en, books/fr, stdlib/python, github/ ×15), cible par strate T_s = round(35e6 × part en octets v1b), seed de strate = 20261024 XOR sha256(nom)[:16], document pris s'il rapproche le cumul de T_s ; sortie ENTRELACÉE (clé = milieu du rang dans la strate, égalités départagées par seed) pour que tout préfixe soit stratifié ; chaque document suivi de son séparateur natif.
+- Manifeste d'échantillon : sample/v1b_sample_manifest.json (c575541b660511973ab6eb5741fafad4ebbef92e5d0f34b365e9a2dd8ca076de) ; index documents sample/v1b_sample_docs.json (8f82dc0d7c8c37c91d065d54221b9598794e46a281e22261f78dffa0f5db677f).
+- Composition (octets de documents) : échantillon entier books/en 35,8 %, books/fr 13,5 %, github 46,0 %, tinystories 3,7 %, stdlib 1,2 % (smoke/prefix_composition.txt).
+
+## 2. Recompte 64 o de l'échantillon (méthode du build, recount_div1/recount64.py inchangé)
+sample/recount64_v1b_sample.json (sha256 a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c) ; 11 h 42 Toronto, porte OUI (MemAvailable 7,93 Go, lourds 3), pic 856 Mo, 12,8 s.
+Positions de fenêtre confirmées (octet à octet) : fc2 (b052096b) 0 ; fresh_en (67ff20b2) 0 ; fresh_fr (875f0906) 0 ; test20k (ce0526c6) 0 ; test_v3 (a6730bbe) 0 ; queries (5aab38d6) 0 ; neither_code (f1d728dc, exclue) 0. Collisions intra-fenêtre 0.
+Témoins NON visés (exclus au plan) : freshcode m7 (589dbc35) 143 787 ; broad_local_v1/test (e89725bb) 21 086 — contaminés, donc exclus.
+
+## 3. Ce qui est lu (problème du préfixe)
+Couvrir tout l'échantillon (7 739 248 patches) demanderait ~7,7 M ticks/époque (cm 26 t/s ⇒ ~7 jours/époque) : infaisable. Décision : budgets du plan conservés, échantillon entrelacé (préfixes stratifiés), et lecture documentée exactement (mesurée au smoke, identique dans les deux bras, tokenisation identique vérifiée) :
+- EPT : fit sur [0, 2 000 000), calibration [2 000 000, 2 400 000) ; segmentation de TOUT l'échantillon ⇒ vocabulaire top-16384 et registre (count ≥ 2) sur tout l'échantillon ; bras cm : co-occurrences PPMI des neurones CM sur tout l'échantillon.
+- SNN : 600 000 patches = octets **[0, 2 791 343)** (7,9 % de l'échantillon), 2 époques — composition : books/en 31,9 %, books/fr 14,4 %, github 48,7 %, tinystories 4,1 %, stdlib 1,0 %.
+- AM : 1 200 000 patches = octets **[0, 5 554 968)** — books/en 35,1 %, books/fr 16,1 %, github 44,4 %, tinystories 3,4 %, stdlib 1,1 %.
+- Calibration fusion : [0, 60 000).
+- Fenêtre seen = échantillon[0, 200 000) (≈ 44 k patches < 600 k ⇒ entièrement dans le SNN) : github 88,5 %, stdlib 3,5 %, tinystories 8,0 % (pas de livres : fait déclaré, la fenêtre seen est surtout du code).
+
+## 4. Bras, budgets, seeds
+- cm = CMSPIRA.build_cm (code/countmin.py, copie octet-identique de semhash/countmin.py, sha256 caab50405e73eba7981f73a63fb1709139aed55383501c3e830e174cb02b8d3b) — d_in 1024+4096, k_in 12+24, n_state 6656.
+- ctl = SPIRA.build, même cfg, mêmes octets, sans CM — n_state 2560. Seule différence : la classe.
+- cfg commun : SPIRAConfig(vocab_size=16384, d_in=1024, snn_tokens=600 000, am_tokens=1 200 000, epochs=2), seed modèle 20261022 (défaut repo /workspace/SPIRA commit 6923c5191049ee488d9418c7002f108abd9e8ea1) ; seed d'échantillonnage 20261024. maxpos 4000 par fenêtre.
+- Script de bras : code/train_m8v1b.py (sha256 b2b12c8c6beb4b76954b6da99b0f273ca5eefad11268355786b8c3d420719e3c) — boucle = copie de SPIRA.train ; éval = eval_hits exécuté tel quel depuis checker/eval_ref_v3.py (e2c8cd1d…, lecture seule) ; fc2 via checker/windows_v2.py (7d9ed224…). Option --smoke-ticks réservée au smoke (jamais passée par la porte).
+- Points de reprise : par ÉPOQUE (W_rec, W_out, W_outG + historique + clé méta) — seul état appris qui survit à une époque (train_pass appelle core.reset()). **Reprise intra-époque NON faisable** sans modifier train_pass (non fait). Test d'équivalence (smoke/equiv, préfixe 3 Mo, snn 1500, am 20 000, 2 époques) : run arrêté après l'époque 1 puis repris = SPIRA.train original, **bit à bit** (empreintes W_rec/W_out/W_outG/AM keys/vals et historique identiques) pour cm ET ctl.
+
+## 5. Mesures smoke (plein échantillon, budgets réels 600k/1,2M pour build/prepare/AM/save ; passe SNN tronquée à 3000 ticks ; 1 fenêtre seen 500 positions)
+- ctl (11 h 53-11 h 55) : 72,3 t/s ; RSS plat pendant le SNN (601 216 ko de tick 500 à 2500 : pente ≈ 0) ; pic ru_maxrss 1 202,6 Mio (≈ 1,26 Go, à la sauvegarde/relecture) ; AM 16,5 s ; calibration+save ~74 s ; éval 6,0 s/500 positions seen ; ctl.npz 180 940 838 o.
+- cm (11 h 56-12 h 02, PID 184698) : 26,0 t/s ; RSS plat pendant le SNN (952 120 → 952 128 ko sur 3000 ticks) ; pic ru_maxrss 2 040,6 Mio (≈ 2,14 Go, à la sauvegarde/relecture) ; AM 14,2 s ; calibration+save ~185 s ; éval 17,9 s/500 positions seen ; cm.npz 394 081 898 o.
+- Estimations par bras (run complet, 2 × 600 000 ticks, 7 fenêtres × 4000) : ctl ≈ 16 700 s SNN + ~10 min (build/AM/save/éval) ≈ **4,8 h**, pic ≈ 1,3 Go (porte : 1,6 Go) ; cm ≈ 46 200 s SNN + ~25 min ≈ **13,3 h**, pic ≈ 2,1 Go (porte : 2,5 Go). Séquentiel ≈ 18 h ; parallèle (si les deux tiennent) ≈ 13,3 h. Vitesses mesurées avec 3 autres lourds sur la machine.
+
+## 6. Fenêtres et règle (verdict figé)
+- Script : **code/verdict_M8v1b.py** — sha256 en §8. Dérivé de lever2_sparse/code/verdict_SP.py (7a6d54145fdabd726d16d0c0f651d5509b561ac82b0b49d1ea1bbf858d9a2deb), chemin v4.2.
+- Fenêtres de la règle : seen (échantillon[:200 000], valide seulement si trained_frac ≥ 0,99 dans les deux bras, sinon NON COMPARABLE ⇒ NON MESURABLE) ; fc2 ; fresh_en ; fresh_fr ; test20k strict (masque lever2/verdict_AH1/mask_oldtest_strict.npz, 50fa08f9…, old_local_v1 ∪ broad_local_v1, recul 64 o ; échantillon : 0 position, vérifié par le recompte) ; test_v3 seulement si propre (recompte échantillon = 0 ET recompte v1b = 0 ET drapeau GO présent).
+- queries : rapportée À PART (hors règle). neither_code : exclue (non évaluée). freshcode m7 et broad_local_v1/test : exclues (contaminées).
+- Positions propres seulement : chaque fenêtre fraîche exige 0 position confirmée au recompte de l'échantillon, sinon exclue.
+- Statistiques : positions in-vocab dans les DEUX bras, taux appariés (même dénominateur), appariement par position (tokenisation identique vérifiée), McNemar exact bilatéral ; bootstrap apparié par blocs de 512 o, B = 10 000, seed 0.
+- Règle : **ADOPTÉ** ssi gain significatif (McNemar p < 0,05 ET c > b ET IC95 bootstrap > 0) sur seen ET sur ≥ 1 fenêtre fraîche valide, ET aucune perte significative (p < 0,05 ET b > c) sur une fenêtre valide (seen + fraîches valides). Sinon **REJETÉ**. **NON MESURABLE** si budgets cm/ctl inégaux (snn_tokens, am_tokens, epochs, ticks/époque, sha des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick ≠ snn_tokens), ou seen non comparable.
+
+## 7. Bogue signalé par Relay 12 h 07 — vérification et correction (révision 2 du verdict)
+- Signalement Relay : vtest (12 h 06) NON MESURABLE alors que budgets « identiques » ; diagnostic proposé : bogue d'unités (ticks 3000 comparés à tokens 600 000).
+- Vérification : dans /workspace/SPIRA/python/spira/spiking.py, SpikingCore.train_pass (l. 471-539) fait UN tick par token SNN (`neurons[t]` = token t, `T = len(cols)`, `"ticks": T`). Donc 1 tick = 1 token ; « 3000 ticks » = 3000 tokens entraînés sur 600 000 déclarés. Le vtest utilisait les modèles du SMOKE, dont la passe SNN était volontairement tronquée (--smoke-ticks 3000). Le NON MESURABLE était donc **correct** (passe incomplète), pas un bogue d'unités ; le diagnostic de Relay ne se vérifie pas. Les champs égaux cm == ctl étaient bien égaux.
+- Vrais défauts trouvés à cette occasion, corrigés : (1) la clause était implicite et le message (« budgets inégaux ou incohérents ») trompeur ⇒ unités rendues explicites (`TOKENS_PER_TICK = 1`, tokens entraînés/époque = ticks × TOKENS_PER_TICK comparés à snn_tokens), égalités cm == ctl gardées séparément (champ par champ), raison précise (« passe SNN incomplète … ») et bloc `budget_check` dans le json ; (2) **audit seen** : trained_frac était calculé avec snn_tokens DÉCLARÉ ; il l'est maintenant avec les tokens RÉELLEMENT entraînés (min sur époques de ticks × 1).
+- Ancienne version conservée : smoke/verdict_M8v1b.v1_69a6a739.py (sha256 69a6a73991458ad8da675190c2ac797311fbe117cb4c7656e441880d474e2da7, jamais soumise ni utilisée sur un run réel).
+- Re-test sur les mêmes entrées tronquées (smoke/vtest/verdict_r2) : toujours NON MESURABLE, raison désormais « passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000 ». Test mesurable : §9.
+- Checker 12 h 10 (spira_relay.md l. 7540-7545) : diagnostic Relay « bug d'unités » invalidé par Checker, clause à conserver, « logique validée » du script r2 (sha256 aa66889b…). Aucune modification depuis : le script de la porte est bien la r2.
+
+## 8. Script de verdict figé (r2)
+**code/verdict_M8v1b.py — sha256 aa66889b53e9566bedebd1e66679ed2c08b07f1fecff7d9a2e79d2e42a9fa8d3** (figé à 12 h 08 Toronto).
+Checker : PASS d'audit écrit demandé sur ce sha complet (relay, Hashing 12 h 17). Le drapeau GO_CHECKER_PASS reste NON posé jusqu'à ce PASS.
+Autres sha : train_m8v1b.py b2b12c8c6beb4b76954b6da99b0f273ca5eefad11268355786b8c3d420719e3c ; gate_m8v1b.sh d82871083e9cf1cab82dd209aff399599b9e8bdbe7a9e3699813f30fda52d617 ; run_guarded.sh f4bf377e601eca804a9383755ba863b3882c9b692624b0f21eb1e60c57076645 ; countmin.py caab5040… ; références : verdict_SP.py 7a6d5414…, train_cm_m8.py 4fa7c2d1… ; masque test20k 50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178 ; eval_ref_v3.py e2c8cd1deabc228faed302bebdb81bf8d10405df63e393b4a8ddb6152401c10e ; windows_v2.py 7d9ed224012184b19723c0254982878bc0a56102ef4722dd3d443ed6486869c1.
+
+## 9. Test mesurable du pipeline (vtest2, non décisionnel)
+Les deux bras ont été lancés sans troncature, avec un budget complet mais petit : snn 3000 (= 3000 ticks), am 1,2M, 1 époque, 7 fenêtres × 300 positions, --no-save. ctl : 12 h 08-12 h 11, pic 1,15 Go. cm : 12 h 11-12 h 17, pic 1,27 Go (min MemAvailable 5,69 Go). Ils ont été suivis du verdict r2, dont la copie ne diffère que par la ligne de chemins.
+Résultat : budget_ok True (ticks × 1 == snn_tokens pour les deux bras), seen COMPARABLE (trained_frac 1,0/1,0), sortie **mesurable** : REJETÉ (pas de gain sur seen ni sur une fenêtre fraîche). C'est un test non décisionnel. test_v3 est exclue parce que le drapeau est absent, comme prévu.
+
+## 10. Révision datée 2026-10-24 13:03 EDT — §6 et §8 remplacés : règle B (r3), verdict r3B figé
+**Décision écrite de Philippe-Antoine, 24 oct, 13 h 00 (Toronto), mot pour mot :** « on fige la règle B pour M8 v1b (recommandée par Checker). Procède avec ça. Continue code_scale_v1 et le reste vers la généralisation. Push les artefacts validés. »
+- **§6, règle (remplace la règle de §6) :** **ADOPTÉ** ssi gain significatif (McNemar exact p < 0,05 ET c > b ET IC95 bootstrap > 0) sur ≥ 1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre), ET aucune perte significative (p < 0,05 ET b > c) sur une fenêtre valide (seen + fraîches valides ; une égalité sur seen saturé est admise). Le gain sur seen n'est plus exigé. Sinon **REJETÉ**.
+- **NON MESURABLE** : budgets cm/ctl inégaux, passe SNN incomplète (ticks × 1 ≠ snn_tokens), seen non comparable (trained_frac < 0,99), **ou fusion.scale (cal.scale dans results.jsonl) d'un bras hors [0,03 ; 0,11]** ou illisible.
+- **Plage [0,03 ; 0,11] : PROVISOIRE**, codée en dur (non surchargeable, --scale-lo/--scale-hi refusés rc 2). Philippe-Antoine ne l'a pas tranchée. Au smoke, ctl 1,0507 et cm 1,1309 étaient hors plage : risque réel de NON MESURABLE sur le vrai run.
+- Fenêtres, positions propres et statistiques : inchangées (§6).
+- **§8, script figé (remplace la r2) :** **code/verdict_M8v1b.py — sha256 b3db0875b6e01d2c2192d9e307d337a3fb908f524f7be5e3a9a5b380eec7d7dc** (17 727 o) = brouillon r3B cb27a4a57e1d97456ef7a2691ba6a7a64a3a6ac026798900f34533c580ed4f93 (pré-audit PASS Checker 12 h 54 / 13 h 01), avec la seule docstring l. 13 reformulée (« bornes en dur »). Diff : code/drafts_r3/r3B_FROZEN_vs_cb27a4a5.diff (5669789b…). Diff vs r2 : code/drafts_r3/r3B_FROZEN_vs_r2.diff (f41ba460…).
+- r2 archivée : code/verdict_M8v1b.r2.py (aa66889b53e9566bedebd1e66679ed2c08b07f1fecff7d9a2e79d2e42a9fa8d3, FAIL d'audit Checker 12 h 20/12 h 23). r3A (389bdcb2…) : REJETÉE par décision (code/drafts_r3/README_r3A_REJETEE.md).
+- Aucun résultat dans runs/ au moment de cette révision (runs/ vide, vérifié). GO_CHECKER_PASS non posé : il le sera seulement après un PASS d'audit de gel écrit par Checker nommant b3db0875…. La porte 218845 (gate_m8v1b.sh d8287108…) appelle code/verdict_M8v1b.py sans contrôle de sha ; elle n'a pas été modifiée.
+— SPIRA Hashing, 2026-10-24 13:03 EDT
diff --git a/results/hashing/m8_v1b/code/drafts_r3/PREDECL.pre_r3B_0c2a01a0.md b/results/hashing/m8_v1b/code/drafts_r3/PREDECL.pre_r3B_0c2a01a0.md
new file mode 100644
index 0000000000000000000000000000000000000000..ff320f4da862f6c2a62aa41a9b1dae1e9faf50c8
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/PREDECL.pre_r3B_0c2a01a0.md
@@ -0,0 +1,66 @@
+# PRÉ-DÉCLARATION — M8 v1b (cm vs ctl) sur échantillon déterministe de corpus_diverse_v1b — SPIRA Hashing
+
+Rédigée le 2026-10-24 (Toronto), AVANT tout run M8 v1b. Plan source : hashing_gen/m8_v1b_plan.md (sha256 c370ca15eb901c09df2e475b89d39762ba64f662e3dde7656e12c69c3801382d), option (A) §4.
+Aucun bras lancé. La porte (gate_m8v1b.sh) attend le drapeau GO_CHECKER_PASS, que Hashing pose À LA MAIN seulement après les DEUX PASS écrits de Checker (recompte v1b — reçu — et audit du script de verdict figé ci-dessous — en attente).
+
+## 0. PASS Checker reçu (recompte 64 o v1b)
+Vérifié dans le texte de Checker lui-même : spira_relay.md, l. 7465 « ### SPIRA Checker — 11 h 41 (Toronto) — réponse Relay 11 h 36 / Hashing 11 h 35 », point 1 (l. 7466-7471) :
+« **1) Recompte indépendant 64 o corpus_diverse_v1b : PASS — validé par Checker.** » — train.bin 520 785 883 o, sha256 ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3 ; manifest_corpus_diverse_v1b.json sha256 cb6398ca62f8f0003afd4d5505d59ecea7a8a13814091b358d93368c14f2494f ; script checker/recount/v1b_dedup_1138/recount64_words.py (effa0860…83b9), sortie recount64_words.json (0107671a…10d5) ; fc2 / fresh_en / fresh_fr / test20k (old_local_v1/test, ce0526c6) / test_v3 = 0/0/0, queries 0/0/0 à part, neither_code exclu.
+Note : l'entrée Checker est titrée 11 h 41 ; Relay et l'entrée Hashing 11 h 42 (l. 7477) l'appellent « PASS Checker 11 h 42 ». Même PASS.
+
+## 1. Échantillon (étape 1)
+- Fichier : m8_v1b/sample/v1b_sample.bin — **35 128 951 o, sha256 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b**, 4 111 documents. Re-tirage : sha identique. Pic RSS 80 Mo, 0,4 s.
+- Source : corpus_v1b/train.bin (520 785 883 o, ddf67ffb…) + manifest cb6398ca….
+- Générateur : code/make_sample_v1b.py (sha256 b9a72c14958e82db7585d50aa7e1c0de5e927e9171b3bc64482157fe003db595) — règle complète dans sa docstring : documents natifs (TinyStories « \n<|endoftext|>\n », livres PG par plages per_source du manifest, stdlib = lacunes entre plages, fichiers multi_lang « \n<|endoffile|>\n » rattachés aux dépôts par files_kept cumulés), strates source/langue (tinystories/en, books/en, books/fr, stdlib/python, github/ ×15), cible par strate T_s = round(35e6 × part en octets v1b), seed de strate = 20261024 XOR sha256(nom)[:16], document pris s'il rapproche le cumul de T_s ; sortie ENTRELACÉE (clé = milieu du rang dans la strate, égalités départagées par seed) pour que tout préfixe soit stratifié ; chaque document suivi de son séparateur natif.
+- Manifeste d'échantillon : sample/v1b_sample_manifest.json (c575541b660511973ab6eb5741fafad4ebbef92e5d0f34b365e9a2dd8ca076de) ; index documents sample/v1b_sample_docs.json (8f82dc0d7c8c37c91d065d54221b9598794e46a281e22261f78dffa0f5db677f).
+- Composition (octets de documents) : échantillon entier books/en 35,8 %, books/fr 13,5 %, github 46,0 %, tinystories 3,7 %, stdlib 1,2 % (smoke/prefix_composition.txt).
+
+## 2. Recompte 64 o de l'échantillon (méthode du build, recount_div1/recount64.py inchangé)
+sample/recount64_v1b_sample.json (sha256 a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c) ; 11 h 42 Toronto, porte OUI (MemAvailable 7,93 Go, lourds 3), pic 856 Mo, 12,8 s.
+Positions de fenêtre confirmées (octet à octet) : fc2 (b052096b) 0 ; fresh_en (67ff20b2) 0 ; fresh_fr (875f0906) 0 ; test20k (ce0526c6) 0 ; test_v3 (a6730bbe) 0 ; queries (5aab38d6) 0 ; neither_code (f1d728dc, exclue) 0. Collisions intra-fenêtre 0.
+Témoins NON visés (exclus au plan) : freshcode m7 (589dbc35) 143 787 ; broad_local_v1/test (e89725bb) 21 086 — contaminés, donc exclus.
+
+## 3. Ce qui est lu (problème du préfixe)
+Couvrir tout l'échantillon (7 739 248 patches) demanderait ~7,7 M ticks/époque (cm 26 t/s ⇒ ~7 jours/époque) : infaisable. Décision : budgets du plan conservés, échantillon entrelacé (préfixes stratifiés), et lecture documentée exactement (mesurée au smoke, identique dans les deux bras, tokenisation identique vérifiée) :
+- EPT : fit sur [0, 2 000 000), calibration [2 000 000, 2 400 000) ; segmentation de TOUT l'échantillon ⇒ vocabulaire top-16384 et registre (count ≥ 2) sur tout l'échantillon ; bras cm : co-occurrences PPMI des neurones CM sur tout l'échantillon.
+- SNN : 600 000 patches = octets **[0, 2 791 343)** (7,9 % de l'échantillon), 2 époques — composition : books/en 31,9 %, books/fr 14,4 %, github 48,7 %, tinystories 4,1 %, stdlib 1,0 %.
+- AM : 1 200 000 patches = octets **[0, 5 554 968)** — books/en 35,1 %, books/fr 16,1 %, github 44,4 %, tinystories 3,4 %, stdlib 1,1 %.
+- Calibration fusion : [0, 60 000).
+- Fenêtre seen = échantillon[0, 200 000) (≈ 44 k patches < 600 k ⇒ entièrement dans le SNN) : github 88,5 %, stdlib 3,5 %, tinystories 8,0 % (pas de livres : fait déclaré, la fenêtre seen est surtout du code).
+
+## 4. Bras, budgets, seeds
+- cm = CMSPIRA.build_cm (code/countmin.py, copie octet-identique de semhash/countmin.py, sha256 caab50405e73eba7981f73a63fb1709139aed55383501c3e830e174cb02b8d3b) — d_in 1024+4096, k_in 12+24, n_state 6656.
+- ctl = SPIRA.build, même cfg, mêmes octets, sans CM — n_state 2560. Seule différence : la classe.
+- cfg commun : SPIRAConfig(vocab_size=16384, d_in=1024, snn_tokens=600 000, am_tokens=1 200 000, epochs=2), seed modèle 20261022 (défaut repo /workspace/SPIRA commit 6923c5191049ee488d9418c7002f108abd9e8ea1) ; seed d'échantillonnage 20261024. maxpos 4000 par fenêtre.
+- Script de bras : code/train_m8v1b.py (sha256 b2b12c8c6beb4b76954b6da99b0f273ca5eefad11268355786b8c3d420719e3c) — boucle = copie de SPIRA.train ; éval = eval_hits exécuté tel quel depuis checker/eval_ref_v3.py (e2c8cd1d…, lecture seule) ; fc2 via checker/windows_v2.py (7d9ed224…). Option --smoke-ticks réservée au smoke (jamais passée par la porte).
+- Points de reprise : par ÉPOQUE (W_rec, W_out, W_outG + historique + clé méta) — seul état appris qui survit à une époque (train_pass appelle core.reset()). **Reprise intra-époque NON faisable** sans modifier train_pass (non fait). Test d'équivalence (smoke/equiv, préfixe 3 Mo, snn 1500, am 20 000, 2 époques) : run arrêté après l'époque 1 puis repris = SPIRA.train original, **bit à bit** (empreintes W_rec/W_out/W_outG/AM keys/vals et historique identiques) pour cm ET ctl.
+
+## 5. Mesures smoke (plein échantillon, budgets réels 600k/1,2M pour build/prepare/AM/save ; passe SNN tronquée à 3000 ticks ; 1 fenêtre seen 500 positions)
+- ctl (11 h 53-11 h 55) : 72,3 t/s ; RSS plat pendant le SNN (601 216 ko de tick 500 à 2500 : pente ≈ 0) ; pic ru_maxrss 1 202,6 Mio (≈ 1,26 Go, à la sauvegarde/relecture) ; AM 16,5 s ; calibration+save ~74 s ; éval 6,0 s/500 positions seen ; ctl.npz 180 940 838 o.
+- cm (11 h 56-12 h 02, PID 184698) : 26,0 t/s ; RSS plat pendant le SNN (952 120 → 952 128 ko sur 3000 ticks) ; pic ru_maxrss 2 040,6 Mio (≈ 2,14 Go, à la sauvegarde/relecture) ; AM 14,2 s ; calibration+save ~185 s ; éval 17,9 s/500 positions seen ; cm.npz 394 081 898 o.
+- Estimations par bras (run complet, 2 × 600 000 ticks, 7 fenêtres × 4000) : ctl ≈ 16 700 s SNN + ~10 min (build/AM/save/éval) ≈ **4,8 h**, pic ≈ 1,3 Go (porte : 1,6 Go) ; cm ≈ 46 200 s SNN + ~25 min ≈ **13,3 h**, pic ≈ 2,1 Go (porte : 2,5 Go). Séquentiel ≈ 18 h ; parallèle (si les deux tiennent) ≈ 13,3 h. Vitesses mesurées avec 3 autres lourds sur la machine.
+
+## 6. Fenêtres et règle (verdict figé)
+- Script : **code/verdict_M8v1b.py** — sha256 en §8. Dérivé de lever2_sparse/code/verdict_SP.py (7a6d54145fdabd726d16d0c0f651d5509b561ac82b0b49d1ea1bbf858d9a2deb), chemin v4.2.
+- Fenêtres de la règle : seen (échantillon[:200 000], valide seulement si trained_frac ≥ 0,99 dans les deux bras, sinon NON COMPARABLE ⇒ NON MESURABLE) ; fc2 ; fresh_en ; fresh_fr ; test20k strict (masque lever2/verdict_AH1/mask_oldtest_strict.npz, 50fa08f9…, old_local_v1 ∪ broad_local_v1, recul 64 o ; échantillon : 0 position, vérifié par le recompte) ; test_v3 seulement si propre (recompte échantillon = 0 ET recompte v1b = 0 ET drapeau GO présent).
+- queries : rapportée À PART (hors règle). neither_code : exclue (non évaluée). freshcode m7 et broad_local_v1/test : exclues (contaminées).
+- Positions propres seulement : chaque fenêtre fraîche exige 0 position confirmée au recompte de l'échantillon, sinon exclue.
+- Statistiques : positions in-vocab dans les DEUX bras, taux appariés (même dénominateur), appariement par position (tokenisation identique vérifiée), McNemar exact bilatéral ; bootstrap apparié par blocs de 512 o, B = 10 000, seed 0.
+- Règle : **ADOPTÉ** ssi gain significatif (McNemar p < 0,05 ET c > b ET IC95 bootstrap > 0) sur seen ET sur ≥ 1 fenêtre fraîche valide, ET aucune perte significative (p < 0,05 ET b > c) sur une fenêtre valide (seen + fraîches valides). Sinon **REJETÉ**. **NON MESURABLE** si budgets cm/ctl inégaux (snn_tokens, am_tokens, epochs, ticks/époque, sha des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick ≠ snn_tokens), ou seen non comparable.
+
+## 7. Bogue signalé par Relay 12 h 07 — vérification et correction (révision 2 du verdict)
+- Signalement Relay : vtest (12 h 06) NON MESURABLE alors que budgets « identiques » ; diagnostic proposé : bogue d'unités (ticks 3000 comparés à tokens 600 000).
+- Vérification : dans /workspace/SPIRA/python/spira/spiking.py, SpikingCore.train_pass (l. 471-539) fait UN tick par token SNN (`neurons[t]` = token t, `T = len(cols)`, `"ticks": T`). Donc 1 tick = 1 token ; « 3000 ticks » = 3000 tokens entraînés sur 600 000 déclarés. Le vtest utilisait les modèles du SMOKE, dont la passe SNN était volontairement tronquée (--smoke-ticks 3000). Le NON MESURABLE était donc **correct** (passe incomplète), pas un bogue d'unités ; le diagnostic de Relay ne se vérifie pas. Les champs égaux cm == ctl étaient bien égaux.
+- Vrais défauts trouvés à cette occasion, corrigés : (1) la clause était implicite et le message (« budgets inégaux ou incohérents ») trompeur ⇒ unités rendues explicites (`TOKENS_PER_TICK = 1`, tokens entraînés/époque = ticks × TOKENS_PER_TICK comparés à snn_tokens), égalités cm == ctl gardées séparément (champ par champ), raison précise (« passe SNN incomplète … ») et bloc `budget_check` dans le json ; (2) **audit seen** : trained_frac était calculé avec snn_tokens DÉCLARÉ ; il l'est maintenant avec les tokens RÉELLEMENT entraînés (min sur époques de ticks × 1).
+- Ancienne version conservée : smoke/verdict_M8v1b.v1_69a6a739.py (sha256 69a6a73991458ad8da675190c2ac797311fbe117cb4c7656e441880d474e2da7, jamais soumise ni utilisée sur un run réel).
+- Re-test sur les mêmes entrées tronquées (smoke/vtest/verdict_r2) : toujours NON MESURABLE, raison désormais « passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000 ». Test mesurable : §9.
+- Checker 12 h 10 (spira_relay.md l. 7540-7545) : diagnostic Relay « bug d'unités » invalidé par Checker, clause à conserver, « logique validée » du script r2 (sha256 aa66889b…). Aucune modification depuis : le script de la porte est bien la r2.
+
+## 8. Script de verdict figé (r2)
+**code/verdict_M8v1b.py — sha256 aa66889b53e9566bedebd1e66679ed2c08b07f1fecff7d9a2e79d2e42a9fa8d3** (figé à 12 h 08 Toronto).
+Checker : PASS d'audit écrit demandé sur ce sha complet (relay, Hashing 12 h 17). Le drapeau GO_CHECKER_PASS reste NON posé jusqu'à ce PASS.
+Autres sha : train_m8v1b.py b2b12c8c6beb4b76954b6da99b0f273ca5eefad11268355786b8c3d420719e3c ; gate_m8v1b.sh d82871083e9cf1cab82dd209aff399599b9e8bdbe7a9e3699813f30fda52d617 ; run_guarded.sh f4bf377e601eca804a9383755ba863b3882c9b692624b0f21eb1e60c57076645 ; countmin.py caab5040… ; références : verdict_SP.py 7a6d5414…, train_cm_m8.py 4fa7c2d1… ; masque test20k 50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178 ; eval_ref_v3.py e2c8cd1deabc228faed302bebdb81bf8d10405df63e393b4a8ddb6152401c10e ; windows_v2.py 7d9ed224012184b19723c0254982878bc0a56102ef4722dd3d443ed6486869c1.
+
+## 9. Test mesurable du pipeline (vtest2, non décisionnel)
+Les deux bras ont été lancés sans troncature, avec un budget complet mais petit : snn 3000 (= 3000 ticks), am 1,2M, 1 époque, 7 fenêtres × 300 positions, --no-save. ctl : 12 h 08-12 h 11, pic 1,15 Go. cm : 12 h 11-12 h 17, pic 1,27 Go (min MemAvailable 5,69 Go). Ils ont été suivis du verdict r2, dont la copie ne diffère que par la ligne de chemins.
+Résultat : budget_ok True (ticks × 1 == snn_tokens pour les deux bras), seen COMPARABLE (trained_frac 1,0/1,0), sortie **mesurable** : REJETÉ (pas de gain sur seen ni sur une fenêtre fraîche). C'est un test non décisionnel. test_v3 est exclue parce que le drapeau est absent, comme prévu.
diff --git a/results/hashing/m8_v1b/code/drafts_r3/README_r3A_REJETEE.md b/results/hashing/m8_v1b/code/drafts_r3/README_r3A_REJETEE.md
new file mode 100644
index 0000000000000000000000000000000000000000..7ec00f598aee995a90975416c457703173da4849
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/README_r3A_REJETEE.md
@@ -0,0 +1,7 @@
+# r3A — REJETÉE par décision de Philippe-Antoine (24 oct, 13 h 00 Toronto)
+Décision écrite, mot pour mot : « on fige la règle B pour M8 v1b (recommandée par Checker). Procède avec ça. Continue code_scale_v1 et le reste vers la généralisation. Push les artefacts validés. »
+- verdict_M8v1b_r3A_DRAFT.py (sha256 389bdcb295cc0742e1883ea01ae6ded765f895358068b4ba0e2657d5873d81f2) : **REJETÉE** (règle A : gain seen exigé). Conservée pour trace, jamais utilisée ; rien supprimé.
+- Règle retenue : B. Version figée : ../verdict_M8v1b.py = verdict_M8v1b_r3B_FROZEN.py, sha256 b3db0875b6e01d2c2192d9e307d337a3fb908f524f7be5e3a9a5b380eec7d7dc
+ (brouillon cb27a4a57e1d97456ef7a2691ba6a7a64a3a6ac026798900f34533c580ed4f93 + docstring l.13 seule, diff : r3B_FROZEN_vs_cb27a4a5.diff).
+- r2 archivée : ../verdict_M8v1b.r2.py (aa66889b53e9566bedebd1e66679ed2c08b07f1fecff7d9a2e79d2e42a9fa8d3).
+Écrit le 2026-10-24 13:02 EDT — SPIRA Hashing
diff --git a/results/hashing/m8_v1b/code/drafts_r3/make_drafts.py b/results/hashing/m8_v1b/code/drafts_r3/make_drafts.py
new file mode 100644
index 0000000000000000000000000000000000000000..915231ac77ecc81b2b982055d5ac954cca7f88f6
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/make_drafts.py
@@ -0,0 +1,42 @@
+# Génère les brouillons r3 (A, B) à partir de verdict_M8v1b.py r2 (aa66889b…) par remplacements textuels exacts (assert sur chaque).
+import hashlib
+src = open("../verdict_M8v1b.py").read()
+assert hashlib.sha256(src.encode()).hexdigest() == "aa66889b53e9566bedebd1e66679ed2c08b07f1fecff7d9a2e79d2e42a9fa8d3"
+def rep(s, a, b):
+ assert s.count(a) == 1, a[:60]; return s.replace(a, b)
+common = [
+ ('import sys, os, json, math, hashlib, numpy as np\nB8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; D = f"{B8}/runs"; OP = f"{B8}/verdict"; RT, CT = "ctl", "cm"',
+ 'import sys, os, json, math, hashlib, argparse, numpy as np\n'
+ 'B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; RT, CT = "ctl", "cm"\n'
+ '_ap = argparse.ArgumentParser(); _ap.add_argument("--runs", default=f"{B8}/runs"); _ap.add_argument("--outdir", default=f"{B8}/verdict")\n'
+ '_ap.add_argument("--scale-lo", type=float, default=0.03); _ap.add_argument("--scale-hi", type=float, default=0.11) # bornes À CONFIRMER par Philippe-Antoine\n'
+ '_a = _ap.parse_args(); D, OP, SCALE_LO, SCALE_HI = _a.runs, _a.outdir, _a.scale_lo, _a.scale_hi'),
+ ('BUDGET_CHECK = {"equal_cm_ctl"',
+ '# ---- garde d\'échelle de fusion (r3) : NON MESURABLE si cal.scale d\'un bras hors [SCALE_LO ; SCALE_HI] (lu dans results.jsonl)\n'
+ 'def _scale(arm):\n'
+ ' c = arm_field(arm, "cal"); return c.get("scale") if isinstance(c, dict) else None\n'
+ 'SCALE = {x: _scale(x) for x in (RT, CT)}\n'
+ 'SCALE_OK = all(isinstance(SCALE[x], (int, float)) and SCALE_LO <= SCALE[x] <= SCALE_HI for x in (RT, CT))\n'
+ 'SCALE_CHECK = {"scale": SCALE, "lo": SCALE_LO, "hi": SCALE_HI, "ok": SCALE_OK}\n'
+ 'BUDGET_CHECK = {"equal_cm_ctl"'),
+ ('if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")\nif BUDGET_OK and SEEN_OK:',
+ 'if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")\n'
+ 'if not SCALE_OK: why.append(f"fusion.scale hors [{SCALE_LO} ; {SCALE_HI}] : ctl {SCALE[RT]} / cm {SCALE[CT]}")\n'
+ 'if BUDGET_OK and SEEN_OK and SCALE_OK:'),
+ ('"budget_ok": BUDGET_OK,', '"budget_ok": BUDGET_OK, "scale_check": SCALE_CHECK,'),
+]
+VA = [('Révision 2 (12 h 08 Toronto)', 'BROUILLON r3-A (NON FIGÉ) : règle r2 inchangée + garde fusion.scale [lo ; hi] (défaut 0,03/0,11) + chemins en paramètres.\nRévision 2 (12 h 08 Toronto)')]
+VB = [('Révision 2 (12 h 08 Toronto)', 'BROUILLON r3-B (NON FIGÉ) : règle v4.2 (Checker 12 h 20) + garde fusion.scale [lo ; hi] (défaut 0,03/0,11) + chemins en paramètres.\nRévision 2 (12 h 08 Toronto)'),
+ ('Règle : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche valide', 'Règle (r3-B) : ADOPTÉ ssi gain significatif sur >=1 fenêtre fraîche valide'),
+ ('ET aucune perte significative sur une fenêtre valide (seen + fraîches valides) ; sinon REJETÉ."""', 'ET aucune perte significative sur une fenêtre valide (seen + fraîches valides ; égalité sur seen admise) ; sinon REJETÉ ;\nNON MESURABLE aussi si fusion.scale d\'un bras hors [lo ; hi]."""'),
+ (' dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"\n if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")\n',
+ ' dec = "ADOPTÉ" if (GF and not L) else "REJETÉ"\n'),
+ ('"rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide',
+ '"rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur >=1 fenêtre fraîche valide'),
+ ('ou seen non comparable",', 'ou seen non comparable ou fusion.scale hors [lo ; hi]",'),
+]
+VA += [('ou seen non comparable",', 'ou seen non comparable ou fusion.scale hors [lo ; hi]",')]
+for name, extra in (("verdict_M8v1b_r3A_DRAFT.py", VA), ("verdict_M8v1b_r3B_DRAFT.py", VB)):
+ s = src
+ for a, b in common + extra: s = rep(s, a, b)
+ open(name, "w").write(s); print(name, hashlib.sha256(s.encode()).hexdigest())
diff --git a/results/hashing/m8_v1b/code/drafts_r3/r3A_vs_prev.diff b/results/hashing/m8_v1b/code/drafts_r3/r3A_vs_prev.diff
new file mode 100644
index 0000000000000000000000000000000000000000..4ce878b6ab5962dbbee94b62af5d5182e4829c81
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/r3A_vs_prev.diff
@@ -0,0 +1,13 @@
+--- verdict_M8v1b_r3A_DRAFT.py.prev 2026-10-24 09:25:14.689184228 -0700
++++ verdict_M8v1b_r3A_DRAFT.py 2026-10-24 09:50:39.002040448 -0700
+@@ -17,8 +17,8 @@
+ import sys, os, json, math, hashlib, argparse, numpy as np
+ B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; RT, CT = "ctl", "cm"
+ _ap = argparse.ArgumentParser(); _ap.add_argument("--runs", default=f"{B8}/runs"); _ap.add_argument("--outdir", default=f"{B8}/verdict")
+-_ap.add_argument("--scale-lo", type=float, default=0.03); _ap.add_argument("--scale-hi", type=float, default=0.11) # bornes À CONFIRMER par Philippe-Antoine
+-_a = _ap.parse_args(); D, OP, SCALE_LO, SCALE_HI = _a.runs, _a.outdir, _a.scale_lo, _a.scale_hi
++SCALE_LO = 0.03; SCALE_HI = 0.11 # bornes EN DUR, non surchargeables ; plage PROVISOIRE, en attente de la décision de Philippe-Antoine
++_a = _ap.parse_args(); D, OP = _a.runs, _a.outdir
+ SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+ GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
diff --git a/results/hashing/m8_v1b/code/drafts_r3/r3A_vs_r2.diff b/results/hashing/m8_v1b/code/drafts_r3/r3A_vs_r2.diff
new file mode 100644
index 0000000000000000000000000000000000000000..54d9505b2f02cd9b49a373f5bcf7e3413cc9faaf
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/r3A_vs_r2.diff
@@ -0,0 +1,54 @@
+--- ../verdict_M8v1b.py 2026-10-24 12:08:22.916650836 -0400
++++ verdict_M8v1b_r3A_DRAFT.py 2026-10-24 12:25:14.689184228 -0400
+@@ -10,11 +10,15 @@
+ IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+ epochs, ticks/époque, sha256 des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick != snn_tokens), ou seen NON COMPARABLE
+ (trained_frac < 0,99 dans un bras ; trained_frac calculé sur les tokens RÉELLEMENT entraînés = ticks × 1, pas sur snn_tokens déclaré).
++BROUILLON r3-A (NON FIGÉ) : règle r2 inchangée + garde fusion.scale [lo ; hi] (défaut 0,03/0,11) + chemins en paramètres.
+ Révision 2 (12 h 08 Toronto) : contrôle d'unités rendu explicite (TOKENS_PER_TICK = 1, spiking.py l. 471-539) et audit seen sur tokens réellement entraînés.
+ Règle : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+ ET aucune perte significative sur une fenêtre valide (seen + fraîches valides) ; sinon REJETÉ."""
+-import sys, os, json, math, hashlib, numpy as np
+-B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; D = f"{B8}/runs"; OP = f"{B8}/verdict"; RT, CT = "ctl", "cm"
++import sys, os, json, math, hashlib, argparse, numpy as np
++B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; RT, CT = "ctl", "cm"
++_ap = argparse.ArgumentParser(); _ap.add_argument("--runs", default=f"{B8}/runs"); _ap.add_argument("--outdir", default=f"{B8}/verdict")
++_ap.add_argument("--scale-lo", type=float, default=0.03); _ap.add_argument("--scale-hi", type=float, default=0.11) # bornes À CONFIRMER par Philippe-Antoine
++_a = _ap.parse_args(); D, OP, SCALE_LO, SCALE_HI = _a.runs, _a.outdir, _a.scale_lo, _a.scale_hi
+ SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+ GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+@@ -41,6 +45,12 @@
+ FULL = {x: (TRAINED[x] is not None and isinstance(BUD["epochs"][x], int) and len(TRAINED[x]) == BUD["epochs"][x]
+ and all(t == BUD["snn_tokens"][x] for t in TRAINED[x])) for x in (RT, CT)}
+ BUDGET_OK = all(EQUAL.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA and FULL[RT] and FULL[CT]
++# ---- garde d'échelle de fusion (r3) : NON MESURABLE si cal.scale d'un bras hors [SCALE_LO ; SCALE_HI] (lu dans results.jsonl)
++def _scale(arm):
++ c = arm_field(arm, "cal"); return c.get("scale") if isinstance(c, dict) else None
++SCALE = {x: _scale(x) for x in (RT, CT)}
++SCALE_OK = all(isinstance(SCALE[x], (int, float)) and SCALE_LO <= SCALE[x] <= SCALE_HI for x in (RT, CT))
++SCALE_CHECK = {"scale": SCALE, "lo": SCALE_LO, "hi": SCALE_HI, "ok": SCALE_OK}
+ BUDGET_CHECK = {"equal_cm_ctl": EQUAL, "data_is_sample": BUD["data_sha256"][RT] == SAMPLE_SHA, "tokens_per_tick": TOKENS_PER_TICK,
+ "trained_snn_tokens_per_epoch": TRAINED, "full_budget_each_epoch": FULL}
+ # tokens SNN réellement entraînés (pour l'audit seen) = min sur les époques de ticks × TOKENS_PER_TICK, borné par snn_tokens
+@@ -126,16 +136,17 @@
+ if BUD["data_sha256"][RT] != SAMPLE_SHA: why.append("données != échantillon v1b")
+ if not (FULL[RT] and FULL[CT]): why.append(f"passe SNN incomplète : tokens entraînés/époque (ticks × {TOKENS_PER_TICK}) ctl {TRAINED[RT]} / cm {TRAINED[CT]} != snn_tokens {BUD['snn_tokens'][RT]}")
+ if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+-if BUDGET_OK and SEEN_OK:
++if not SCALE_OK: why.append(f"fusion.scale hors [{SCALE_LO} ; {SCALE_HI}] : ctl {SCALE[RT]} / cm {SCALE[CT]}")
++if BUDGET_OK and SEEN_OK and SCALE_OK:
+ dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+ if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+ else: dec = "NON MESURABLE"
+ out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+- "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
++ "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "scale_check": SCALE_CHECK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+- "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable",
++ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
diff --git a/results/hashing/m8_v1b/code/drafts_r3/r3A_vs_r2_v2.diff b/results/hashing/m8_v1b/code/drafts_r3/r3A_vs_r2_v2.diff
new file mode 100644
index 0000000000000000000000000000000000000000..20d81271725950def7b9a5c1848fcbe0d84ab715
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/r3A_vs_r2_v2.diff
@@ -0,0 +1,54 @@
+--- ../verdict_M8v1b.py 2026-10-24 09:08:22.916650836 -0700
++++ verdict_M8v1b_r3A_DRAFT.py 2026-10-24 09:50:39.002040448 -0700
+@@ -10,11 +10,15 @@
+ IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+ epochs, ticks/époque, sha256 des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick != snn_tokens), ou seen NON COMPARABLE
+ (trained_frac < 0,99 dans un bras ; trained_frac calculé sur les tokens RÉELLEMENT entraînés = ticks × 1, pas sur snn_tokens déclaré).
++BROUILLON r3-A (NON FIGÉ) : règle r2 inchangée + garde fusion.scale [lo ; hi] (défaut 0,03/0,11) + chemins en paramètres.
+ Révision 2 (12 h 08 Toronto) : contrôle d'unités rendu explicite (TOKENS_PER_TICK = 1, spiking.py l. 471-539) et audit seen sur tokens réellement entraînés.
+ Règle : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+ ET aucune perte significative sur une fenêtre valide (seen + fraîches valides) ; sinon REJETÉ."""
+-import sys, os, json, math, hashlib, numpy as np
+-B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; D = f"{B8}/runs"; OP = f"{B8}/verdict"; RT, CT = "ctl", "cm"
++import sys, os, json, math, hashlib, argparse, numpy as np
++B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; RT, CT = "ctl", "cm"
++_ap = argparse.ArgumentParser(); _ap.add_argument("--runs", default=f"{B8}/runs"); _ap.add_argument("--outdir", default=f"{B8}/verdict")
++SCALE_LO = 0.03; SCALE_HI = 0.11 # bornes EN DUR, non surchargeables ; plage PROVISOIRE, en attente de la décision de Philippe-Antoine
++_a = _ap.parse_args(); D, OP = _a.runs, _a.outdir
+ SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+ GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+@@ -41,6 +45,12 @@
+ FULL = {x: (TRAINED[x] is not None and isinstance(BUD["epochs"][x], int) and len(TRAINED[x]) == BUD["epochs"][x]
+ and all(t == BUD["snn_tokens"][x] for t in TRAINED[x])) for x in (RT, CT)}
+ BUDGET_OK = all(EQUAL.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA and FULL[RT] and FULL[CT]
++# ---- garde d'échelle de fusion (r3) : NON MESURABLE si cal.scale d'un bras hors [SCALE_LO ; SCALE_HI] (lu dans results.jsonl)
++def _scale(arm):
++ c = arm_field(arm, "cal"); return c.get("scale") if isinstance(c, dict) else None
++SCALE = {x: _scale(x) for x in (RT, CT)}
++SCALE_OK = all(isinstance(SCALE[x], (int, float)) and SCALE_LO <= SCALE[x] <= SCALE_HI for x in (RT, CT))
++SCALE_CHECK = {"scale": SCALE, "lo": SCALE_LO, "hi": SCALE_HI, "ok": SCALE_OK}
+ BUDGET_CHECK = {"equal_cm_ctl": EQUAL, "data_is_sample": BUD["data_sha256"][RT] == SAMPLE_SHA, "tokens_per_tick": TOKENS_PER_TICK,
+ "trained_snn_tokens_per_epoch": TRAINED, "full_budget_each_epoch": FULL}
+ # tokens SNN réellement entraînés (pour l'audit seen) = min sur les époques de ticks × TOKENS_PER_TICK, borné par snn_tokens
+@@ -126,16 +136,17 @@
+ if BUD["data_sha256"][RT] != SAMPLE_SHA: why.append("données != échantillon v1b")
+ if not (FULL[RT] and FULL[CT]): why.append(f"passe SNN incomplète : tokens entraînés/époque (ticks × {TOKENS_PER_TICK}) ctl {TRAINED[RT]} / cm {TRAINED[CT]} != snn_tokens {BUD['snn_tokens'][RT]}")
+ if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+-if BUDGET_OK and SEEN_OK:
++if not SCALE_OK: why.append(f"fusion.scale hors [{SCALE_LO} ; {SCALE_HI}] : ctl {SCALE[RT]} / cm {SCALE[CT]}")
++if BUDGET_OK and SEEN_OK and SCALE_OK:
+ dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+ if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+ else: dec = "NON MESURABLE"
+ out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+- "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
++ "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "scale_check": SCALE_CHECK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+- "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable",
++ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
diff --git a/results/hashing/m8_v1b/code/drafts_r3/r3B_FROZEN_vs_cb27a4a5.diff b/results/hashing/m8_v1b/code/drafts_r3/r3B_FROZEN_vs_cb27a4a5.diff
new file mode 100644
index 0000000000000000000000000000000000000000..51ae26d6624b33f4ed0ac00d70ad6483a39ee365
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/r3B_FROZEN_vs_cb27a4a5.diff
@@ -0,0 +1,11 @@
+--- drafts_r3/verdict_M8v1b_r3B_DRAFT.py 2026-10-24 12:50:39.002040448 -0400
++++ drafts_r3/verdict_M8v1b_r3B_FROZEN.py 2026-10-24 13:02:08.943859487 -0400
+@@ -10,7 +10,7 @@
+ IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+ epochs, ticks/époque, sha256 des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick != snn_tokens), ou seen NON COMPARABLE
+ (trained_frac < 0,99 dans un bras ; trained_frac calculé sur les tokens RÉELLEMENT entraînés = ticks × 1, pas sur snn_tokens déclaré).
+-BROUILLON r3-B (NON FIGÉ) : règle v4.2 (Checker 12 h 20) + garde fusion.scale [lo ; hi] (défaut 0,03/0,11) + chemins en paramètres.
++Révision 3-B (figée le 24 oct, décision de Philippe-Antoine 13 h 00 Toronto) : règle v4.2 (Checker 12 h 20) + garde fusion.scale, bornes en dur [0,03 ; 0,11] (non surchargeables) + chemins --runs/--outdir en paramètres.
+ Révision 2 (12 h 08 Toronto) : contrôle d'unités rendu explicite (TOKENS_PER_TICK = 1, spiking.py l. 471-539) et audit seen sur tokens réellement entraînés.
+ Règle (r3-B) : ADOPTÉ ssi gain significatif sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+ ET aucune perte significative sur une fenêtre valide (seen + fraîches valides ; égalité sur seen admise) ; sinon REJETÉ ;
diff --git a/results/hashing/m8_v1b/code/drafts_r3/r3B_FROZEN_vs_r2.diff b/results/hashing/m8_v1b/code/drafts_r3/r3B_FROZEN_vs_r2.diff
new file mode 100644
index 0000000000000000000000000000000000000000..b86229ff9c0246e61197265e27c9fb98e462e61f
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/r3B_FROZEN_vs_r2.diff
@@ -0,0 +1,58 @@
+--- verdict_M8v1b.r2.py 2026-10-24 12:08:22.916650836 -0400
++++ verdict_M8v1b.py 2026-10-24 13:02:24.839993556 -0400
+@@ -10,11 +10,16 @@
+ IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+ epochs, ticks/époque, sha256 des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick != snn_tokens), ou seen NON COMPARABLE
+ (trained_frac < 0,99 dans un bras ; trained_frac calculé sur les tokens RÉELLEMENT entraînés = ticks × 1, pas sur snn_tokens déclaré).
++Révision 3-B (figée le 24 oct, décision de Philippe-Antoine 13 h 00 Toronto) : règle v4.2 (Checker 12 h 20) + garde fusion.scale, bornes en dur [0,03 ; 0,11] (non surchargeables) + chemins --runs/--outdir en paramètres.
+ Révision 2 (12 h 08 Toronto) : contrôle d'unités rendu explicite (TOKENS_PER_TICK = 1, spiking.py l. 471-539) et audit seen sur tokens réellement entraînés.
+-Règle : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+-ET aucune perte significative sur une fenêtre valide (seen + fraîches valides) ; sinon REJETÉ."""
+-import sys, os, json, math, hashlib, numpy as np
+-B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; D = f"{B8}/runs"; OP = f"{B8}/verdict"; RT, CT = "ctl", "cm"
++Règle (r3-B) : ADOPTÉ ssi gain significatif sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
++ET aucune perte significative sur une fenêtre valide (seen + fraîches valides ; égalité sur seen admise) ; sinon REJETÉ ;
++NON MESURABLE aussi si fusion.scale d'un bras hors [lo ; hi]."""
++import sys, os, json, math, hashlib, argparse, numpy as np
++B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; RT, CT = "ctl", "cm"
++_ap = argparse.ArgumentParser(); _ap.add_argument("--runs", default=f"{B8}/runs"); _ap.add_argument("--outdir", default=f"{B8}/verdict")
++SCALE_LO = 0.03; SCALE_HI = 0.11 # bornes EN DUR, non surchargeables ; plage PROVISOIRE, en attente de la décision de Philippe-Antoine
++_a = _ap.parse_args(); D, OP = _a.runs, _a.outdir
+ SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+ GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+@@ -41,6 +46,12 @@
+ FULL = {x: (TRAINED[x] is not None and isinstance(BUD["epochs"][x], int) and len(TRAINED[x]) == BUD["epochs"][x]
+ and all(t == BUD["snn_tokens"][x] for t in TRAINED[x])) for x in (RT, CT)}
+ BUDGET_OK = all(EQUAL.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA and FULL[RT] and FULL[CT]
++# ---- garde d'échelle de fusion (r3) : NON MESURABLE si cal.scale d'un bras hors [SCALE_LO ; SCALE_HI] (lu dans results.jsonl)
++def _scale(arm):
++ c = arm_field(arm, "cal"); return c.get("scale") if isinstance(c, dict) else None
++SCALE = {x: _scale(x) for x in (RT, CT)}
++SCALE_OK = all(isinstance(SCALE[x], (int, float)) and SCALE_LO <= SCALE[x] <= SCALE_HI for x in (RT, CT))
++SCALE_CHECK = {"scale": SCALE, "lo": SCALE_LO, "hi": SCALE_HI, "ok": SCALE_OK}
+ BUDGET_CHECK = {"equal_cm_ctl": EQUAL, "data_is_sample": BUD["data_sha256"][RT] == SAMPLE_SHA, "tokens_per_tick": TOKENS_PER_TICK,
+ "trained_snn_tokens_per_epoch": TRAINED, "full_budget_each_epoch": FULL}
+ # tokens SNN réellement entraînés (pour l'audit seen) = min sur les époques de ticks × TOKENS_PER_TICK, borné par snn_tokens
+@@ -126,16 +137,16 @@
+ if BUD["data_sha256"][RT] != SAMPLE_SHA: why.append("données != échantillon v1b")
+ if not (FULL[RT] and FULL[CT]): why.append(f"passe SNN incomplète : tokens entraînés/époque (ticks × {TOKENS_PER_TICK}) ctl {TRAINED[RT]} / cm {TRAINED[CT]} != snn_tokens {BUD['snn_tokens'][RT]}")
+ if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+-if BUDGET_OK and SEEN_OK:
+- dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+- if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
++if not SCALE_OK: why.append(f"fusion.scale hors [{SCALE_LO} ; {SCALE_HI}] : ctl {SCALE[RT]} / cm {SCALE[CT]}")
++if BUDGET_OK and SEEN_OK and SCALE_OK:
++ dec = "ADOPTÉ" if (GF and not L) else "REJETÉ"
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+ else: dec = "NON MESURABLE"
+ out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+- "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
++ "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "scale_check": SCALE_CHECK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+- "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable",
++ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
diff --git a/results/hashing/m8_v1b/code/drafts_r3/r3B_vs_prev.diff b/results/hashing/m8_v1b/code/drafts_r3/r3B_vs_prev.diff
new file mode 100644
index 0000000000000000000000000000000000000000..a049d63810a93ad5e5a8008e12d9f8bdd2c10c41
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/r3B_vs_prev.diff
@@ -0,0 +1,13 @@
+--- verdict_M8v1b_r3B_DRAFT.py.prev 2026-10-24 09:25:14.689184228 -0700
++++ verdict_M8v1b_r3B_DRAFT.py 2026-10-24 09:50:39.002040448 -0700
+@@ -18,8 +18,8 @@
+ import sys, os, json, math, hashlib, argparse, numpy as np
+ B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; RT, CT = "ctl", "cm"
+ _ap = argparse.ArgumentParser(); _ap.add_argument("--runs", default=f"{B8}/runs"); _ap.add_argument("--outdir", default=f"{B8}/verdict")
+-_ap.add_argument("--scale-lo", type=float, default=0.03); _ap.add_argument("--scale-hi", type=float, default=0.11) # bornes À CONFIRMER par Philippe-Antoine
+-_a = _ap.parse_args(); D, OP, SCALE_LO, SCALE_HI = _a.runs, _a.outdir, _a.scale_lo, _a.scale_hi
++SCALE_LO = 0.03; SCALE_HI = 0.11 # bornes EN DUR, non surchargeables ; plage PROVISOIRE, en attente de la décision de Philippe-Antoine
++_a = _ap.parse_args(); D, OP = _a.runs, _a.outdir
+ SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+ GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
diff --git a/results/hashing/m8_v1b/code/drafts_r3/r3B_vs_r2.diff b/results/hashing/m8_v1b/code/drafts_r3/r3B_vs_r2.diff
new file mode 100644
index 0000000000000000000000000000000000000000..21c534bee6287a52fc31dca80b241422add8c41c
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/r3B_vs_r2.diff
@@ -0,0 +1,58 @@
+--- ../verdict_M8v1b.py 2026-10-24 12:08:22.916650836 -0400
++++ verdict_M8v1b_r3B_DRAFT.py 2026-10-24 12:25:14.689184228 -0400
+@@ -10,11 +10,16 @@
+ IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+ epochs, ticks/époque, sha256 des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick != snn_tokens), ou seen NON COMPARABLE
+ (trained_frac < 0,99 dans un bras ; trained_frac calculé sur les tokens RÉELLEMENT entraînés = ticks × 1, pas sur snn_tokens déclaré).
++BROUILLON r3-B (NON FIGÉ) : règle v4.2 (Checker 12 h 20) + garde fusion.scale [lo ; hi] (défaut 0,03/0,11) + chemins en paramètres.
+ Révision 2 (12 h 08 Toronto) : contrôle d'unités rendu explicite (TOKENS_PER_TICK = 1, spiking.py l. 471-539) et audit seen sur tokens réellement entraînés.
+-Règle : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+-ET aucune perte significative sur une fenêtre valide (seen + fraîches valides) ; sinon REJETÉ."""
+-import sys, os, json, math, hashlib, numpy as np
+-B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; D = f"{B8}/runs"; OP = f"{B8}/verdict"; RT, CT = "ctl", "cm"
++Règle (r3-B) : ADOPTÉ ssi gain significatif sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
++ET aucune perte significative sur une fenêtre valide (seen + fraîches valides ; égalité sur seen admise) ; sinon REJETÉ ;
++NON MESURABLE aussi si fusion.scale d'un bras hors [lo ; hi]."""
++import sys, os, json, math, hashlib, argparse, numpy as np
++B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; RT, CT = "ctl", "cm"
++_ap = argparse.ArgumentParser(); _ap.add_argument("--runs", default=f"{B8}/runs"); _ap.add_argument("--outdir", default=f"{B8}/verdict")
++_ap.add_argument("--scale-lo", type=float, default=0.03); _ap.add_argument("--scale-hi", type=float, default=0.11) # bornes À CONFIRMER par Philippe-Antoine
++_a = _ap.parse_args(); D, OP, SCALE_LO, SCALE_HI = _a.runs, _a.outdir, _a.scale_lo, _a.scale_hi
+ SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+ GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+@@ -41,6 +46,12 @@
+ FULL = {x: (TRAINED[x] is not None and isinstance(BUD["epochs"][x], int) and len(TRAINED[x]) == BUD["epochs"][x]
+ and all(t == BUD["snn_tokens"][x] for t in TRAINED[x])) for x in (RT, CT)}
+ BUDGET_OK = all(EQUAL.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA and FULL[RT] and FULL[CT]
++# ---- garde d'échelle de fusion (r3) : NON MESURABLE si cal.scale d'un bras hors [SCALE_LO ; SCALE_HI] (lu dans results.jsonl)
++def _scale(arm):
++ c = arm_field(arm, "cal"); return c.get("scale") if isinstance(c, dict) else None
++SCALE = {x: _scale(x) for x in (RT, CT)}
++SCALE_OK = all(isinstance(SCALE[x], (int, float)) and SCALE_LO <= SCALE[x] <= SCALE_HI for x in (RT, CT))
++SCALE_CHECK = {"scale": SCALE, "lo": SCALE_LO, "hi": SCALE_HI, "ok": SCALE_OK}
+ BUDGET_CHECK = {"equal_cm_ctl": EQUAL, "data_is_sample": BUD["data_sha256"][RT] == SAMPLE_SHA, "tokens_per_tick": TOKENS_PER_TICK,
+ "trained_snn_tokens_per_epoch": TRAINED, "full_budget_each_epoch": FULL}
+ # tokens SNN réellement entraînés (pour l'audit seen) = min sur les époques de ticks × TOKENS_PER_TICK, borné par snn_tokens
+@@ -126,16 +137,16 @@
+ if BUD["data_sha256"][RT] != SAMPLE_SHA: why.append("données != échantillon v1b")
+ if not (FULL[RT] and FULL[CT]): why.append(f"passe SNN incomplète : tokens entraînés/époque (ticks × {TOKENS_PER_TICK}) ctl {TRAINED[RT]} / cm {TRAINED[CT]} != snn_tokens {BUD['snn_tokens'][RT]}")
+ if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+-if BUDGET_OK and SEEN_OK:
+- dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+- if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
++if not SCALE_OK: why.append(f"fusion.scale hors [{SCALE_LO} ; {SCALE_HI}] : ctl {SCALE[RT]} / cm {SCALE[CT]}")
++if BUDGET_OK and SEEN_OK and SCALE_OK:
++ dec = "ADOPTÉ" if (GF and not L) else "REJETÉ"
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+ else: dec = "NON MESURABLE"
+ out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+- "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
++ "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "scale_check": SCALE_CHECK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+- "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable",
++ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
diff --git a/results/hashing/m8_v1b/code/drafts_r3/r3B_vs_r2_v2.diff b/results/hashing/m8_v1b/code/drafts_r3/r3B_vs_r2_v2.diff
new file mode 100644
index 0000000000000000000000000000000000000000..c8e6e99787f7226b1a45ef6f2a8b8ec0ba0170f8
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/r3B_vs_r2_v2.diff
@@ -0,0 +1,58 @@
+--- ../verdict_M8v1b.py 2026-10-24 09:08:22.916650836 -0700
++++ verdict_M8v1b_r3B_DRAFT.py 2026-10-24 09:50:39.002040448 -0700
+@@ -10,11 +10,16 @@
+ IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+ epochs, ticks/époque, sha256 des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick != snn_tokens), ou seen NON COMPARABLE
+ (trained_frac < 0,99 dans un bras ; trained_frac calculé sur les tokens RÉELLEMENT entraînés = ticks × 1, pas sur snn_tokens déclaré).
++BROUILLON r3-B (NON FIGÉ) : règle v4.2 (Checker 12 h 20) + garde fusion.scale [lo ; hi] (défaut 0,03/0,11) + chemins en paramètres.
+ Révision 2 (12 h 08 Toronto) : contrôle d'unités rendu explicite (TOKENS_PER_TICK = 1, spiking.py l. 471-539) et audit seen sur tokens réellement entraînés.
+-Règle : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+-ET aucune perte significative sur une fenêtre valide (seen + fraîches valides) ; sinon REJETÉ."""
+-import sys, os, json, math, hashlib, numpy as np
+-B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; D = f"{B8}/runs"; OP = f"{B8}/verdict"; RT, CT = "ctl", "cm"
++Règle (r3-B) : ADOPTÉ ssi gain significatif sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
++ET aucune perte significative sur une fenêtre valide (seen + fraîches valides ; égalité sur seen admise) ; sinon REJETÉ ;
++NON MESURABLE aussi si fusion.scale d'un bras hors [lo ; hi]."""
++import sys, os, json, math, hashlib, argparse, numpy as np
++B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; RT, CT = "ctl", "cm"
++_ap = argparse.ArgumentParser(); _ap.add_argument("--runs", default=f"{B8}/runs"); _ap.add_argument("--outdir", default=f"{B8}/verdict")
++SCALE_LO = 0.03; SCALE_HI = 0.11 # bornes EN DUR, non surchargeables ; plage PROVISOIRE, en attente de la décision de Philippe-Antoine
++_a = _ap.parse_args(); D, OP = _a.runs, _a.outdir
+ SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+ GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+@@ -41,6 +46,12 @@
+ FULL = {x: (TRAINED[x] is not None and isinstance(BUD["epochs"][x], int) and len(TRAINED[x]) == BUD["epochs"][x]
+ and all(t == BUD["snn_tokens"][x] for t in TRAINED[x])) for x in (RT, CT)}
+ BUDGET_OK = all(EQUAL.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA and FULL[RT] and FULL[CT]
++# ---- garde d'échelle de fusion (r3) : NON MESURABLE si cal.scale d'un bras hors [SCALE_LO ; SCALE_HI] (lu dans results.jsonl)
++def _scale(arm):
++ c = arm_field(arm, "cal"); return c.get("scale") if isinstance(c, dict) else None
++SCALE = {x: _scale(x) for x in (RT, CT)}
++SCALE_OK = all(isinstance(SCALE[x], (int, float)) and SCALE_LO <= SCALE[x] <= SCALE_HI for x in (RT, CT))
++SCALE_CHECK = {"scale": SCALE, "lo": SCALE_LO, "hi": SCALE_HI, "ok": SCALE_OK}
+ BUDGET_CHECK = {"equal_cm_ctl": EQUAL, "data_is_sample": BUD["data_sha256"][RT] == SAMPLE_SHA, "tokens_per_tick": TOKENS_PER_TICK,
+ "trained_snn_tokens_per_epoch": TRAINED, "full_budget_each_epoch": FULL}
+ # tokens SNN réellement entraînés (pour l'audit seen) = min sur les époques de ticks × TOKENS_PER_TICK, borné par snn_tokens
+@@ -126,16 +137,16 @@
+ if BUD["data_sha256"][RT] != SAMPLE_SHA: why.append("données != échantillon v1b")
+ if not (FULL[RT] and FULL[CT]): why.append(f"passe SNN incomplète : tokens entraînés/époque (ticks × {TOKENS_PER_TICK}) ctl {TRAINED[RT]} / cm {TRAINED[CT]} != snn_tokens {BUD['snn_tokens'][RT]}")
+ if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+-if BUDGET_OK and SEEN_OK:
+- dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+- if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
++if not SCALE_OK: why.append(f"fusion.scale hors [{SCALE_LO} ; {SCALE_HI}] : ctl {SCALE[RT]} / cm {SCALE[CT]}")
++if BUDGET_OK and SEEN_OK and SCALE_OK:
++ dec = "ADOPTÉ" if (GF and not L) else "REJETÉ"
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+ else: dec = "NON MESURABLE"
+ out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+- "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
++ "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "scale_check": SCALE_CHECK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+- "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable",
++ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
diff --git a/results/hashing/m8_v1b/code/drafts_r3/relay_1227.txt b/results/hashing/m8_v1b/code/drafts_r3/relay_1227.txt
new file mode 100644
index 0000000000000000000000000000000000000000..54f8f62360ea2b77ed1208c1019d3ca4b553cf86
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/relay_1227.txt
@@ -0,0 +1,22 @@
+
+### Lu/appliqué — Hashing — 12 h 27 (Toronto) — PASS de push train_m8v1b, lancement M8 v1b NON fait, brouillons r3 A/B (NON figés)
+- **Push HF fait (add-only)** : commit **40f1edd616bec6493673386229f089054256cc49** (12 h 24 m 44), 1 ajout : results/hashing/m8_v1b/code/train_m8v1b.py (10 859 o, sha256 b2b12c8c6beb4b76954b6da99b0f273ca5eefad11268355786b8c3d420719e3c). 0 modif, 0 suppression (530 → 531). Retéléchargé (hashing_gen/push_m8v1b_train/hf_check/) : sha256 identique. Consigné dans hf_pushed.txt. Base : PASS de push écrit de Checker 12 h 20 (l. 7596 : « PASS de push : train_m8v1b.py (b2b12c8c…3e9c) accordé sous v3_scale/results/hashing/ ») et Checker worker 2 12 h 23 (l. 7660 : « Push sous results/hashing/ — contenu : PASS pour les deux scripts »). Chemin utilisé : results/hashing/ (comme tous les pushes Hashing et comme worker 2), pas v3_scale/results/hashing/ : **Checker, à confirmer**. Note : worker 2 garde le FAIL d'audit de train_m8v1b.py « en l'état » (garde d'échelle absente) ; le push archive le script figé, ce n'est pas un PASS d'audit. **verdict_M8v1b.py NON poussé** (r2 non validée, r3 non figée).
+- **Entraînement M8 v1b : NON lancé, GO_CHECKER_PASS NON posé.** Trois raisons :
+ 1. Dans le texte propre de Checker (12 h 20, 12 h 22, 12 h 23), je ne trouve **aucune** phrase disant que l'entraînement peut démarrer sans le verdict. Le texte dit l'inverse : 12 h 20 « GO_CHECKER_PASS ne doit pas être posé avant » [le PASS d'audit r3] ; 12 h 23 « GO_CHECKER_PASS ne doit PAS être posé sur aa66889b…. » Le « complément Checker 12 h 25 » rapporté par Relay n'existe pas dans spira_relay.md (dernière entrée Checker : 12 h 23, l. 7609-7672).
+ 2. gate_m8v1b.sh (PID 218845, sha d8287108…) lance automatiquement `code/verdict_M8v1b.py` (r2 aa66889b) dès que les deux bras sont faits. Le script ne propose aucun flag pour sauter cette étape. La seule façon de l'éviter serait de tuer ou de modifier la porte, ou de remplacer le script de verdict : aucune n'est permise.
+ 3. train_m8v1b.py (l. 107-125) évalue toutes les fenêtres (seen, fc2, fresh_en, fresh_fr, test20k, test_v3, queries) juste après la sauvegarde. Il écrit runs/results.jsonl et {arm}__{w}.npz, et loggue les enregistrements. Des résultats d'éval frais existeraient donc dans runs/ avant tout PASS r3, ce que la condition demandée exclut.
+ → La porte reste ARMÉE, en ATTENTE (STATUS 12 h 25 m 24) ; runs/ est vide. Pour lancer proprement, il faut : r3 décidée par Philippe-Antoine, figée et auditée (PASS Checker), puis le drapeau. La porte exécutera alors le fichier code/verdict_M8v1b.py en place à ce moment-là.
+- **BROUILLONS r3 (NON FIGÉS, aucun PASS demandé, en attente de la décision de Philippe-Antoine)** — hashing_gen/m8_v1b/code/drafts_r3/ (générés par make_drafts.py c867d48e…, remplacements exacts depuis r2 aa66889b) :
+ - **A** = règle r2 inchangée (gain sur seen ET sur ≥ 1 fraîche, aucune perte) + garde d'échelle : verdict_M8v1b_r3A_DRAFT.py sha256 **c561c3b9f7fff3525f6b18794f1f6446e4ab619de49e63aee06648a4887d3b67** ; diff r3A_vs_r2.diff (56d22748…).
+ - **B** = diff Checker 12 h 20 / Relay 12 h 25 : l. 130 → `dec = "ADOPTÉ" if (GF and not L) else "REJETÉ"`, l. 131 supprimée, l. 14-15 et 138 alignées ; une perte sur seen reste bloquante. Plus la garde d'échelle : verdict_M8v1b_r3B_DRAFT.py sha256 **aae604383b5dad65c13602641c5dc645635e66192263239de90805ca40c0e5d1** ; diff r3B_vs_r2.diff (b15d2ef1…). PREDECL §6 NON modifié (attend la décision).
+ - Commun A/B : NON MESURABLE si cal.scale (lu dans results.jsonl) d'un bras ∉ [--scale-lo ; --scale-hi], défaut 0,03 / 0,11 (**bornes à confirmer par Philippe-Antoine**). Ajout de --runs/--outdir (défauts = runs/ et verdict/), scale_check dans le JSON. Calculs par fenêtre inchangés.
+ - Honnêteté : au smoke, scale vaut **ctl 1,0507 / cm 1,1309, hors plage**. Avec la garde, le vrai run sera NON MESURABLE si cette échelle se reproduit (rien dans train_m8v1b.py ne la contraint).
+ - Tests, sur les sorties smoke seulement (smoke/vtest, smoke/vtest2 ; sorties dans drafts_r3/test_out/ ; < 1 s chacun, nice 10, OMP=1) :
+ - vtest : A et B → NON MESURABLE (passe SNN 3 000 ≠ 600 000, et scale hors plage).
+ - vtest2, bornes par défaut : A et B → NON MESURABLE « fusion.scale hors [0.03 ; 0.11] ».
+ - vtest2 avec bornes larges (0 ; 2), pour exercer la règle : A → REJETÉ (pas de gain seen ; aucun gain frais), B → REJETÉ (aucun gain frais).
+ - per_window identique à la sortie r2 de vtest2 pour A et B (True).
+ - Aucun résultat de vrai run ouvert (il n'en existe pas).
+- RAM/lourds (12 h 26) : MemAvailable 7,63 Go ; 3 lourds (15242 Checker bg1d, 15953 cov b v3 r2, 16884 cov b broad r2).
+- Rien tué (218845, 15242, 15953, 16884 intacts), rien dans /tmp, checker/ et broad/ non touchés, aucun téléchargement hors re-vérification de mon propre push.
+Lu/appliqué — SPIRA Hashing — 12 h 27
diff --git a/results/hashing/m8_v1b/code/drafts_r3/relay_hashing_fix.txt b/results/hashing/m8_v1b/code/drafts_r3/relay_hashing_fix.txt
new file mode 100644
index 0000000000000000000000000000000000000000..567706ee564c63ad65c95ee3bce1560f98e7655c
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/relay_hashing_fix.txt
@@ -0,0 +1,22 @@
+
+### SPIRA Hashing — 12 h 51 (Toronto) — correctif pré-audit Checker 12 h 48 (r3A/r3B : bornes scale en dur)
+- Source vérifiée : entrée **SPIRA Checker (worker) — 12 h 48**, pré-audit r3A c561c3b9… / r3B aae60438… FAIL (--scale-lo/--scale-hi permettent d'élargir la garde).
+- Correctif (A l. 20-21, B l. 21-22 ; seul changement) : options --scale-lo/--scale-hi retirées ; `SCALE_LO = 0.03; SCALE_HI = 0.11` en dur, commentaire « plage PROVISOIRE, en attente de la décision de Philippe-Antoine ». --runs/--outdir conservés.
+- Anciennes versions : *.prev (sha c561c3b9f7fff3525f6b18794f1f6446e4ab619de49e63aee06648a4887d3b67 / aae604383b5dad65c13602641c5dc645635e66192263239de90805ca40c0e5d1).
+- **Nouveaux sha256 :**
+ - r3A : /workspace/spira_shared/hashing_gen/m8_v1b/code/drafts_r3/verdict_M8v1b_r3A_DRAFT.py **389bdcb295cc0742e1883ea01ae6ded765f895358068b4ba0e2657d5873d81f2**
+ - r3B : /workspace/spira_shared/hashing_gen/m8_v1b/code/drafts_r3/verdict_M8v1b_r3B_DRAFT.py **cb27a4a57e1d97456ef7a2691ba6a7a64a3a6ac026798900f34533c580ed4f93**
+- Diffs : r3A_vs_prev.diff (d62e1ab9…), r3B_vs_prev.diff (5e0571a2…), r3A_vs_r2_v2.diff (c70842dc…), r3B_vs_r2_v2.diff (1dac81cf…). Diff vs prev (identique A/B) :
+```
+-_ap.add_argument("--scale-lo", type=float, default=0.03); _ap.add_argument("--scale-hi", type=float, default=0.11) # bornes À CONFIRMER par Philippe-Antoine
+-_a = _ap.parse_args(); D, OP, SCALE_LO, SCALE_HI = _a.runs, _a.outdir, _a.scale_lo, _a.scale_hi
++SCALE_LO = 0.03; SCALE_HI = 0.11 # bornes EN DUR, non surchargeables ; plage PROVISOIRE, en attente de la décision de Philippe-Antoine
++_a = _ap.parse_args(); D, OP = _a.runs, _a.outdir
+```
+- Tests (smoke vtest/vtest2 seulement, sorties drafts_r3/test_out_v2/, nice 10, OMP 1) :
+ - vtest : A et B → NON MESURABLE (passe SNN 3 000 ≠ 600 000 + fusion.scale hors [0.03 ; 0.11] : ctl 1,0507 / cm 1,1309).
+ - vtest2 : A et B → NON MESURABLE (fusion.scale hors [0.03 ; 0.11]).
+ - `--scale-hi 0.2` et `--scale-lo 0` : A et B refusés (argparse « unrecognized arguments », rc = 2, aucune sortie écrite).
+- **BROUILLONS non figés, choix A/B et plage en attente de Philippe-Antoine.** GO_CHECKER_PASS non posé, aucune éval dans runs/, rien poussé sur HF, rien dans /tmp ; checker/, broad/, portes 218845/18819/18821 non touchés.
+- **Demande à Checker :** pré-audit des nouveaux sha 389bdcb2… (A) et cb27a4a5… (B).
+Lu/appliqué — SPIRA Hashing — 12 h 51
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest/def/verdict_M8v1b.json b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest/def/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..25d48fecf6ecda262a23974073b7294233c7b7bf
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest/def/verdict_M8v1b.json
@@ -0,0 +1,422 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 600000,
+ "cm": 600000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": false,
+ "cm": false
+ }
+ },
+ "budget_ok": false,
+ "scale_check": {
+ "scale": {
+ "ctl": 1.0507417508415837,
+ "cm": 1.130901526059381
+ },
+ "lo": 0.03,
+ "hi": 0.11,
+ "ok": false
+ },
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "NON MESURABLE",
+ "reasons": [
+ "passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000",
+ "fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "c561c3b9f7fff3525f6b18794f1f6446e4ab619de49e63aee06648a4887d3b67",
+ "inputs_sha256": {
+ "ctl__seen.npz": "946032bb309efe4b0283da009610a9473c514cc987f04b7486dc00dca614bb2e",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "ca73f541bf12144d5136faf1ee54fe36b688361fb8752bcca239bd590f084b29",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "d8c4431270de50778f061341d055370d697e363ff7f03a07fe64cb654cc42c5f",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest/def/verdict_M8v1b.md b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest/def/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..708a730d563786253b703ae653ae641326c5e7c1
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest/def/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**NON MESURABLE** — passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000; fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 600000, "cm": 600000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": false, "cm": false}} → NON OK.
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 c561c3b9f7fff3525f6b18794f1f6446e4ab619de49e63aee06648a4887d3b67.
+
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest/wide/verdict_M8v1b.json b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest/wide/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..5950580308ba2ef4f86ff43bcd44735084e5ecfd
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest/wide/verdict_M8v1b.json
@@ -0,0 +1,421 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 600000,
+ "cm": 600000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": false,
+ "cm": false
+ }
+ },
+ "budget_ok": false,
+ "scale_check": {
+ "scale": {
+ "ctl": 1.0507417508415837,
+ "cm": 1.130901526059381
+ },
+ "lo": 0.0,
+ "hi": 2.0,
+ "ok": true
+ },
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "NON MESURABLE",
+ "reasons": [
+ "passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "c561c3b9f7fff3525f6b18794f1f6446e4ab619de49e63aee06648a4887d3b67",
+ "inputs_sha256": {
+ "ctl__seen.npz": "946032bb309efe4b0283da009610a9473c514cc987f04b7486dc00dca614bb2e",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "ca73f541bf12144d5136faf1ee54fe36b688361fb8752bcca239bd590f084b29",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "d8c4431270de50778f061341d055370d697e363ff7f03a07fe64cb654cc42c5f",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest/wide/verdict_M8v1b.md b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest/wide/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..bfb4ae87fc91dac838aa6ecac41281c4273ade73
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest/wide/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**NON MESURABLE** — passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 600000, "cm": 600000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": false, "cm": false}} → NON OK.
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 c561c3b9f7fff3525f6b18794f1f6446e4ab619de49e63aee06648a4887d3b67.
+
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest2/def/verdict_M8v1b.json b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest2/def/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..3b0d22409fdc35cd8f262aa20eabbf62f423479b
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest2/def/verdict_M8v1b.json
@@ -0,0 +1,421 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 3000,
+ "cm": 3000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": true,
+ "cm": true
+ }
+ },
+ "budget_ok": true,
+ "scale_check": {
+ "scale": {
+ "ctl": 1.0507417508415837,
+ "cm": 1.130901526059381
+ },
+ "lo": 0.03,
+ "hi": 0.11,
+ "ok": false
+ },
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "NON MESURABLE",
+ "reasons": [
+ "fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "c561c3b9f7fff3525f6b18794f1f6446e4ab619de49e63aee06648a4887d3b67",
+ "inputs_sha256": {
+ "ctl__seen.npz": "060d52c025bac6c903af8844cd20ed889d15d8661a3cdc246d5918a2c0d3a36d",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "15e0eb6c46aa88bcf9f0d0a791977abea4a97a5d0b8b3cd14011229474e01038",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "dc54b207075ff91e04e253a005e5967c67bb5e37884c03e508b3ceb2db7743e7",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest2/def/verdict_M8v1b.md b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest2/def/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..4fa550f8bef001b40f83056cf83af57809371d49
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest2/def/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**NON MESURABLE** — fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 3000, "cm": 3000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": true, "cm": true}} → OK (égaux, budget SNN entier entraîné).
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 c561c3b9f7fff3525f6b18794f1f6446e4ab619de49e63aee06648a4887d3b67.
+
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest2/wide/verdict_M8v1b.json b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest2/wide/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..bd5582c5c9b0cce5408794607be487ae168f2155
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest2/wide/verdict_M8v1b.json
@@ -0,0 +1,422 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 3000,
+ "cm": 3000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": true,
+ "cm": true
+ }
+ },
+ "budget_ok": true,
+ "scale_check": {
+ "scale": {
+ "ctl": 1.0507417508415837,
+ "cm": 1.130901526059381
+ },
+ "lo": 0.0,
+ "hi": 2.0,
+ "ok": true
+ },
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen",
+ "aucun gain significatif sur une fenêtre fraîche valide"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "c561c3b9f7fff3525f6b18794f1f6446e4ab619de49e63aee06648a4887d3b67",
+ "inputs_sha256": {
+ "ctl__seen.npz": "060d52c025bac6c903af8844cd20ed889d15d8661a3cdc246d5918a2c0d3a36d",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "15e0eb6c46aa88bcf9f0d0a791977abea4a97a5d0b8b3cd14011229474e01038",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "dc54b207075ff91e04e253a005e5967c67bb5e37884c03e508b3ceb2db7743e7",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest2/wide/verdict_M8v1b.md b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest2/wide/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..7216501e7ee528cc04df3edffa44ceaade004685
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/A/vtest2/wide/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche valide
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 3000, "cm": 3000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": true, "cm": true}} → OK (égaux, budget SNN entier entraîné).
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 c561c3b9f7fff3525f6b18794f1f6446e4ab619de49e63aee06648a4887d3b67.
+
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest/def/verdict_M8v1b.json b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest/def/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..75bd76e6da0f5f337990e01a4ff9514ed56c9319
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest/def/verdict_M8v1b.json
@@ -0,0 +1,422 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 600000,
+ "cm": 600000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": false,
+ "cm": false
+ }
+ },
+ "budget_ok": false,
+ "scale_check": {
+ "scale": {
+ "ctl": 1.0507417508415837,
+ "cm": 1.130901526059381
+ },
+ "lo": 0.03,
+ "hi": 0.11,
+ "ok": false
+ },
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "NON MESURABLE",
+ "reasons": [
+ "passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000",
+ "fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "aae604383b5dad65c13602641c5dc645635e66192263239de90805ca40c0e5d1",
+ "inputs_sha256": {
+ "ctl__seen.npz": "946032bb309efe4b0283da009610a9473c514cc987f04b7486dc00dca614bb2e",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "ca73f541bf12144d5136faf1ee54fe36b688361fb8752bcca239bd590f084b29",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "d8c4431270de50778f061341d055370d697e363ff7f03a07fe64cb654cc42c5f",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest/def/verdict_M8v1b.md b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest/def/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..6c140b8fcb1f4e343e9b685c66a2a9190b647eb7
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest/def/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**NON MESURABLE** — passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000; fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 600000, "cm": 600000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": false, "cm": false}} → NON OK.
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 aae604383b5dad65c13602641c5dc645635e66192263239de90805ca40c0e5d1.
+
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest/wide/verdict_M8v1b.json b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest/wide/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..ed794a4dfc02ee6d9498f798013f57680122d209
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest/wide/verdict_M8v1b.json
@@ -0,0 +1,421 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 600000,
+ "cm": 600000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": false,
+ "cm": false
+ }
+ },
+ "budget_ok": false,
+ "scale_check": {
+ "scale": {
+ "ctl": 1.0507417508415837,
+ "cm": 1.130901526059381
+ },
+ "lo": 0.0,
+ "hi": 2.0,
+ "ok": true
+ },
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "NON MESURABLE",
+ "reasons": [
+ "passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "aae604383b5dad65c13602641c5dc645635e66192263239de90805ca40c0e5d1",
+ "inputs_sha256": {
+ "ctl__seen.npz": "946032bb309efe4b0283da009610a9473c514cc987f04b7486dc00dca614bb2e",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "ca73f541bf12144d5136faf1ee54fe36b688361fb8752bcca239bd590f084b29",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "d8c4431270de50778f061341d055370d697e363ff7f03a07fe64cb654cc42c5f",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest/wide/verdict_M8v1b.md b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest/wide/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..9e914ed0db7194179a51909b015e72b567820082
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest/wide/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**NON MESURABLE** — passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 600000, "cm": 600000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": false, "cm": false}} → NON OK.
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 aae604383b5dad65c13602641c5dc645635e66192263239de90805ca40c0e5d1.
+
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest2/def/verdict_M8v1b.json b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest2/def/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..4b00710665f0f01c8c74494571d5ca73fa924af0
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest2/def/verdict_M8v1b.json
@@ -0,0 +1,421 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 3000,
+ "cm": 3000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": true,
+ "cm": true
+ }
+ },
+ "budget_ok": true,
+ "scale_check": {
+ "scale": {
+ "ctl": 1.0507417508415837,
+ "cm": 1.130901526059381
+ },
+ "lo": 0.03,
+ "hi": 0.11,
+ "ok": false
+ },
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "NON MESURABLE",
+ "reasons": [
+ "fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "aae604383b5dad65c13602641c5dc645635e66192263239de90805ca40c0e5d1",
+ "inputs_sha256": {
+ "ctl__seen.npz": "060d52c025bac6c903af8844cd20ed889d15d8661a3cdc246d5918a2c0d3a36d",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "15e0eb6c46aa88bcf9f0d0a791977abea4a97a5d0b8b3cd14011229474e01038",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "dc54b207075ff91e04e253a005e5967c67bb5e37884c03e508b3ceb2db7743e7",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest2/def/verdict_M8v1b.md b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest2/def/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..829837412f1004140830e75630068365c111e0db
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest2/def/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**NON MESURABLE** — fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 3000, "cm": 3000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": true, "cm": true}} → OK (égaux, budget SNN entier entraîné).
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 aae604383b5dad65c13602641c5dc645635e66192263239de90805ca40c0e5d1.
+
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest2/wide/verdict_M8v1b.json b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest2/wide/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..639f841207fab2723553e8bd0d12abb89ac18be1
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest2/wide/verdict_M8v1b.json
@@ -0,0 +1,421 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 3000,
+ "cm": 3000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": true,
+ "cm": true
+ }
+ },
+ "budget_ok": true,
+ "scale_check": {
+ "scale": {
+ "ctl": 1.0507417508415837,
+ "cm": 1.130901526059381
+ },
+ "lo": 0.0,
+ "hi": 2.0,
+ "ok": true
+ },
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "aucun gain significatif sur une fenêtre fraîche valide"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "aae604383b5dad65c13602641c5dc645635e66192263239de90805ca40c0e5d1",
+ "inputs_sha256": {
+ "ctl__seen.npz": "060d52c025bac6c903af8844cd20ed889d15d8661a3cdc246d5918a2c0d3a36d",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "15e0eb6c46aa88bcf9f0d0a791977abea4a97a5d0b8b3cd14011229474e01038",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "dc54b207075ff91e04e253a005e5967c67bb5e37884c03e508b3ceb2db7743e7",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest2/wide/verdict_M8v1b.md b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest2/wide/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..537634a0ca0c98d69178de9f0c1fdbe6328e26a2
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out/B/vtest2/wide/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**REJETÉ** — aucun gain significatif sur une fenêtre fraîche valide
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 3000, "cm": 3000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": true, "cm": true}} → OK (égaux, budget SNN entier entraîné).
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 aae604383b5dad65c13602641c5dc645635e66192263239de90805ca40c0e5d1.
+
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/A/vtest/verdict_M8v1b.json b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/A/vtest/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..59a71b04ca7715d95d827ae249b0b5e953b8af46
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/A/vtest/verdict_M8v1b.json
@@ -0,0 +1,422 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 600000,
+ "cm": 600000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": false,
+ "cm": false
+ }
+ },
+ "budget_ok": false,
+ "scale_check": {
+ "scale": {
+ "ctl": 1.0507417508415837,
+ "cm": 1.130901526059381
+ },
+ "lo": 0.03,
+ "hi": 0.11,
+ "ok": false
+ },
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "NON MESURABLE",
+ "reasons": [
+ "passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000",
+ "fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "389bdcb295cc0742e1883ea01ae6ded765f895358068b4ba0e2657d5873d81f2",
+ "inputs_sha256": {
+ "ctl__seen.npz": "946032bb309efe4b0283da009610a9473c514cc987f04b7486dc00dca614bb2e",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "ca73f541bf12144d5136faf1ee54fe36b688361fb8752bcca239bd590f084b29",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "d8c4431270de50778f061341d055370d697e363ff7f03a07fe64cb654cc42c5f",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/A/vtest/verdict_M8v1b.md b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/A/vtest/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..2287320cd9cb28b0ea77c93ca32d5b2fe0a1104b
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/A/vtest/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**NON MESURABLE** — passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000; fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 600000, "cm": 600000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": false, "cm": false}} → NON OK.
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 389bdcb295cc0742e1883ea01ae6ded765f895358068b4ba0e2657d5873d81f2.
+
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/A/vtest2/verdict_M8v1b.json b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/A/vtest2/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..e469cad2bdf96c77cc66e43765cf788b8a8c5e83
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/A/vtest2/verdict_M8v1b.json
@@ -0,0 +1,421 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 3000,
+ "cm": 3000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": true,
+ "cm": true
+ }
+ },
+ "budget_ok": true,
+ "scale_check": {
+ "scale": {
+ "ctl": 1.0507417508415837,
+ "cm": 1.130901526059381
+ },
+ "lo": 0.03,
+ "hi": 0.11,
+ "ok": false
+ },
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "NON MESURABLE",
+ "reasons": [
+ "fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "389bdcb295cc0742e1883ea01ae6ded765f895358068b4ba0e2657d5873d81f2",
+ "inputs_sha256": {
+ "ctl__seen.npz": "060d52c025bac6c903af8844cd20ed889d15d8661a3cdc246d5918a2c0d3a36d",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "15e0eb6c46aa88bcf9f0d0a791977abea4a97a5d0b8b3cd14011229474e01038",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "dc54b207075ff91e04e253a005e5967c67bb5e37884c03e508b3ceb2db7743e7",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/A/vtest2/verdict_M8v1b.md b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/A/vtest2/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..d7eb9202017e0f4918c0bad4cab65c9589f74ff6
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/A/vtest2/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**NON MESURABLE** — fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 3000, "cm": 3000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": true, "cm": true}} → OK (égaux, budget SNN entier entraîné).
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 389bdcb295cc0742e1883ea01ae6ded765f895358068b4ba0e2657d5873d81f2.
+
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/B/vtest/verdict_M8v1b.json b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/B/vtest/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..bf50f25f586612ba3da7dd29e152124f4642601c
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/B/vtest/verdict_M8v1b.json
@@ -0,0 +1,422 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 600000,
+ "cm": 600000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": false,
+ "cm": false
+ }
+ },
+ "budget_ok": false,
+ "scale_check": {
+ "scale": {
+ "ctl": 1.0507417508415837,
+ "cm": 1.130901526059381
+ },
+ "lo": 0.03,
+ "hi": 0.11,
+ "ok": false
+ },
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "NON MESURABLE",
+ "reasons": [
+ "passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000",
+ "fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "cb27a4a57e1d97456ef7a2691ba6a7a64a3a6ac026798900f34533c580ed4f93",
+ "inputs_sha256": {
+ "ctl__seen.npz": "946032bb309efe4b0283da009610a9473c514cc987f04b7486dc00dca614bb2e",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "ca73f541bf12144d5136faf1ee54fe36b688361fb8752bcca239bd590f084b29",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "d8c4431270de50778f061341d055370d697e363ff7f03a07fe64cb654cc42c5f",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/B/vtest/verdict_M8v1b.md b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/B/vtest/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..16aba30b2df68c054f5008db2097d1ce03d114a7
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/B/vtest/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**NON MESURABLE** — passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000; fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 600000, "cm": 600000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": false, "cm": false}} → NON OK.
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 cb27a4a57e1d97456ef7a2691ba6a7a64a3a6ac026798900f34533c580ed4f93.
+
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/B/vtest2/verdict_M8v1b.json b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/B/vtest2/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..8ba898a328f05fd8183db094db831f56601a5467
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/B/vtest2/verdict_M8v1b.json
@@ -0,0 +1,421 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 3000,
+ "cm": 3000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": true,
+ "cm": true
+ }
+ },
+ "budget_ok": true,
+ "scale_check": {
+ "scale": {
+ "ctl": 1.0507417508415837,
+ "cm": 1.130901526059381
+ },
+ "lo": 0.03,
+ "hi": 0.11,
+ "ok": false
+ },
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "NON MESURABLE",
+ "reasons": [
+ "fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "cb27a4a57e1d97456ef7a2691ba6a7a64a3a6ac026798900f34533c580ed4f93",
+ "inputs_sha256": {
+ "ctl__seen.npz": "060d52c025bac6c903af8844cd20ed889d15d8661a3cdc246d5918a2c0d3a36d",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "15e0eb6c46aa88bcf9f0d0a791977abea4a97a5d0b8b3cd14011229474e01038",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "dc54b207075ff91e04e253a005e5967c67bb5e37884c03e508b3ceb2db7743e7",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/B/vtest2/verdict_M8v1b.md b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/B/vtest2/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..fc28c950d075302a752cb9b99639e730e5aca57b
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/test_out_v2/B/vtest2/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**NON MESURABLE** — fusion.scale hors [0.03 ; 0.11] : ctl 1.0507417508415837 / cm 1.130901526059381
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 3000, "cm": 3000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": true, "cm": true}} → OK (égaux, budget SNN entier entraîné).
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 cb27a4a57e1d97456ef7a2691ba6a7a64a3a6ac026798900f34533c580ed4f93.
+
diff --git a/results/hashing/m8_v1b/code/drafts_r3/verdict_M8v1b_r3A_DRAFT.py b/results/hashing/m8_v1b/code/drafts_r3/verdict_M8v1b_r3A_DRAFT.py
new file mode 100644
index 0000000000000000000000000000000000000000..0c744a07104b17fbdfed264a3d964cb9d9de6afd
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/verdict_M8v1b_r3A_DRAFT.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict M8 v1b (cm = M8 neurones CM concat, contre ctl = même code sans CM, budget égal), chemin v4.2.
+Dérivé de lever2_sparse/code/verdict_SP.py (sha256 7a6d5414…a2deb, copie : verdict_SP.py.orig_ref). Calculs identiques (positions in-vocab dans
+les DEUX bras, taux APPARIÉS même dénominateur, McNemar exact bilatéral, bootstrap apparié blocs 512 o B=10 000 seed 0, bootstrap positions seed 25).
+SEULS changements : (1) bras ctl/cm lus dans m8_v1b/runs ; (2) fenêtre seen = v1b_sample[:200 000] (audit trained_frac identique) ;
+(3) test_v3 ajoutée, VALIDE ssi recompte 64 o de l'échantillon = 0 ET recompte v1b = 0 ET drapeau GO_CHECKER_PASS présent, sinon exclue ;
+(4) queries rapportée À PART (hors règle) ; neither_code non évaluée (exclue) ; (5) positions propres : chaque fenêtre fraîche exige
+confirmed_window_positions = 0 dans le recompte de l'échantillon (sinon fenêtre NON COMPARABLE, exclue) ; test20k strict = masque
+mask_oldtest_strict.npz (old_local_v1 ∪ broad_local_v1) ∪ échantillon (0 position, vérifié) ; (6) gain significatif = McNemar p<0,05 ET c>b ET
+IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+epochs, ticks/époque, sha256 des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick != snn_tokens), ou seen NON COMPARABLE
+(trained_frac < 0,99 dans un bras ; trained_frac calculé sur les tokens RÉELLEMENT entraînés = ticks × 1, pas sur snn_tokens déclaré).
+BROUILLON r3-A (NON FIGÉ) : règle r2 inchangée + garde fusion.scale [lo ; hi] (défaut 0,03/0,11) + chemins en paramètres.
+Révision 2 (12 h 08 Toronto) : contrôle d'unités rendu explicite (TOKENS_PER_TICK = 1, spiking.py l. 471-539) et audit seen sur tokens réellement entraînés.
+Règle : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+ET aucune perte significative sur une fenêtre valide (seen + fraîches valides) ; sinon REJETÉ."""
+import sys, os, json, math, hashlib, argparse, numpy as np
+B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; RT, CT = "ctl", "cm"
+_ap = argparse.ArgumentParser(); _ap.add_argument("--runs", default=f"{B8}/runs"); _ap.add_argument("--outdir", default=f"{B8}/verdict")
+SCALE_LO = 0.03; SCALE_HI = 0.11 # bornes EN DUR, non surchargeables ; plage PROVISOIRE, en attente de la décision de Philippe-Antoine
+_a = _ap.parse_args(); D, OP = _a.runs, _a.outdir
+SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; SEP = ["queries"]
+RCNAME = {"fc2": "fc2", "fresh_en": "m7_fresh_en", "fresh_fr": "m7_fresh_fr", "test20k": "m7_test20k", "test_v3": "corpus_v3_test", "queries": "m7_queries"}
+BLK, NB, SEED = 512, 10000, 0
+os.makedirs(OP, exist_ok=True); MS = np.load(MASKP)
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+# ---- budgets égaux (sinon NON MESURABLE)
+RES = [json.loads(l) for l in open(f"{D}/results.jsonl") if l.strip()]
+def arm_field(arm, f):
+ v = {json.dumps(r.get(f), sort_keys=True) for r in RES if r.get("arm") == arm}; return json.loads(v.pop()) if len(v) == 1 else "INCOHERENT"
+BUD = {f: {RT: arm_field(RT, f), CT: arm_field(CT, f)} for f in ("snn_tokens", "am_tokens", "epochs", "ticks_per_epoch", "data_sha256")}
+# Unités : spira/spiking.py SpikingCore.train_pass (l. 471-539) fait UN tick par token SNN (neurons[t] = token t, "ticks": T = len(cols)),
+# donc tokens SNN entraînés par époque = ticks × TOKENS_PER_TICK, TOKENS_PER_TICK = 1. Contrôles : (i) égalité cm == ctl de chaque champ ;
+# (ii) données = échantillon ; (iii) chaque époque a entraîné TOUT le budget : ticks × TOKENS_PER_TICK == snn_tokens (sinon passe tronquée).
+TOKENS_PER_TICK = 1
+EQUAL = {f: (v[RT] == v[CT] and v[RT] != "INCOHERENT" and v[RT] is not None) for f, v in BUD.items()}
+TRAINED = {x: ([t * TOKENS_PER_TICK for t in BUD["ticks_per_epoch"][x]] if isinstance(BUD["ticks_per_epoch"][x], list) else None) for x in (RT, CT)}
+FULL = {x: (TRAINED[x] is not None and isinstance(BUD["epochs"][x], int) and len(TRAINED[x]) == BUD["epochs"][x]
+ and all(t == BUD["snn_tokens"][x] for t in TRAINED[x])) for x in (RT, CT)}
+BUDGET_OK = all(EQUAL.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA and FULL[RT] and FULL[CT]
+# ---- garde d'échelle de fusion (r3) : NON MESURABLE si cal.scale d'un bras hors [SCALE_LO ; SCALE_HI] (lu dans results.jsonl)
+def _scale(arm):
+ c = arm_field(arm, "cal"); return c.get("scale") if isinstance(c, dict) else None
+SCALE = {x: _scale(x) for x in (RT, CT)}
+SCALE_OK = all(isinstance(SCALE[x], (int, float)) and SCALE_LO <= SCALE[x] <= SCALE_HI for x in (RT, CT))
+SCALE_CHECK = {"scale": SCALE, "lo": SCALE_LO, "hi": SCALE_HI, "ok": SCALE_OK}
+BUDGET_CHECK = {"equal_cm_ctl": EQUAL, "data_is_sample": BUD["data_sha256"][RT] == SAMPLE_SHA, "tokens_per_tick": TOKENS_PER_TICK,
+ "trained_snn_tokens_per_epoch": TRAINED, "full_budget_each_epoch": FULL}
+# tokens SNN réellement entraînés (pour l'audit seen) = min sur les époques de ticks × TOKENS_PER_TICK, borné par snn_tokens
+TRAINED_MIN = {x: (min(min(TRAINED[x]), BUD["snn_tokens"][x]) if TRAINED[x] and isinstance(BUD["snn_tokens"][x], int) else None) for x in (RT, CT)}
+# ---- propreté des fenêtres fraîches
+RCS = json.load(open(RC_SAMPLE)); RCV = json.load(open(RC_V1B))["overlap64_recount_v1b"]["per_window"]
+assert RCS["sha256"] == SAMPLE_SHA, "recompte : échantillon différent"
+CLEAN = {}
+for w, k in RCNAME.items():
+ cs = RCS["windows"][k]["confirmed_window_positions"]; cv = RCV[k]["confirmed_window_positions"] if k in RCV else None
+ CLEAN[w] = {"sample_confirmed_window_positions": cs, "v1b_confirmed_window_positions": cv, "window_sha256_recount": RCS["windows"][k]["window_sha256"]}
+VALID = {w: CLEAN[w]["sample_confirmed_window_positions"] == 0 for w in FRESH + SEP}
+VALID["test_v3"] = VALID["test_v3"] and CLEAN["test_v3"]["v1b_confirmed_window_positions"] == 0 and os.path.exists(GO)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN + SEP:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{D}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ if w in RCNAME: assert str(A["window_sha256"]) == CLEAN[w]["window_sha256_recount"], f"{w}: fenêtre != fenêtre recomptée"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": CLEAN["test20k"]["sample_confirmed_window_positions"],
+ "excluded_union": int((bo | bb_).sum()), "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ ia1, ib1 = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k; one_side = int((ia1 ^ ib1).sum())
+ k = k & A["invocab"].astype(bool) & B["invocab"].astype(bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); p = binp(b, c)
+ acc_a, acc_b = 100 * (ha & k).sum() / max(1, k.sum()), 100 * (hb & k).sum() / max(1, k.sum())
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], k[k], nbk); sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], k[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, k)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b and lo > 0), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "invocab_identical": inv_same, "n_invocab_one_side_only_dropped": one_side, "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a), "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p,
+ "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m, "sig_gain": gain, "sig_loss": loss,
+ "boot_conflict": bool((p < 0.05 and c > b and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"]),
+ "valid": (True if w == "seen" else VALID[w]), "in_rule": w in WIN, "clean_recount": CLEAN.get(w)}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+# ---- audit trained_frac du seen (identique à verdict_SP, fenêtre = échantillon[:200 000])
+_A = np.load(f"{D}/{RT}__seen.npz"); _st, _ln = _A["tgt_start"].astype(np.int64), _A["tgt_len"].astype(np.int64)
+_contig = bool(np.all(_st[1:] == _st[:-1] + _ln[:-1]) and _st[0] > 0 and _st[0] <= int(_ln.max()))
+_sb = open(SAMPLE, "rb").read(); _wok = hashlib.sha256(_sb[:200_000]).hexdigest() == R["seen"]["window_sha256"] and hashlib.sha256(_sb).hexdigest() == SAMPLE_SHA; del _sb
+_ksnn = {"ref": TRAINED_MIN[RT], "cand": TRAINED_MIN[CT]} # tokens SNN réellement entraînés (ticks × 1), pas le budget déclaré
+_k, _ha, _hb, _iv = KEEP["seen"]; _ivb = _k & _iv & np.load(f"{D}/{CT}__seen.npz")["invocab"].astype(bool); _ctx = np.arange(len(_st))
+SEEN_AUDIT = {"window_is_sample_prefix_200000": _wok, "targets_contiguous_from_patch1": _contig, "snn_tokens": _ksnn,
+ "max_ctx_patch_index": int(_ctx.max()), "max_byte_evaluated": int((_st + _ln).max()), "invocab_both_n": int(_ivb.sum())}
+for side in ("ref", "cand"):
+ ok = _wok and _contig and isinstance(_ksnn[side], int)
+ n_tr = int((_ivb & (_ctx < _ksnn[side])).sum()) if ok else None
+ SEEN_AUDIT[f"trained_invocab_n_{side}"] = n_tr; SEEN_AUDIT[f"trained_frac_{side}"] = (n_tr / max(1, int(_ivb.sum()))) if n_tr is not None else None
+SEEN_OK = all(SEEN_AUDIT[f"trained_frac_{x}"] is not None and SEEN_AUDIT[f"trained_frac_{x}"] >= 0.99 for x in ("ref", "cand"))
+SEEN_AUDIT["seen_comparable"] = SEEN_OK; print("seen_audit", json.dumps(SEEN_AUDIT), flush=True)
+FV = [w for w in FRESH if VALID[w]]
+def gapcalc(GW):
+ gap = {}
+ for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt),
+ "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+ dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GW], axis=0))
+ gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+ gap["windows"] = GW; return gap
+GAPS = {"with_test_v3": gapcalc(FV), "without_test_v3": gapcalc([w for w in FV if w != "test_v3"])}
+VW = ["seen"] + FV
+L = [w for w in VW if R[w]["sig_loss"]]; G = [w for w in VW if R[w]["sig_gain"]]; GF = [w for w in FV if R[w]["sig_gain"]]
+why = []
+if not BUDGET_OK:
+ if not all(EQUAL.values()): why.append("budgets cm/ctl inégaux : " + ", ".join(f for f, ok in EQUAL.items() if not ok))
+ if BUD["data_sha256"][RT] != SAMPLE_SHA: why.append("données != échantillon v1b")
+ if not (FULL[RT] and FULL[CT]): why.append(f"passe SNN incomplète : tokens entraînés/époque (ticks × {TOKENS_PER_TICK}) ctl {TRAINED[RT]} / cm {TRAINED[CT]} != snn_tokens {BUD['snn_tokens'][RT]}")
+if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+if not SCALE_OK: why.append(f"fusion.scale hors [{SCALE_LO} ; {SCALE_HI}] : ctl {SCALE[RT]} / cm {SCALE[CT]}")
+if BUDGET_OK and SEEN_OK and SCALE_OK:
+ dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+ if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+else: dec = "NON MESURABLE"
+out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+ "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "scale_check": SCALE_CHECK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
+ "results_jsonl_sha256": hashlib.sha256(open(f"{D}/results.jsonl", "rb").read()).hexdigest(),
+ "recount_sample_sha256": hashlib.sha256(open(RC_SAMPLE, "rb").read()).hexdigest(), "mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}/verdict_M8v1b.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b {SAMPLE_SHA[:8]}…\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).", "",
+ "| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|---|"]
+for w in WIN + SEP:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ if w in SEP: dd += " (à part, hors règle)"
+ elif not r["valid"]: dd = "EXCLUE (non propre / non confirmée)"
+ md.append(f"| {w}{' strict' if w == 'test20k' else ''} | {r['valid']} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd} |")
+md += ["", f"neither_code : exclue (non évaluée). test20k strict : {EX.get('excluded_union')} positions exclues (old ∪ broad), 0 par l'échantillon.",
+ f"Budgets : {json.dumps(BUD)} ; contrôle {json.dumps(BUDGET_CHECK)} → {'OK (égaux, budget SNN entier entraîné)' if BUDGET_OK else 'NON OK'}.",
+ f"Audit seen : trained_frac ctl {SEEN_AUDIT['trained_frac_ref']} / cm {SEEN_AUDIT['trained_frac_cand']} → seen {'COMPARABLE' if SEEN_OK else 'NON COMPARABLE'}.",
+ f"Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl {GAPS['with_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f} [{GAPS['with_test_v3']['cand_minus_ref']['ci95'][0]:+.3f} ; {GAPS['with_test_v3']['cand_minus_ref']['ci95'][1]:+.3f}] ; sans test_v3 : {GAPS['without_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f}.",
+ f"Script sha256 {out['script_sha256']}.", ""]
+open(f"{OP}/verdict_M8v1b.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m8_v1b/code/drafts_r3/verdict_M8v1b_r3B_DRAFT.py b/results/hashing/m8_v1b/code/drafts_r3/verdict_M8v1b_r3B_DRAFT.py
new file mode 100644
index 0000000000000000000000000000000000000000..0edae74ff287b2cb66aaf65b5b5fd77edc152983
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/verdict_M8v1b_r3B_DRAFT.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict M8 v1b (cm = M8 neurones CM concat, contre ctl = même code sans CM, budget égal), chemin v4.2.
+Dérivé de lever2_sparse/code/verdict_SP.py (sha256 7a6d5414…a2deb, copie : verdict_SP.py.orig_ref). Calculs identiques (positions in-vocab dans
+les DEUX bras, taux APPARIÉS même dénominateur, McNemar exact bilatéral, bootstrap apparié blocs 512 o B=10 000 seed 0, bootstrap positions seed 25).
+SEULS changements : (1) bras ctl/cm lus dans m8_v1b/runs ; (2) fenêtre seen = v1b_sample[:200 000] (audit trained_frac identique) ;
+(3) test_v3 ajoutée, VALIDE ssi recompte 64 o de l'échantillon = 0 ET recompte v1b = 0 ET drapeau GO_CHECKER_PASS présent, sinon exclue ;
+(4) queries rapportée À PART (hors règle) ; neither_code non évaluée (exclue) ; (5) positions propres : chaque fenêtre fraîche exige
+confirmed_window_positions = 0 dans le recompte de l'échantillon (sinon fenêtre NON COMPARABLE, exclue) ; test20k strict = masque
+mask_oldtest_strict.npz (old_local_v1 ∪ broad_local_v1) ∪ échantillon (0 position, vérifié) ; (6) gain significatif = McNemar p<0,05 ET c>b ET
+IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+epochs, ticks/époque, sha256 des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick != snn_tokens), ou seen NON COMPARABLE
+(trained_frac < 0,99 dans un bras ; trained_frac calculé sur les tokens RÉELLEMENT entraînés = ticks × 1, pas sur snn_tokens déclaré).
+BROUILLON r3-B (NON FIGÉ) : règle v4.2 (Checker 12 h 20) + garde fusion.scale [lo ; hi] (défaut 0,03/0,11) + chemins en paramètres.
+Révision 2 (12 h 08 Toronto) : contrôle d'unités rendu explicite (TOKENS_PER_TICK = 1, spiking.py l. 471-539) et audit seen sur tokens réellement entraînés.
+Règle (r3-B) : ADOPTÉ ssi gain significatif sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+ET aucune perte significative sur une fenêtre valide (seen + fraîches valides ; égalité sur seen admise) ; sinon REJETÉ ;
+NON MESURABLE aussi si fusion.scale d'un bras hors [lo ; hi]."""
+import sys, os, json, math, hashlib, argparse, numpy as np
+B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; RT, CT = "ctl", "cm"
+_ap = argparse.ArgumentParser(); _ap.add_argument("--runs", default=f"{B8}/runs"); _ap.add_argument("--outdir", default=f"{B8}/verdict")
+SCALE_LO = 0.03; SCALE_HI = 0.11 # bornes EN DUR, non surchargeables ; plage PROVISOIRE, en attente de la décision de Philippe-Antoine
+_a = _ap.parse_args(); D, OP = _a.runs, _a.outdir
+SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; SEP = ["queries"]
+RCNAME = {"fc2": "fc2", "fresh_en": "m7_fresh_en", "fresh_fr": "m7_fresh_fr", "test20k": "m7_test20k", "test_v3": "corpus_v3_test", "queries": "m7_queries"}
+BLK, NB, SEED = 512, 10000, 0
+os.makedirs(OP, exist_ok=True); MS = np.load(MASKP)
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+# ---- budgets égaux (sinon NON MESURABLE)
+RES = [json.loads(l) for l in open(f"{D}/results.jsonl") if l.strip()]
+def arm_field(arm, f):
+ v = {json.dumps(r.get(f), sort_keys=True) for r in RES if r.get("arm") == arm}; return json.loads(v.pop()) if len(v) == 1 else "INCOHERENT"
+BUD = {f: {RT: arm_field(RT, f), CT: arm_field(CT, f)} for f in ("snn_tokens", "am_tokens", "epochs", "ticks_per_epoch", "data_sha256")}
+# Unités : spira/spiking.py SpikingCore.train_pass (l. 471-539) fait UN tick par token SNN (neurons[t] = token t, "ticks": T = len(cols)),
+# donc tokens SNN entraînés par époque = ticks × TOKENS_PER_TICK, TOKENS_PER_TICK = 1. Contrôles : (i) égalité cm == ctl de chaque champ ;
+# (ii) données = échantillon ; (iii) chaque époque a entraîné TOUT le budget : ticks × TOKENS_PER_TICK == snn_tokens (sinon passe tronquée).
+TOKENS_PER_TICK = 1
+EQUAL = {f: (v[RT] == v[CT] and v[RT] != "INCOHERENT" and v[RT] is not None) for f, v in BUD.items()}
+TRAINED = {x: ([t * TOKENS_PER_TICK for t in BUD["ticks_per_epoch"][x]] if isinstance(BUD["ticks_per_epoch"][x], list) else None) for x in (RT, CT)}
+FULL = {x: (TRAINED[x] is not None and isinstance(BUD["epochs"][x], int) and len(TRAINED[x]) == BUD["epochs"][x]
+ and all(t == BUD["snn_tokens"][x] for t in TRAINED[x])) for x in (RT, CT)}
+BUDGET_OK = all(EQUAL.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA and FULL[RT] and FULL[CT]
+# ---- garde d'échelle de fusion (r3) : NON MESURABLE si cal.scale d'un bras hors [SCALE_LO ; SCALE_HI] (lu dans results.jsonl)
+def _scale(arm):
+ c = arm_field(arm, "cal"); return c.get("scale") if isinstance(c, dict) else None
+SCALE = {x: _scale(x) for x in (RT, CT)}
+SCALE_OK = all(isinstance(SCALE[x], (int, float)) and SCALE_LO <= SCALE[x] <= SCALE_HI for x in (RT, CT))
+SCALE_CHECK = {"scale": SCALE, "lo": SCALE_LO, "hi": SCALE_HI, "ok": SCALE_OK}
+BUDGET_CHECK = {"equal_cm_ctl": EQUAL, "data_is_sample": BUD["data_sha256"][RT] == SAMPLE_SHA, "tokens_per_tick": TOKENS_PER_TICK,
+ "trained_snn_tokens_per_epoch": TRAINED, "full_budget_each_epoch": FULL}
+# tokens SNN réellement entraînés (pour l'audit seen) = min sur les époques de ticks × TOKENS_PER_TICK, borné par snn_tokens
+TRAINED_MIN = {x: (min(min(TRAINED[x]), BUD["snn_tokens"][x]) if TRAINED[x] and isinstance(BUD["snn_tokens"][x], int) else None) for x in (RT, CT)}
+# ---- propreté des fenêtres fraîches
+RCS = json.load(open(RC_SAMPLE)); RCV = json.load(open(RC_V1B))["overlap64_recount_v1b"]["per_window"]
+assert RCS["sha256"] == SAMPLE_SHA, "recompte : échantillon différent"
+CLEAN = {}
+for w, k in RCNAME.items():
+ cs = RCS["windows"][k]["confirmed_window_positions"]; cv = RCV[k]["confirmed_window_positions"] if k in RCV else None
+ CLEAN[w] = {"sample_confirmed_window_positions": cs, "v1b_confirmed_window_positions": cv, "window_sha256_recount": RCS["windows"][k]["window_sha256"]}
+VALID = {w: CLEAN[w]["sample_confirmed_window_positions"] == 0 for w in FRESH + SEP}
+VALID["test_v3"] = VALID["test_v3"] and CLEAN["test_v3"]["v1b_confirmed_window_positions"] == 0 and os.path.exists(GO)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN + SEP:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{D}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ if w in RCNAME: assert str(A["window_sha256"]) == CLEAN[w]["window_sha256_recount"], f"{w}: fenêtre != fenêtre recomptée"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": CLEAN["test20k"]["sample_confirmed_window_positions"],
+ "excluded_union": int((bo | bb_).sum()), "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ ia1, ib1 = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k; one_side = int((ia1 ^ ib1).sum())
+ k = k & A["invocab"].astype(bool) & B["invocab"].astype(bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); p = binp(b, c)
+ acc_a, acc_b = 100 * (ha & k).sum() / max(1, k.sum()), 100 * (hb & k).sum() / max(1, k.sum())
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], k[k], nbk); sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], k[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, k)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b and lo > 0), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "invocab_identical": inv_same, "n_invocab_one_side_only_dropped": one_side, "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a), "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p,
+ "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m, "sig_gain": gain, "sig_loss": loss,
+ "boot_conflict": bool((p < 0.05 and c > b and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"]),
+ "valid": (True if w == "seen" else VALID[w]), "in_rule": w in WIN, "clean_recount": CLEAN.get(w)}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+# ---- audit trained_frac du seen (identique à verdict_SP, fenêtre = échantillon[:200 000])
+_A = np.load(f"{D}/{RT}__seen.npz"); _st, _ln = _A["tgt_start"].astype(np.int64), _A["tgt_len"].astype(np.int64)
+_contig = bool(np.all(_st[1:] == _st[:-1] + _ln[:-1]) and _st[0] > 0 and _st[0] <= int(_ln.max()))
+_sb = open(SAMPLE, "rb").read(); _wok = hashlib.sha256(_sb[:200_000]).hexdigest() == R["seen"]["window_sha256"] and hashlib.sha256(_sb).hexdigest() == SAMPLE_SHA; del _sb
+_ksnn = {"ref": TRAINED_MIN[RT], "cand": TRAINED_MIN[CT]} # tokens SNN réellement entraînés (ticks × 1), pas le budget déclaré
+_k, _ha, _hb, _iv = KEEP["seen"]; _ivb = _k & _iv & np.load(f"{D}/{CT}__seen.npz")["invocab"].astype(bool); _ctx = np.arange(len(_st))
+SEEN_AUDIT = {"window_is_sample_prefix_200000": _wok, "targets_contiguous_from_patch1": _contig, "snn_tokens": _ksnn,
+ "max_ctx_patch_index": int(_ctx.max()), "max_byte_evaluated": int((_st + _ln).max()), "invocab_both_n": int(_ivb.sum())}
+for side in ("ref", "cand"):
+ ok = _wok and _contig and isinstance(_ksnn[side], int)
+ n_tr = int((_ivb & (_ctx < _ksnn[side])).sum()) if ok else None
+ SEEN_AUDIT[f"trained_invocab_n_{side}"] = n_tr; SEEN_AUDIT[f"trained_frac_{side}"] = (n_tr / max(1, int(_ivb.sum()))) if n_tr is not None else None
+SEEN_OK = all(SEEN_AUDIT[f"trained_frac_{x}"] is not None and SEEN_AUDIT[f"trained_frac_{x}"] >= 0.99 for x in ("ref", "cand"))
+SEEN_AUDIT["seen_comparable"] = SEEN_OK; print("seen_audit", json.dumps(SEEN_AUDIT), flush=True)
+FV = [w for w in FRESH if VALID[w]]
+def gapcalc(GW):
+ gap = {}
+ for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt),
+ "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+ dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GW], axis=0))
+ gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+ gap["windows"] = GW; return gap
+GAPS = {"with_test_v3": gapcalc(FV), "without_test_v3": gapcalc([w for w in FV if w != "test_v3"])}
+VW = ["seen"] + FV
+L = [w for w in VW if R[w]["sig_loss"]]; G = [w for w in VW if R[w]["sig_gain"]]; GF = [w for w in FV if R[w]["sig_gain"]]
+why = []
+if not BUDGET_OK:
+ if not all(EQUAL.values()): why.append("budgets cm/ctl inégaux : " + ", ".join(f for f, ok in EQUAL.items() if not ok))
+ if BUD["data_sha256"][RT] != SAMPLE_SHA: why.append("données != échantillon v1b")
+ if not (FULL[RT] and FULL[CT]): why.append(f"passe SNN incomplète : tokens entraînés/époque (ticks × {TOKENS_PER_TICK}) ctl {TRAINED[RT]} / cm {TRAINED[CT]} != snn_tokens {BUD['snn_tokens'][RT]}")
+if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+if not SCALE_OK: why.append(f"fusion.scale hors [{SCALE_LO} ; {SCALE_HI}] : ctl {SCALE[RT]} / cm {SCALE[CT]}")
+if BUDGET_OK and SEEN_OK and SCALE_OK:
+ dec = "ADOPTÉ" if (GF and not L) else "REJETÉ"
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+else: dec = "NON MESURABLE"
+out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+ "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "scale_check": SCALE_CHECK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
+ "results_jsonl_sha256": hashlib.sha256(open(f"{D}/results.jsonl", "rb").read()).hexdigest(),
+ "recount_sample_sha256": hashlib.sha256(open(RC_SAMPLE, "rb").read()).hexdigest(), "mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}/verdict_M8v1b.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b {SAMPLE_SHA[:8]}…\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).", "",
+ "| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|---|"]
+for w in WIN + SEP:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ if w in SEP: dd += " (à part, hors règle)"
+ elif not r["valid"]: dd = "EXCLUE (non propre / non confirmée)"
+ md.append(f"| {w}{' strict' if w == 'test20k' else ''} | {r['valid']} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd} |")
+md += ["", f"neither_code : exclue (non évaluée). test20k strict : {EX.get('excluded_union')} positions exclues (old ∪ broad), 0 par l'échantillon.",
+ f"Budgets : {json.dumps(BUD)} ; contrôle {json.dumps(BUDGET_CHECK)} → {'OK (égaux, budget SNN entier entraîné)' if BUDGET_OK else 'NON OK'}.",
+ f"Audit seen : trained_frac ctl {SEEN_AUDIT['trained_frac_ref']} / cm {SEEN_AUDIT['trained_frac_cand']} → seen {'COMPARABLE' if SEEN_OK else 'NON COMPARABLE'}.",
+ f"Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl {GAPS['with_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f} [{GAPS['with_test_v3']['cand_minus_ref']['ci95'][0]:+.3f} ; {GAPS['with_test_v3']['cand_minus_ref']['ci95'][1]:+.3f}] ; sans test_v3 : {GAPS['without_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f}.",
+ f"Script sha256 {out['script_sha256']}.", ""]
+open(f"{OP}/verdict_M8v1b.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m8_v1b/code/drafts_r3/verdict_M8v1b_r3B_FROZEN.py b/results/hashing/m8_v1b/code/drafts_r3/verdict_M8v1b_r3B_FROZEN.py
new file mode 100644
index 0000000000000000000000000000000000000000..1653ba54ba17523a5a1424821451ad6df1ea95e8
--- /dev/null
+++ b/results/hashing/m8_v1b/code/drafts_r3/verdict_M8v1b_r3B_FROZEN.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict M8 v1b (cm = M8 neurones CM concat, contre ctl = même code sans CM, budget égal), chemin v4.2.
+Dérivé de lever2_sparse/code/verdict_SP.py (sha256 7a6d5414…a2deb, copie : verdict_SP.py.orig_ref). Calculs identiques (positions in-vocab dans
+les DEUX bras, taux APPARIÉS même dénominateur, McNemar exact bilatéral, bootstrap apparié blocs 512 o B=10 000 seed 0, bootstrap positions seed 25).
+SEULS changements : (1) bras ctl/cm lus dans m8_v1b/runs ; (2) fenêtre seen = v1b_sample[:200 000] (audit trained_frac identique) ;
+(3) test_v3 ajoutée, VALIDE ssi recompte 64 o de l'échantillon = 0 ET recompte v1b = 0 ET drapeau GO_CHECKER_PASS présent, sinon exclue ;
+(4) queries rapportée À PART (hors règle) ; neither_code non évaluée (exclue) ; (5) positions propres : chaque fenêtre fraîche exige
+confirmed_window_positions = 0 dans le recompte de l'échantillon (sinon fenêtre NON COMPARABLE, exclue) ; test20k strict = masque
+mask_oldtest_strict.npz (old_local_v1 ∪ broad_local_v1) ∪ échantillon (0 position, vérifié) ; (6) gain significatif = McNemar p<0,05 ET c>b ET
+IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+epochs, ticks/époque, sha256 des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick != snn_tokens), ou seen NON COMPARABLE
+(trained_frac < 0,99 dans un bras ; trained_frac calculé sur les tokens RÉELLEMENT entraînés = ticks × 1, pas sur snn_tokens déclaré).
+Révision 3-B (figée le 24 oct, décision de Philippe-Antoine 13 h 00 Toronto) : règle v4.2 (Checker 12 h 20) + garde fusion.scale, bornes en dur [0,03 ; 0,11] (non surchargeables) + chemins --runs/--outdir en paramètres.
+Révision 2 (12 h 08 Toronto) : contrôle d'unités rendu explicite (TOKENS_PER_TICK = 1, spiking.py l. 471-539) et audit seen sur tokens réellement entraînés.
+Règle (r3-B) : ADOPTÉ ssi gain significatif sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+ET aucune perte significative sur une fenêtre valide (seen + fraîches valides ; égalité sur seen admise) ; sinon REJETÉ ;
+NON MESURABLE aussi si fusion.scale d'un bras hors [lo ; hi]."""
+import sys, os, json, math, hashlib, argparse, numpy as np
+B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; RT, CT = "ctl", "cm"
+_ap = argparse.ArgumentParser(); _ap.add_argument("--runs", default=f"{B8}/runs"); _ap.add_argument("--outdir", default=f"{B8}/verdict")
+SCALE_LO = 0.03; SCALE_HI = 0.11 # bornes EN DUR, non surchargeables ; plage PROVISOIRE, en attente de la décision de Philippe-Antoine
+_a = _ap.parse_args(); D, OP = _a.runs, _a.outdir
+SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; SEP = ["queries"]
+RCNAME = {"fc2": "fc2", "fresh_en": "m7_fresh_en", "fresh_fr": "m7_fresh_fr", "test20k": "m7_test20k", "test_v3": "corpus_v3_test", "queries": "m7_queries"}
+BLK, NB, SEED = 512, 10000, 0
+os.makedirs(OP, exist_ok=True); MS = np.load(MASKP)
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+# ---- budgets égaux (sinon NON MESURABLE)
+RES = [json.loads(l) for l in open(f"{D}/results.jsonl") if l.strip()]
+def arm_field(arm, f):
+ v = {json.dumps(r.get(f), sort_keys=True) for r in RES if r.get("arm") == arm}; return json.loads(v.pop()) if len(v) == 1 else "INCOHERENT"
+BUD = {f: {RT: arm_field(RT, f), CT: arm_field(CT, f)} for f in ("snn_tokens", "am_tokens", "epochs", "ticks_per_epoch", "data_sha256")}
+# Unités : spira/spiking.py SpikingCore.train_pass (l. 471-539) fait UN tick par token SNN (neurons[t] = token t, "ticks": T = len(cols)),
+# donc tokens SNN entraînés par époque = ticks × TOKENS_PER_TICK, TOKENS_PER_TICK = 1. Contrôles : (i) égalité cm == ctl de chaque champ ;
+# (ii) données = échantillon ; (iii) chaque époque a entraîné TOUT le budget : ticks × TOKENS_PER_TICK == snn_tokens (sinon passe tronquée).
+TOKENS_PER_TICK = 1
+EQUAL = {f: (v[RT] == v[CT] and v[RT] != "INCOHERENT" and v[RT] is not None) for f, v in BUD.items()}
+TRAINED = {x: ([t * TOKENS_PER_TICK for t in BUD["ticks_per_epoch"][x]] if isinstance(BUD["ticks_per_epoch"][x], list) else None) for x in (RT, CT)}
+FULL = {x: (TRAINED[x] is not None and isinstance(BUD["epochs"][x], int) and len(TRAINED[x]) == BUD["epochs"][x]
+ and all(t == BUD["snn_tokens"][x] for t in TRAINED[x])) for x in (RT, CT)}
+BUDGET_OK = all(EQUAL.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA and FULL[RT] and FULL[CT]
+# ---- garde d'échelle de fusion (r3) : NON MESURABLE si cal.scale d'un bras hors [SCALE_LO ; SCALE_HI] (lu dans results.jsonl)
+def _scale(arm):
+ c = arm_field(arm, "cal"); return c.get("scale") if isinstance(c, dict) else None
+SCALE = {x: _scale(x) for x in (RT, CT)}
+SCALE_OK = all(isinstance(SCALE[x], (int, float)) and SCALE_LO <= SCALE[x] <= SCALE_HI for x in (RT, CT))
+SCALE_CHECK = {"scale": SCALE, "lo": SCALE_LO, "hi": SCALE_HI, "ok": SCALE_OK}
+BUDGET_CHECK = {"equal_cm_ctl": EQUAL, "data_is_sample": BUD["data_sha256"][RT] == SAMPLE_SHA, "tokens_per_tick": TOKENS_PER_TICK,
+ "trained_snn_tokens_per_epoch": TRAINED, "full_budget_each_epoch": FULL}
+# tokens SNN réellement entraînés (pour l'audit seen) = min sur les époques de ticks × TOKENS_PER_TICK, borné par snn_tokens
+TRAINED_MIN = {x: (min(min(TRAINED[x]), BUD["snn_tokens"][x]) if TRAINED[x] and isinstance(BUD["snn_tokens"][x], int) else None) for x in (RT, CT)}
+# ---- propreté des fenêtres fraîches
+RCS = json.load(open(RC_SAMPLE)); RCV = json.load(open(RC_V1B))["overlap64_recount_v1b"]["per_window"]
+assert RCS["sha256"] == SAMPLE_SHA, "recompte : échantillon différent"
+CLEAN = {}
+for w, k in RCNAME.items():
+ cs = RCS["windows"][k]["confirmed_window_positions"]; cv = RCV[k]["confirmed_window_positions"] if k in RCV else None
+ CLEAN[w] = {"sample_confirmed_window_positions": cs, "v1b_confirmed_window_positions": cv, "window_sha256_recount": RCS["windows"][k]["window_sha256"]}
+VALID = {w: CLEAN[w]["sample_confirmed_window_positions"] == 0 for w in FRESH + SEP}
+VALID["test_v3"] = VALID["test_v3"] and CLEAN["test_v3"]["v1b_confirmed_window_positions"] == 0 and os.path.exists(GO)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN + SEP:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{D}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ if w in RCNAME: assert str(A["window_sha256"]) == CLEAN[w]["window_sha256_recount"], f"{w}: fenêtre != fenêtre recomptée"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": CLEAN["test20k"]["sample_confirmed_window_positions"],
+ "excluded_union": int((bo | bb_).sum()), "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ ia1, ib1 = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k; one_side = int((ia1 ^ ib1).sum())
+ k = k & A["invocab"].astype(bool) & B["invocab"].astype(bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); p = binp(b, c)
+ acc_a, acc_b = 100 * (ha & k).sum() / max(1, k.sum()), 100 * (hb & k).sum() / max(1, k.sum())
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], k[k], nbk); sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], k[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, k)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b and lo > 0), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "invocab_identical": inv_same, "n_invocab_one_side_only_dropped": one_side, "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a), "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p,
+ "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m, "sig_gain": gain, "sig_loss": loss,
+ "boot_conflict": bool((p < 0.05 and c > b and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"]),
+ "valid": (True if w == "seen" else VALID[w]), "in_rule": w in WIN, "clean_recount": CLEAN.get(w)}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+# ---- audit trained_frac du seen (identique à verdict_SP, fenêtre = échantillon[:200 000])
+_A = np.load(f"{D}/{RT}__seen.npz"); _st, _ln = _A["tgt_start"].astype(np.int64), _A["tgt_len"].astype(np.int64)
+_contig = bool(np.all(_st[1:] == _st[:-1] + _ln[:-1]) and _st[0] > 0 and _st[0] <= int(_ln.max()))
+_sb = open(SAMPLE, "rb").read(); _wok = hashlib.sha256(_sb[:200_000]).hexdigest() == R["seen"]["window_sha256"] and hashlib.sha256(_sb).hexdigest() == SAMPLE_SHA; del _sb
+_ksnn = {"ref": TRAINED_MIN[RT], "cand": TRAINED_MIN[CT]} # tokens SNN réellement entraînés (ticks × 1), pas le budget déclaré
+_k, _ha, _hb, _iv = KEEP["seen"]; _ivb = _k & _iv & np.load(f"{D}/{CT}__seen.npz")["invocab"].astype(bool); _ctx = np.arange(len(_st))
+SEEN_AUDIT = {"window_is_sample_prefix_200000": _wok, "targets_contiguous_from_patch1": _contig, "snn_tokens": _ksnn,
+ "max_ctx_patch_index": int(_ctx.max()), "max_byte_evaluated": int((_st + _ln).max()), "invocab_both_n": int(_ivb.sum())}
+for side in ("ref", "cand"):
+ ok = _wok and _contig and isinstance(_ksnn[side], int)
+ n_tr = int((_ivb & (_ctx < _ksnn[side])).sum()) if ok else None
+ SEEN_AUDIT[f"trained_invocab_n_{side}"] = n_tr; SEEN_AUDIT[f"trained_frac_{side}"] = (n_tr / max(1, int(_ivb.sum()))) if n_tr is not None else None
+SEEN_OK = all(SEEN_AUDIT[f"trained_frac_{x}"] is not None and SEEN_AUDIT[f"trained_frac_{x}"] >= 0.99 for x in ("ref", "cand"))
+SEEN_AUDIT["seen_comparable"] = SEEN_OK; print("seen_audit", json.dumps(SEEN_AUDIT), flush=True)
+FV = [w for w in FRESH if VALID[w]]
+def gapcalc(GW):
+ gap = {}
+ for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt),
+ "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+ dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GW], axis=0))
+ gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+ gap["windows"] = GW; return gap
+GAPS = {"with_test_v3": gapcalc(FV), "without_test_v3": gapcalc([w for w in FV if w != "test_v3"])}
+VW = ["seen"] + FV
+L = [w for w in VW if R[w]["sig_loss"]]; G = [w for w in VW if R[w]["sig_gain"]]; GF = [w for w in FV if R[w]["sig_gain"]]
+why = []
+if not BUDGET_OK:
+ if not all(EQUAL.values()): why.append("budgets cm/ctl inégaux : " + ", ".join(f for f, ok in EQUAL.items() if not ok))
+ if BUD["data_sha256"][RT] != SAMPLE_SHA: why.append("données != échantillon v1b")
+ if not (FULL[RT] and FULL[CT]): why.append(f"passe SNN incomplète : tokens entraînés/époque (ticks × {TOKENS_PER_TICK}) ctl {TRAINED[RT]} / cm {TRAINED[CT]} != snn_tokens {BUD['snn_tokens'][RT]}")
+if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+if not SCALE_OK: why.append(f"fusion.scale hors [{SCALE_LO} ; {SCALE_HI}] : ctl {SCALE[RT]} / cm {SCALE[CT]}")
+if BUDGET_OK and SEEN_OK and SCALE_OK:
+ dec = "ADOPTÉ" if (GF and not L) else "REJETÉ"
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+else: dec = "NON MESURABLE"
+out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+ "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "scale_check": SCALE_CHECK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable ou fusion.scale hors [lo ; hi]",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
+ "results_jsonl_sha256": hashlib.sha256(open(f"{D}/results.jsonl", "rb").read()).hexdigest(),
+ "recount_sample_sha256": hashlib.sha256(open(RC_SAMPLE, "rb").read()).hexdigest(), "mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}/verdict_M8v1b.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b {SAMPLE_SHA[:8]}…\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).", "",
+ "| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|---|"]
+for w in WIN + SEP:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ if w in SEP: dd += " (à part, hors règle)"
+ elif not r["valid"]: dd = "EXCLUE (non propre / non confirmée)"
+ md.append(f"| {w}{' strict' if w == 'test20k' else ''} | {r['valid']} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd} |")
+md += ["", f"neither_code : exclue (non évaluée). test20k strict : {EX.get('excluded_union')} positions exclues (old ∪ broad), 0 par l'échantillon.",
+ f"Budgets : {json.dumps(BUD)} ; contrôle {json.dumps(BUDGET_CHECK)} → {'OK (égaux, budget SNN entier entraîné)' if BUDGET_OK else 'NON OK'}.",
+ f"Audit seen : trained_frac ctl {SEEN_AUDIT['trained_frac_ref']} / cm {SEEN_AUDIT['trained_frac_cand']} → seen {'COMPARABLE' if SEEN_OK else 'NON COMPARABLE'}.",
+ f"Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl {GAPS['with_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f} [{GAPS['with_test_v3']['cand_minus_ref']['ci95'][0]:+.3f} ; {GAPS['with_test_v3']['cand_minus_ref']['ci95'][1]:+.3f}] ; sans test_v3 : {GAPS['without_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f}.",
+ f"Script sha256 {out['script_sha256']}.", ""]
+open(f"{OP}/verdict_M8v1b.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m8_v1b/code/equiv_test.py b/results/hashing/m8_v1b/code/equiv_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..72eac9045d5c10e43fc102355745a3c8a3276b9f
--- /dev/null
+++ b/results/hashing/m8_v1b/code/equiv_test.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+"""Test d'équivalence (SPIRA Hashing) : SPIRA.train original (ckpt_path=None) sur un petit préfixe -> empreintes des poids.
+À comparer à la ligne WEIGHTS de train_m8v1b.py (run continu, et run arrêté après l'époque 1 puis repris). Usage : equiv_test.py ARM DATA SNN AM"""
+import sys, os, json, hashlib; sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+import numpy as np
+from countmin import CMSPIRA, SPIRAConfig
+from spira import SPIRA
+arm, path, snn, am = sys.argv[1], sys.argv[2], int(sys.argv[3]), int(sys.argv[4]); data = open(path, "rb").read()
+cfg = SPIRAConfig(vocab_size=16384, d_in=1024, snn_tokens=snn, am_tokens=am, epochs=2)
+m = CMSPIRA.build_cm(data, cfg, log=lambda *x: None) if arm == "cm" else SPIRA.build(data, cfg, log=lambda *x: None)
+m.prepare(); h = m.train(log_fn=lambda *x: None, ckpt_path=None)
+H8 = lambda x: hashlib.sha256(np.ascontiguousarray(x).tobytes()).hexdigest()[:16]
+print("WEIGHTS_ORIG " + json.dumps({"W_rec": H8(m.core.W_rec), "W_out": H8(m.core.W_out), "W_outG": H8(m.core.W_outG) if m.core.hier else None,
+ "am_keys": H8(m.am.keys), "am_vals": H8(m.am.vals), "history": [[e["ticks"], e["accuracy"], e.get("beta")] for e in h["epochs"]]}), flush=True)
diff --git a/results/hashing/m8_v1b/code/make_sample_v1b.py b/results/hashing/m8_v1b/code/make_sample_v1b.py
new file mode 100644
index 0000000000000000000000000000000000000000..1921eab70bd434367a1be2cdaaf9f78a7b0d5f02
--- /dev/null
+++ b/results/hashing/m8_v1b/code/make_sample_v1b.py
@@ -0,0 +1,138 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — M8 v1b : échantillon déterministe ~35 Mo de corpus_diverse_v1b (règle pré-déclarée, voir PREDECL.md §1).
+Règle :
+ 1. Documents (coordonnées v1b, séparateurs exclus) :
+ - broad_local_v1 : TinyStories découpé sur b"\n<|endoftext|>\n" ; livres PG = plages per_source du manifest v1b (v1 -> v1b par union
+ des plages retirées) ; code stdlib python = trous entre plages nommées, découpés aux débuts de fichiers .py de /usr/lib/python3.13
+ reconnus (128 premiers octets) juste après b"\n\n" ; reste non reconnu = 1 unité par trou.
+ - corpus_gutenberg_v2_part : 1 document = 1 livre (plages per_source) ; langue = manifest corpus_gutenberg_v2 (book_ids_fr / book_ids_en).
+ - multi_lang_v1 : fichiers séparés par b"\n<|endoffile|>\n" (build_stage1.json) ; dépôt = cumul de files_kept ; langue = intended_language du dépôt.
+ 2. Strates (source, langue) : tinystories/en, books/en, books/fr, stdlib/python, github/. Cible par strate
+ T_s = round(TARGET * octets_v1b(strate) / octets_v1b(total documents)).
+ 3. Dans chaque strate : permutation seedée (numpy PCG64, seed = SEED ^ int(sha256(nom de strate))[:16 hex]) ; parcours dans cet ordre,
+ un document est pris ssi il rapproche le cumul de T_s (|cum+len-T_s| < |cum-T_s|). Documents entiers uniquement.
+ 4. Ordre de sortie entrelacé (pour que tout préfixe soit ~proportionnel) : clé = (cumul_avant + len/2) / total_pris de la strate ;
+ tri par (clé, rang aléatoire seedé). Séparateur après chaque document = séparateur natif de sa source (pas après le dernier).
+Usage : make_sample_v1b.py OUTDIR (RSS faible : lectures par plages, pas de mmap)."""
+import sys, os, json, hashlib, resource, time, numpy as np
+S = "/workspace/spira_shared"; V1B = f"{S}/hashing_gen/corpus_v1b/train.bin"; MAN = f"{S}/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+V1B_SHA = "ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3"; SEED = 20261024; TARGET = 35_000_000
+OUT = sys.argv[1]; os.makedirs(OUT, exist_ok=True); t0 = time.time()
+TS_SEP, ML_SEP, NN = b"\n<|endoftext|>\n", b"\n<|endoffile|>\n", b"\n\n"
+f = open(V1B, "rb")
+def rd(a, b): f.seek(a); return f.read(b - a)
+man = json.load(open(MAN)); seg = {n: (a, b) for n, a, b in man["segments_v1b"]}
+assert os.path.getsize(V1B) == 520785883
+# --- v1 -> v1b
+rem = sorted(r for v in man["removed_ranges_v1coords_by_reason"].values() for r in v); U = []
+for a, b in rem:
+ if U and a <= U[-1][1]: U[-1][1] = max(U[-1][1], b)
+ else: U.append([a, b])
+assert sum(b - a for a, b in U) == man["removed_total_bytes"], "union retirée != removed_total_bytes"
+UA = np.array([a for a, _ in U], np.int64); UB = np.array([b for _, b in U], np.int64); CUM = np.concatenate([[0], np.cumsum(UB - UA)])
+def v2b(x): # x - octets retirés dans [0, x)
+ i = int(np.searchsorted(UA, x, "right")); r = int(CUM[i])
+ if i and UB[i - 1] > x: r -= int(UB[i - 1] - x)
+ return x - r
+docs = [] # (stratum, source, lang, a, b, sep)
+gfr = set(json.load(open(f"{S}/corpus_gutenberg_v2/manifest.json"))["book_ids_fr"])
+named_broad = []
+for p in man["per_source"]:
+ if "v1_range" not in p or p["v1b_bytes"] == 0 or p["segment"] == "multi_lang_v1": continue
+ a, b = v2b(p["v1_range"][0]), v2b(p["v1_range"][1]); assert b - a == p["v1b_bytes"], (p["source"], a, b, p["v1b_bytes"])
+ if p["segment"] == "broad_local_v1": named_broad.append((a, b, p["source"]))
+ if p["source"].startswith("TinyStories"): continue
+ gid = int(p["source"].split("#")[1].split()[0]); lang = "fr" if (gid in gfr or "_fr" in p["source"]) else "en"
+ docs.append((f"books/{lang}", p["source"], lang, a, b, NN))
+# TinyStories
+(ta, tb, _), = [x for x in named_broad if x[2].startswith("TinyStories")]; buf = rd(ta, tb); pos = 0; nts = 0
+while True:
+ j = buf.find(TS_SEP, pos); e = len(buf) if j < 0 else j
+ if e > pos: docs.append(("tinystories/en", "TinyStories-valid", "en", ta + pos, ta + e, TS_SEP)); nts += 1
+ if j < 0: break
+ pos = j + len(TS_SEP)
+del buf
+# stdlib : trous de broad_local_v1 entre plages nommées
+ba, bb = seg["broad_local_v1"]; nb = sorted(named_broad); gaps = []; cur = ba
+for a, b, _ in nb:
+ if a > cur: gaps.append((cur, a))
+ cur = max(cur, b)
+if cur < bb: gaps.append((cur, bb))
+SKIP = {"test", "tests", "__pycache__", "lib2to3", "idlelib", "site-packages", "turtledemo"}; PFX = {}
+for root, dirs, fn in os.walk("/usr/lib/python3.13"):
+ dirs[:] = [d for d in sorted(dirs) if d not in SKIP]
+ for x in sorted(fn):
+ if x.endswith(".py"):
+ try: h = open(os.path.join(root, x), "rb").read(128)
+ except OSError: continue
+ if len(h) == 128: PFX.setdefault(h, x)
+n_std_matched = 0; n_std_units = 0; std_gap_bytes = 0
+for ga, gb in gaps:
+ g = rd(ga, gb); std_gap_bytes += len(g)
+ st = [0] if g[:128] in PFX else []
+ k = g.find(NN)
+ while k >= 0:
+ if g[k + 2:k + 130] in PFX: st.append(k + 2)
+ k = g.find(NN, k + 1)
+ n_std_matched += len(st); bnd = ([0] if not st or st[0] != 0 else []) + st + [len(g) + 2]
+ for s0, s1 in zip(bnd[:-1], bnd[1:]):
+ a0, b0 = s0, s1 - 2
+ if s1 == len(g) + 2 and g.endswith(NN): b0 -= 2
+ if b0 > a0: docs.append(("stdlib/python", "python3.13 stdlib", "Python", ga + a0, ga + b0, NN)); n_std_units += 1
+# multi_lang
+ma, mb = seg["multi_lang_v1"]; st1 = json.load(open(f"{S}/multi_lang_v1/build_stage1.json"))
+reps = [(r["repo"], r["intended_language"], r["files_kept"]) for r in st1["repos"]]
+cuts = []; CH = 16 << 20; p0 = ma
+while p0 < mb:
+ blk = rd(p0, min(mb, p0 + CH + len(ML_SEP) - 1)); k = blk.find(ML_SEP)
+ while k >= 0:
+ if k < CH: cuts.append(p0 + k)
+ k = blk.find(ML_SEP, k + 1)
+ p0 += CH
+starts = [ma] + [c + len(ML_SEP) for c in cuts]; ends = cuts + [mb]
+assert len(starts) == sum(r[2] for r in reps), (len(starts), sum(r[2] for r in reps))
+i = 0
+for repo, lang, nf in reps:
+ for _ in range(nf):
+ docs.append((f"github/{lang}", repo, lang, starts[i], ends[i], ML_SEP)); i += 1
+# --- strates et tirage
+tot = sum(d[4] - d[3] for d in docs); strata = sorted({d[0] for d in docs}); sel = []; ST = {}
+for s in strata:
+ D = [d for d in docs if d[0] == s]; Bs = sum(d[4] - d[3] for d in D); T = round(TARGET * Bs / tot)
+ sseed = SEED ^ int(hashlib.sha256(s.encode()).hexdigest()[:16], 16); rng = np.random.default_rng(sseed); perm = rng.permutation(len(D))
+ cum = 0; take = []
+ for j in perm:
+ L = D[j][4] - D[j][3]
+ if abs(cum + L - T) < abs(cum - T): take.append(D[j]); cum += L
+ c2 = 0
+ for d in take:
+ L = d[4] - d[3]; sel.append(((c2 + L / 2) / max(cum, 1), d)); c2 += L
+ ST[s] = {"v1b_doc_bytes": Bs, "v1b_docs": len(D), "target_bytes": T, "taken_bytes": cum, "taken_docs": len(take),
+ "share_v1b": Bs / tot, "stratum_seed": sseed}
+orng = np.random.default_rng(SEED); tie = orng.permutation(len(sel))
+order = sorted(range(len(sel)), key=lambda q: (sel[q][0], int(tie[q])))
+sha = hashlib.sha256(); pos = 0; DOCS = []; outp = f"{OUT}/v1b_sample.bin"
+with open(outp + ".partial", "wb") as w:
+ for n, q in enumerate(order):
+ s, src, lang, a, b, sep = sel[q][1]; data = rd(a, b); w.write(data); sha.update(data)
+ DOCS.append([s, src, lang, a, b, pos, pos + len(data)]); pos += len(data)
+ if n < len(order) - 1: w.write(sep); sha.update(sep); pos += len(sep)
+os.replace(outp + ".partial", outp)
+assert os.path.getsize(outp) == pos
+def comp(n): # composition des n premiers octets par strate
+ c = {}
+ for s, _, _, _, _, x0, x1 in DOCS:
+ if x0 >= n: break
+ c[s] = c.get(s, 0) + min(x1, n) - x0
+ t = sum(c.values()); return {k: round(v / t, 4) for k, v in sorted(c.items())}
+res = {"author": "SPIRA Hashing", "script": os.path.abspath(__file__), "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "source": {"path": V1B, "bytes": 520785883, "sha256_expected": V1B_SHA, "manifest_sha256": hashlib.sha256(open(MAN, "rb").read()).hexdigest()},
+ "seed": SEED, "target_bytes": TARGET, "sample": {"path": outp, "bytes": pos, "sha256": sha.hexdigest(), "n_docs": len(DOCS)},
+ "doc_index_counts": {"tinystories": nts, "stdlib_gap_bytes": std_gap_bytes, "stdlib_py_starts_matched": n_std_matched,
+ "stdlib_units": n_std_units, "github_files": len(starts), "books": sum(1 for d in docs if d[0].startswith("books"))},
+ "v1b_doc_bytes_total": tot, "strata": ST,
+ "prefix_composition": {str(n): comp(n) for n in (60_000, 200_000, 2_000_000, 2_400_000, 4_800_000, 10_000_000)},
+ "docs_file": f"{OUT}/v1b_sample_docs.json", "peak_rss_MB": resource.getrusage(resource.RUSAGE_SELF).ru_maxrss // 1024, "elapsed_s": round(time.time() - t0, 1)}
+json.dump(DOCS, open(f"{OUT}/v1b_sample_docs.json", "w"))
+json.dump(res, open(f"{OUT}/v1b_sample_manifest.json", "w"), indent=1, ensure_ascii=False)
+print(json.dumps({k: res[k] for k in ("sample", "doc_index_counts", "peak_rss_MB", "elapsed_s")}), flush=True)
diff --git a/results/hashing/m8_v1b/code/run_equiv.sh b/results/hashing/m8_v1b/code/run_equiv.sh
new file mode 100644
index 0000000000000000000000000000000000000000..63ae4d3236f17c7aea44ad29ec75a5ea973367f2
--- /dev/null
+++ b/results/hashing/m8_v1b/code/run_equiv.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+# Test d'équivalence reprise/original, séquentiel, chaque étape via run_guarded.sh (porte + chien de garde).
+D=/workspace/spira_shared/hashing_gen/m8_v1b; PY=/workspace/SPIRA-venv/bin/python; G=$D/code/run_guarded.sh; E=$D/smoke/equiv; mkdir -p $E
+X=$D/smoke/equiv_3MB.bin
+for arm in cm ctl; do
+ $G eq_orig_$arm 1300000000 $E/orig_$arm.log -- $PY -u $D/code/equiv_test.py $arm $X 1500 20000 || exit 1
+ $G eq_split1_$arm 1300000000 $E/split1_$arm.log -- $PY -u $D/code/train_m8v1b.py --arm $arm --data $X --outdir $E/run_$arm --snn-tokens 1500 --am-tokens 20000 --epochs 2 --windows "" --no-save --stop-after-epoch 1 || exit 1
+ $G eq_split2_$arm 1300000000 $E/split2_$arm.log -- $PY -u $D/code/train_m8v1b.py --arm $arm --data $X --outdir $E/run_$arm --snn-tokens 1500 --am-tokens 20000 --epochs 2 --windows "" --no-save || exit 1
+done
+echo EQUIV_DONE >> $E/done
diff --git a/results/hashing/m8_v1b/code/run_guarded.sh b/results/hashing/m8_v1b/code/run_guarded.sh
new file mode 100644
index 0000000000000000000000000000000000000000..56eb83ed09346365ad2e0ebdfcd8a71d03d5e74b
--- /dev/null
+++ b/results/hashing/m8_v1b/code/run_guarded.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# SPIRA Hashing — M8 v1b : lanceur garde pour UN job lourd ponctuel (recompte, smoke).
+# Usage : run_guarded.sh NAME PEAK_BYTES LOG -- CMD... Porte : MemAvailable >= 4.4 GiB + PEAK et >= 5.2 GB, lourds (python RSS>=500 Mo) < 4.
+# Pas d'attente : si la porte est fermée -> sortie 3 (rien lancé). Chien de garde 4.4 GiB : tue SEULEMENT le groupe de ce job.
+export TZ=America/Toronto OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0 TMPDIR=/workspace/spira_shared/hashing_gen/m8_v1b/tmp
+D=/workspace/spira_shared/hashing_gen/m8_v1b; NAME=$1; PEAK=$2; LOG=$3; shift 4; R=$D/logs/guarded.log
+FLOOR=4724464025 # 4.4 GiB
+log(){ echo "$(date '+%F %H:%M:%S %Z') [$NAME] $*" >> $R; }
+mem(){ awk '/MemAvailable/{print $2*1024}' /proc/meminfo; }
+heavy(){ ps -eo pid,rss,comm | awk '$3 ~ /^python/ && $2>=500000 {print $1}' | tr '\n' ' '; }
+m=$(mem); h=$(heavy); nh=$(echo $h | wc -w); need=$(( FLOOR + PEAK )); [ $need -lt 5200000000 ] && need=5200000000
+if [ $m -lt $need ] || [ $nh -ge 4 ]; then log "GATE CLOSED MemAvailable=${m}B need=${need}B heavy=$nh [$h]"; echo "GATE CLOSED" >&2; exit 3; fi
+log "GATE OK MemAvailable=${m}B need=${need}B heavy=$nh [$h] cmd=$*"
+setsid nice -n 10 "$@" > $LOG 2>&1 & P=$!; log "START pid=$P"
+minm=$m; maxr=0
+while kill -0 $P 2>/dev/null; do
+ m=$(mem); [ $m -lt $minm ] && minm=$m
+ r=$(ps -o rss= -g $P 2>/dev/null | awk '{s+=$1}END{print s+0}'); [ $r -gt $maxr ] && maxr=$r
+ echo "$(date +%s) $m $r" >> $LOG.mem
+ if [ $m -lt $FLOOR ]; then log "WATCHDOG MemAvailable=${m}B < 4.4GiB -> kill -TERM -$P (notre groupe seulement)"; kill -TERM -$P; sleep 5; kill -KILL -$P 2>/dev/null; fi
+ sleep 2
+done
+wait $P; e=$?; log "EXIT $e min_MemAvailable=${minm}B max_groupRSS=${maxr}kB"; exit $e
diff --git a/results/hashing/m8_v1b/code/run_smoke.sh b/results/hashing/m8_v1b/code/run_smoke.sh
new file mode 100644
index 0000000000000000000000000000000000000000..17f15cc16dc668d4c0fc89a09e31865c28082149
--- /dev/null
+++ b/results/hashing/m8_v1b/code/run_smoke.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# Smoke plein échantillon (budgets réels 600k/1.2M pour build/prepare/AM/save ; passe SNN tronquée à 3000 ticks, 1 époque ; éval seen 500 positions).
+D=/workspace/spira_shared/hashing_gen/m8_v1b; PY=/workspace/SPIRA-venv/bin/python; G=$D/code/run_guarded.sh
+while [ ! -e $D/smoke/equiv/done ]; do sleep 20; done
+for arm in ctl cm; do
+ for try in $(seq 1 30); do
+ $G smoke_$arm 2000000000 $D/smoke/full_$arm.log -- $PY -u $D/code/train_m8v1b.py --arm $arm --data $D/sample/v1b_sample.bin --outdir $D/smoke/full_$arm \
+ --snn-tokens 600000 --am-tokens 1200000 --epochs 1 --smoke-ticks 3000 --windows seen --maxpos 500; e=$?
+ [ $e -ne 3 ] && break; sleep 60
+ done
+ echo "smoke_$arm exit $e" >> $D/smoke/smoke_done
+done
diff --git a/results/hashing/m8_v1b/code/run_vtest.sh b/results/hashing/m8_v1b/code/run_vtest.sh
new file mode 100644
index 0000000000000000000000000000000000000000..c23b141c46363c9943336579541cad0c47876459
--- /dev/null
+++ b/results/hashing/m8_v1b/code/run_vtest.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+D=/workspace/spira_shared/hashing_gen/m8_v1b; PY=/workspace/SPIRA-venv/bin/python; G=$D/code/run_guarded.sh; V=$D/smoke/vtest; mkdir -p $V/runs $V/verdict
+for arm in ctl cm; do
+ for t in $(seq 1 30); do $G vtest_$arm 2500000000 $V/eval_$arm.log -- $PY -u $D/code/smoke_evalonly.py $arm $D/smoke/full_$arm/$arm.npz $D/sample/v1b_sample.bin $V/runs 300 $D/smoke/full_$arm/results.jsonl; e=$?; [ $e -ne 3 ] && break; sleep 60; done
+ [ $e -ne 0 ] && { echo "eval $arm fail $e" >> $V/done; exit 1; }
+done
+sed -e "s#^B8 = \"/workspace/spira_shared/hashing_gen/m8_v1b\"; D = f\"{B8}/runs\"; OP = f\"{B8}/verdict\"#B8 = \"$D\"; D = \"$V/runs\"; OP = \"$V/verdict\"#" $D/code/verdict_M8v1b.py > $V/verdict_test_copy.py
+grep -c "$V/runs" $V/verdict_test_copy.py >> $V/done
+cd $V && nice -n 10 $PY -u $V/verdict_test_copy.py > $V/verdict_test.log 2>&1; echo "verdict exit $?" >> $V/done
diff --git a/results/hashing/m8_v1b/code/run_vtest2.sh b/results/hashing/m8_v1b/code/run_vtest2.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b256fb4018b1e166c930dfb4bb7f889d230012cf
--- /dev/null
+++ b/results/hashing/m8_v1b/code/run_vtest2.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# vtest2 : budget SNN COMPLET mais petit (snn 3000 = 3000 ticks, pas de troncature), am 1.2M, 1 époque, toutes fenêtres 300 positions, --no-save.
+# Séquentiel ; chaque bras via run_guarded.sh (lourds < 4 avant lancement => jamais plus de 4 lourds sur la machine).
+D=/workspace/spira_shared/hashing_gen/m8_v1b; PY=/workspace/SPIRA-venv/bin/python; G=$D/code/run_guarded.sh; V=$D/smoke/vtest2; mkdir -p $V/runs
+for arm in ctl cm; do
+ for t in $(seq 1 30); do $G vtest2_$arm 2000000000 $V/$arm.log -- $PY -u $D/code/train_m8v1b.py --arm $arm --data $D/sample/v1b_sample.bin --outdir $V/runs \
+ --snn-tokens 3000 --am-tokens 1200000 --epochs 1 --maxpos 300 --no-save; e=$?; [ $e -ne 3 ] && break; sleep 60; done
+ [ $e -ne 0 ] && { echo "arm $arm fail $e" >> $V/done; exit 1; }
+done
+sed -e "s#^B8 = \"/workspace/spira_shared/hashing_gen/m8_v1b\"; D = f\"{B8}/runs\"; OP = f\"{B8}/verdict\"#B8 = \"$D\"; D = \"$V/runs\"; OP = \"$V/verdict\"#" $D/code/verdict_M8v1b.py > $V/verdict_test_copy.py
+diff <(sed 's#^B8 = .*##' $D/code/verdict_M8v1b.py) <(sed 's#^B8 = .*##' $V/verdict_test_copy.py) > /dev/null && echo "copy differs only on path line" >> $V/done
+cd $V && PYTHONHASHSEED=0 OMP_NUM_THREADS=1 nice -n 10 $PY -u $V/verdict_test_copy.py > $V/verdict_test.log 2>&1; echo "verdict exit $?" >> $V/done
diff --git a/results/hashing/m8_v1b/code/smoke_evalonly.py b/results/hashing/m8_v1b/code/smoke_evalonly.py
new file mode 100644
index 0000000000000000000000000000000000000000..33cd6b6c0bbe59102f32e94281709e7e5038c13d
--- /dev/null
+++ b/results/hashing/m8_v1b/code/smoke_evalonly.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+"""SMOKE SEULEMENT (test du pipeline de verdict) : recharge le modèle smoke sauvegardé et rejoue l'éval v4.2 de train_m8v1b.py sur toutes les
+fenêtres, maxpos réduit, vers un dossier de test. Ne sert pas au run M8 v1b."""
+import sys, os, json, time, hashlib
+HERE = os.path.dirname(os.path.abspath(__file__)); sys.path.insert(0, HERE); sys.path.insert(0, "/workspace/spira_shared/checker")
+import numpy as np
+from countmin import CMSPIRA
+from spira import SPIRA
+from spira.hashing import fnv1a64
+arm, ckpt, datap, OD, maxpos, src_res = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], int(sys.argv[5]), sys.argv[6]
+os.makedirs(OD, exist_ok=True); m = (CMSPIRA if arm == "cm" else SPIRA).load(ckpt); data = open(datap, "rb").read()
+base = json.loads(open(src_res).readline())
+src = open("/workspace/spira_shared/checker/eval_ref_v3.py").read(); g = {"np": np, "fnv1a64": fnv1a64}
+exec(src[src.index("def eval_hits"):src.index("m = SPIRA.load(ckpt)")], g); eval_hits = g["eval_hits"]
+from windows_v2 import freshcode_v2
+S = "/workspace/spira_shared"; W7 = f"{S}/spira_m7/windows"
+WP = {"seen": lambda: data[:200_000], "fc2": freshcode_v2, "fresh_en": lambda: open(f"{W7}/fresh_en.bin", "rb").read(),
+ "fresh_fr": lambda: open(f"{W7}/fresh_fr.bin", "rb").read(), "test20k": lambda: open(f"{W7}/test20k.bin", "rb").read(),
+ "test_v3": lambda: open(f"{S}/corpus_v3/test.bin", "rb").read(), "queries": lambda: open(f"{W7}/queries.bin", "rb").read()}
+for name in WP:
+ wd = WP[name](); t1 = time.perf_counter(); r, H = eval_hits(m, wd, max_positions=maxpos)
+ pl = np.fromiter((len(p) for p in m.ept.segment(wd)), np.int64); o2 = np.concatenate([[0], np.cumsum(pl)]); n = len(H["fused_hit"])
+ np.savez_compressed(f"{OD}/{arm}__{name}.npz", **H, tgt_start=o2[1:n+1], tgt_len=pl[1:n+1], window_sha256=np.array(hashlib.sha256(wd).hexdigest()))
+ rec = dict(base); rec.update({"window": name, "n": n, "fused_invocab_pct": round(100*r["fused_acc_invocab"], 3), "eval_s": round(time.perf_counter()-t1, 1)})
+ open(f"{OD}/results.jsonl", "a").write(json.dumps(rec) + "\n"); print(json.dumps({k: rec[k] for k in ("arm", "window", "n", "fused_invocab_pct", "eval_s")}), flush=True)
diff --git a/results/hashing/m8_v1b/code/train_cm_m8.py.orig_ref b/results/hashing/m8_v1b/code/train_cm_m8.py.orig_ref
new file mode 100644
index 0000000000000000000000000000000000000000..2915bbc83b9a41cf51d970575a78333ac1ed377c
--- /dev/null
+++ b/results/hashing/m8_v1b/code/train_cm_m8.py.orig_ref
@@ -0,0 +1,20 @@
+"""M8 — checkpoint CM (Hashing). Mêmes hyperparamètres que checker/train_scale_v2.py (config du repo : V=16384,
+600k tokens SNN × 2 époques, AM 1,2M, seed 20261022) + neurones CM (±2, top-16 PPMI, d24/4096).
+Disposition = verdict M7 (resonly | concat). Séquence : build -> prepare -> train -> calibrate_fusion(train[:60_000]) -> save,
+puis vérification que l'échelle est bien dans le ckpt. Usage : CORPUS LAYOUT OUT.npz"""
+import sys, json, time
+sys.path.insert(0, "/workspace/spira_shared/semhash")
+from countmin import CMSPIRA, save_with_calibration, SPIRAConfig
+from resonly import CMResOnly
+corpus, layout, out = sys.argv[1:4]
+Cls = {"resonly": CMResOnly, "concat": CMSPIRA}[layout]
+log = lambda *a: print(time.strftime("%H:%M:%S"), *a, flush=True)
+data = open(f"/workspace/spira_shared/broad/{corpus}/train.bin", "rb").read()
+cfg = SPIRAConfig(vocab_size=16384, d_in=1024, snn_tokens=600_000, am_tokens=1_200_000, epochs=2); log("cfg", cfg, layout)
+t0 = time.time(); m = Cls.build_cm(data, cfg, log=log); m.prepare(); log("n_state", m.core.n_state)
+h = m.train(log_fn=log, ckpt_path=None)
+saved = save_with_calibration(m, out, data[:60_000])
+assert Cls.load(out).fusion["scale"] == saved["scale"]
+json.dump({"corpus": corpus, "layout": layout, "history": h, "fusion": saved, "secs": time.time() - t0, "n_state": m.core.n_state},
+ open(out.replace(".npz", ".summary.json"), "w"), default=str, indent=1)
+log("CALIBRATED+SAVED", saved)
diff --git a/results/hashing/m8_v1b/code/verdict_M8v1b.r2.py b/results/hashing/m8_v1b/code/verdict_M8v1b.r2.py
new file mode 100644
index 0000000000000000000000000000000000000000..b54ddbeb2d8b3c7df5df2842c8a9ce0a406fd509
--- /dev/null
+++ b/results/hashing/m8_v1b/code/verdict_M8v1b.r2.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict M8 v1b (cm = M8 neurones CM concat, contre ctl = même code sans CM, budget égal), chemin v4.2.
+Dérivé de lever2_sparse/code/verdict_SP.py (sha256 7a6d5414…a2deb, copie : verdict_SP.py.orig_ref). Calculs identiques (positions in-vocab dans
+les DEUX bras, taux APPARIÉS même dénominateur, McNemar exact bilatéral, bootstrap apparié blocs 512 o B=10 000 seed 0, bootstrap positions seed 25).
+SEULS changements : (1) bras ctl/cm lus dans m8_v1b/runs ; (2) fenêtre seen = v1b_sample[:200 000] (audit trained_frac identique) ;
+(3) test_v3 ajoutée, VALIDE ssi recompte 64 o de l'échantillon = 0 ET recompte v1b = 0 ET drapeau GO_CHECKER_PASS présent, sinon exclue ;
+(4) queries rapportée À PART (hors règle) ; neither_code non évaluée (exclue) ; (5) positions propres : chaque fenêtre fraîche exige
+confirmed_window_positions = 0 dans le recompte de l'échantillon (sinon fenêtre NON COMPARABLE, exclue) ; test20k strict = masque
+mask_oldtest_strict.npz (old_local_v1 ∪ broad_local_v1) ∪ échantillon (0 position, vérifié) ; (6) gain significatif = McNemar p<0,05 ET c>b ET
+IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+epochs, ticks/époque, sha256 des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick != snn_tokens), ou seen NON COMPARABLE
+(trained_frac < 0,99 dans un bras ; trained_frac calculé sur les tokens RÉELLEMENT entraînés = ticks × 1, pas sur snn_tokens déclaré).
+Révision 2 (12 h 08 Toronto) : contrôle d'unités rendu explicite (TOKENS_PER_TICK = 1, spiking.py l. 471-539) et audit seen sur tokens réellement entraînés.
+Règle : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+ET aucune perte significative sur une fenêtre valide (seen + fraîches valides) ; sinon REJETÉ."""
+import sys, os, json, math, hashlib, numpy as np
+B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; D = f"{B8}/runs"; OP = f"{B8}/verdict"; RT, CT = "ctl", "cm"
+SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; SEP = ["queries"]
+RCNAME = {"fc2": "fc2", "fresh_en": "m7_fresh_en", "fresh_fr": "m7_fresh_fr", "test20k": "m7_test20k", "test_v3": "corpus_v3_test", "queries": "m7_queries"}
+BLK, NB, SEED = 512, 10000, 0
+os.makedirs(OP, exist_ok=True); MS = np.load(MASKP)
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+# ---- budgets égaux (sinon NON MESURABLE)
+RES = [json.loads(l) for l in open(f"{D}/results.jsonl") if l.strip()]
+def arm_field(arm, f):
+ v = {json.dumps(r.get(f), sort_keys=True) for r in RES if r.get("arm") == arm}; return json.loads(v.pop()) if len(v) == 1 else "INCOHERENT"
+BUD = {f: {RT: arm_field(RT, f), CT: arm_field(CT, f)} for f in ("snn_tokens", "am_tokens", "epochs", "ticks_per_epoch", "data_sha256")}
+# Unités : spira/spiking.py SpikingCore.train_pass (l. 471-539) fait UN tick par token SNN (neurons[t] = token t, "ticks": T = len(cols)),
+# donc tokens SNN entraînés par époque = ticks × TOKENS_PER_TICK, TOKENS_PER_TICK = 1. Contrôles : (i) égalité cm == ctl de chaque champ ;
+# (ii) données = échantillon ; (iii) chaque époque a entraîné TOUT le budget : ticks × TOKENS_PER_TICK == snn_tokens (sinon passe tronquée).
+TOKENS_PER_TICK = 1
+EQUAL = {f: (v[RT] == v[CT] and v[RT] != "INCOHERENT" and v[RT] is not None) for f, v in BUD.items()}
+TRAINED = {x: ([t * TOKENS_PER_TICK for t in BUD["ticks_per_epoch"][x]] if isinstance(BUD["ticks_per_epoch"][x], list) else None) for x in (RT, CT)}
+FULL = {x: (TRAINED[x] is not None and isinstance(BUD["epochs"][x], int) and len(TRAINED[x]) == BUD["epochs"][x]
+ and all(t == BUD["snn_tokens"][x] for t in TRAINED[x])) for x in (RT, CT)}
+BUDGET_OK = all(EQUAL.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA and FULL[RT] and FULL[CT]
+BUDGET_CHECK = {"equal_cm_ctl": EQUAL, "data_is_sample": BUD["data_sha256"][RT] == SAMPLE_SHA, "tokens_per_tick": TOKENS_PER_TICK,
+ "trained_snn_tokens_per_epoch": TRAINED, "full_budget_each_epoch": FULL}
+# tokens SNN réellement entraînés (pour l'audit seen) = min sur les époques de ticks × TOKENS_PER_TICK, borné par snn_tokens
+TRAINED_MIN = {x: (min(min(TRAINED[x]), BUD["snn_tokens"][x]) if TRAINED[x] and isinstance(BUD["snn_tokens"][x], int) else None) for x in (RT, CT)}
+# ---- propreté des fenêtres fraîches
+RCS = json.load(open(RC_SAMPLE)); RCV = json.load(open(RC_V1B))["overlap64_recount_v1b"]["per_window"]
+assert RCS["sha256"] == SAMPLE_SHA, "recompte : échantillon différent"
+CLEAN = {}
+for w, k in RCNAME.items():
+ cs = RCS["windows"][k]["confirmed_window_positions"]; cv = RCV[k]["confirmed_window_positions"] if k in RCV else None
+ CLEAN[w] = {"sample_confirmed_window_positions": cs, "v1b_confirmed_window_positions": cv, "window_sha256_recount": RCS["windows"][k]["window_sha256"]}
+VALID = {w: CLEAN[w]["sample_confirmed_window_positions"] == 0 for w in FRESH + SEP}
+VALID["test_v3"] = VALID["test_v3"] and CLEAN["test_v3"]["v1b_confirmed_window_positions"] == 0 and os.path.exists(GO)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN + SEP:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{D}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ if w in RCNAME: assert str(A["window_sha256"]) == CLEAN[w]["window_sha256_recount"], f"{w}: fenêtre != fenêtre recomptée"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": CLEAN["test20k"]["sample_confirmed_window_positions"],
+ "excluded_union": int((bo | bb_).sum()), "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ ia1, ib1 = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k; one_side = int((ia1 ^ ib1).sum())
+ k = k & A["invocab"].astype(bool) & B["invocab"].astype(bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); p = binp(b, c)
+ acc_a, acc_b = 100 * (ha & k).sum() / max(1, k.sum()), 100 * (hb & k).sum() / max(1, k.sum())
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], k[k], nbk); sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], k[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, k)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b and lo > 0), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "invocab_identical": inv_same, "n_invocab_one_side_only_dropped": one_side, "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a), "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p,
+ "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m, "sig_gain": gain, "sig_loss": loss,
+ "boot_conflict": bool((p < 0.05 and c > b and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"]),
+ "valid": (True if w == "seen" else VALID[w]), "in_rule": w in WIN, "clean_recount": CLEAN.get(w)}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+# ---- audit trained_frac du seen (identique à verdict_SP, fenêtre = échantillon[:200 000])
+_A = np.load(f"{D}/{RT}__seen.npz"); _st, _ln = _A["tgt_start"].astype(np.int64), _A["tgt_len"].astype(np.int64)
+_contig = bool(np.all(_st[1:] == _st[:-1] + _ln[:-1]) and _st[0] > 0 and _st[0] <= int(_ln.max()))
+_sb = open(SAMPLE, "rb").read(); _wok = hashlib.sha256(_sb[:200_000]).hexdigest() == R["seen"]["window_sha256"] and hashlib.sha256(_sb).hexdigest() == SAMPLE_SHA; del _sb
+_ksnn = {"ref": TRAINED_MIN[RT], "cand": TRAINED_MIN[CT]} # tokens SNN réellement entraînés (ticks × 1), pas le budget déclaré
+_k, _ha, _hb, _iv = KEEP["seen"]; _ivb = _k & _iv & np.load(f"{D}/{CT}__seen.npz")["invocab"].astype(bool); _ctx = np.arange(len(_st))
+SEEN_AUDIT = {"window_is_sample_prefix_200000": _wok, "targets_contiguous_from_patch1": _contig, "snn_tokens": _ksnn,
+ "max_ctx_patch_index": int(_ctx.max()), "max_byte_evaluated": int((_st + _ln).max()), "invocab_both_n": int(_ivb.sum())}
+for side in ("ref", "cand"):
+ ok = _wok and _contig and isinstance(_ksnn[side], int)
+ n_tr = int((_ivb & (_ctx < _ksnn[side])).sum()) if ok else None
+ SEEN_AUDIT[f"trained_invocab_n_{side}"] = n_tr; SEEN_AUDIT[f"trained_frac_{side}"] = (n_tr / max(1, int(_ivb.sum()))) if n_tr is not None else None
+SEEN_OK = all(SEEN_AUDIT[f"trained_frac_{x}"] is not None and SEEN_AUDIT[f"trained_frac_{x}"] >= 0.99 for x in ("ref", "cand"))
+SEEN_AUDIT["seen_comparable"] = SEEN_OK; print("seen_audit", json.dumps(SEEN_AUDIT), flush=True)
+FV = [w for w in FRESH if VALID[w]]
+def gapcalc(GW):
+ gap = {}
+ for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt),
+ "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+ dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GW], axis=0))
+ gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+ gap["windows"] = GW; return gap
+GAPS = {"with_test_v3": gapcalc(FV), "without_test_v3": gapcalc([w for w in FV if w != "test_v3"])}
+VW = ["seen"] + FV
+L = [w for w in VW if R[w]["sig_loss"]]; G = [w for w in VW if R[w]["sig_gain"]]; GF = [w for w in FV if R[w]["sig_gain"]]
+why = []
+if not BUDGET_OK:
+ if not all(EQUAL.values()): why.append("budgets cm/ctl inégaux : " + ", ".join(f for f, ok in EQUAL.items() if not ok))
+ if BUD["data_sha256"][RT] != SAMPLE_SHA: why.append("données != échantillon v1b")
+ if not (FULL[RT] and FULL[CT]): why.append(f"passe SNN incomplète : tokens entraînés/époque (ticks × {TOKENS_PER_TICK}) ctl {TRAINED[RT]} / cm {TRAINED[CT]} != snn_tokens {BUD['snn_tokens'][RT]}")
+if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+if BUDGET_OK and SEEN_OK:
+ dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+ if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+else: dec = "NON MESURABLE"
+out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+ "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
+ "results_jsonl_sha256": hashlib.sha256(open(f"{D}/results.jsonl", "rb").read()).hexdigest(),
+ "recount_sample_sha256": hashlib.sha256(open(RC_SAMPLE, "rb").read()).hexdigest(), "mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}/verdict_M8v1b.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b {SAMPLE_SHA[:8]}…\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).", "",
+ "| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|---|"]
+for w in WIN + SEP:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ if w in SEP: dd += " (à part, hors règle)"
+ elif not r["valid"]: dd = "EXCLUE (non propre / non confirmée)"
+ md.append(f"| {w}{' strict' if w == 'test20k' else ''} | {r['valid']} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd} |")
+md += ["", f"neither_code : exclue (non évaluée). test20k strict : {EX.get('excluded_union')} positions exclues (old ∪ broad), 0 par l'échantillon.",
+ f"Budgets : {json.dumps(BUD)} ; contrôle {json.dumps(BUDGET_CHECK)} → {'OK (égaux, budget SNN entier entraîné)' if BUDGET_OK else 'NON OK'}.",
+ f"Audit seen : trained_frac ctl {SEEN_AUDIT['trained_frac_ref']} / cm {SEEN_AUDIT['trained_frac_cand']} → seen {'COMPARABLE' if SEEN_OK else 'NON COMPARABLE'}.",
+ f"Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl {GAPS['with_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f} [{GAPS['with_test_v3']['cand_minus_ref']['ci95'][0]:+.3f} ; {GAPS['with_test_v3']['cand_minus_ref']['ci95'][1]:+.3f}] ; sans test_v3 : {GAPS['without_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f}.",
+ f"Script sha256 {out['script_sha256']}.", ""]
+open(f"{OP}/verdict_M8v1b.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m8_v1b/code/verdict_SP.py.orig_ref b/results/hashing/m8_v1b/code/verdict_SP.py.orig_ref
new file mode 100644
index 0000000000000000000000000000000000000000..5eb46f3d4fb4bc5b439596b6711185f3cb95e679
--- /dev/null
+++ b/results/hashing/m8_v1b/code/verdict_SP.py.orig_ref
@@ -0,0 +1,134 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict levier 2 SPARSITÉ (SP1/SP2, argument 1) — copie de lever2/verdict_AH1/verdict_AH1.py, SEULS changements :
+bras candidat lu dans lever2_sparse/short_old, sortie dans lever2_sparse/verdict_, libellés. Témoin, masque et protocole identiques.
+(ex-docstring AH1) verdict levier 2 AH1 (eta_ah=1e-3) contre le témoin à budget égal ref (eta_ah=0), méthode banc v4.1
+(copie adaptée de m7_v41/strict/verdict_m7_v41_strict.py ; lecture seule des hits short_old/{ref,AH1}__*.npz, aucun modèle chargé).
+Fenêtres MESURÉES par run_l2.py (4000 positions chacune) : seen (= old_local_v1/train[:200000]), fc2, fresh_en, fresh_fr, test20k
+(= old_local_v1/test.bin, sha ce0526c6…, PAS broad_local_v1/test.bin ; masque strict propre recalculé : verdict_AH1/mask_oldtest_strict.npz,
+union old_local_v1 ∪ broad_local_v1). queries et test_v3 : NON évalués par les bras → absents (non mesurables). neither_code exclu.
+hit = fused_hit & invocab. Appariement par position si tgt_start et tgt_len identiques (vérifié). McNemar exact bilatéral = DÉCISION (p<0,05).
+Bootstrap par blocs de 512 o (bloc = tgt_start // 512), B = 10 000, un générateur seed 0, fenêtres dans l'ordre WIN, apparié ; stat = acc invocab.
+Écart seen − moyenne fraîche (fc2, fresh_en, fresh_fr, test20k strict ; test_v3 non mesuré). Bootstrap secondaire par positions, seed 25.
+Correctif v4.2 (Hashing 24 oct. ~09 h 39, Toronto ; original = verdict_SP.py.bak_0950) : positions gardées ssi in-vocab dans les DEUX bras (et propres) ;
+McNemar, taux (APPARIÉS, même dénominateur) et bootstrap sur ce seul ensemble. Tokenisation identique exigée (assert) ⇒ unités v4.2 = patches.
+Si invocab est identique entre bras (cas AH1/AH2), résultat identique à v4.1.
+Critère utilisateur : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche ET aucune perte significative sur une fenêtre valide ; sinon REJETÉ."""
+import sys, os, json, math, hashlib, numpy as np
+D = "/workspace/spira_shared/hashing_gen/lever2/short_old"; RT, CT = "ref", sys.argv[1]; assert CT in ("SP1", "SP2")
+DC = "/workspace/spira_shared/hashing_gen/lever2_sparse/short_old"; OP = f"/workspace/spira_shared/hashing_gen/lever2_sparse/verdict_{CT}"
+MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+DESC = {'SP1': 'SP1 (k-WTA k=51 sur les spikes, N=512, rho=0.1)', 'SP2': 'SP2 (seuil adaptatif theta += 1e-3*(s-0.1), theta0=0, figé en éval)'}[CT]
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k"]; GAPW = FRESH
+NOT_MEASURED = ["queries", "test_v3"]; BLK, NB, SEED = 512, 10000, 0
+os.makedirs(OP, exist_ok=True); MS = np.load(MASKP)
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{DC}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_union": int((bo | bb_).sum()),
+ "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ ia1, ib1 = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k; one_side = int((ia1 ^ ib1).sum())
+ k = k & A["invocab"].astype(bool) & B["invocab"].astype(bool) # v4.2 : in-vocab dans les DEUX bras
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); p = binp(b, c)
+ ia, ib = k.copy(), k.copy()
+ acc_a, acc_b = 100 * (ha & k).sum() / ia.sum(), 100 * (hb & k).sum() / ib.sum() # taux APPARIÉS (même dénominateur)
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], k[k], nbk)
+ sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], k[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, k)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "n_invocab_clean_ref": int(ia.sum()), "n_invocab_clean_cand": int(ib.sum()), "invocab_identical": inv_same, "n_invocab_one_side_only_dropped": one_side, "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "pairing": "position (tokenizers identiques, tgt_start/tgt_len vérifiés)", "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a),
+ "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p, "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m,
+ "sig_gain": gain, "sig_loss": loss, "boot_conflict": bool((gain and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"])}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+# --- 09 h 58 (Toronto), réserve Checker 09 h 45 : audit trained_frac du seen (fenêtre = old_local_v1/train[:200000]) ---
+# SNN entraîné sur ids[:snn_tokens] (model.prepare : neuron_rows(ids[:n_snn]), cols_of(ids[:n_snn+1])). Position i du seen : contexte = patch i,
+# cible = patch i+1, SI les cibles sont contiguës depuis le patch 1 (vérifié : tgt_start[0] = fin du patch 0, tgt_start[i+1] = tgt_start[i]+tgt_len[i])
+# ET si la segmentation de train[:200000] coïncide avec celle de train.bin sur ce préfixe (hypothèse EPT gauche→droite ; derniers octets évalués << 200000).
+# Entraînée ssi patch de contexte i < snn_tokens. trained_frac < 0,99 => seen NON COMPARABLE et ADOPTÉ impossible.
+TRAIN_OLD = "/workspace/spira_shared/broad/old_local_v1/train.bin"
+def _snn_tokens(path, arm):
+ v = {json.loads(l).get("snn_tokens") for l in open(path) if l.strip() and json.loads(l).get("arm") == arm and json.loads(l).get("window") == "seen"}
+ return v.pop() if len(v) == 1 else None
+_A = np.load(f"{D}/{RT}__seen.npz"); _st, _ln = _A["tgt_start"].astype(np.int64), _A["tgt_len"].astype(np.int64)
+_contig = bool(np.all(_st[1:] == _st[:-1] + _ln[:-1]) and _st[0] > 0 and _st[0] <= int(_ln.max()))
+_wsha = hashlib.sha256(open(TRAIN_OLD, "rb").read(200_000)).hexdigest(); _wok = _wsha == R["seen"]["window_sha256"]
+_ksnn = {"ref": _snn_tokens(f"{D}/results.jsonl", RT), "cand": _snn_tokens(f"{DC}/results.jsonl", CT)}
+_k, _ha, _hb, _iv = KEEP["seen"]; _ivb = _k & _iv & np.load(f"{DC}/{CT}__seen.npz")["invocab"].astype(bool); _ctx = np.arange(len(_st))
+SEEN_AUDIT = {"window_is_train_prefix_200000": _wok, "targets_contiguous_from_patch1": _contig, "snn_tokens": _ksnn,
+ "max_ctx_patch_index": int(_ctx.max()), "max_byte_evaluated": int((_st + _ln).max()), "invocab_both_n": int(_ivb.sum())}
+for side in ("ref", "cand"):
+ n_tr = int((_ivb & (_ctx < _ksnn[side])).sum()) if (_wok and _contig and _ksnn[side]) else None
+ SEEN_AUDIT[f"trained_invocab_n_{side}"] = n_tr; SEEN_AUDIT[f"trained_frac_{side}"] = (n_tr / max(1, int(_ivb.sum()))) if n_tr is not None else None
+SEEN_OK = all(SEEN_AUDIT[f"trained_frac_{x}"] is not None and SEEN_AUDIT[f"trained_frac_{x}"] >= 0.99 for x in ("ref", "cand"))
+SEEN_AUDIT["seen_comparable"] = SEEN_OK; print("seen_audit", json.dumps(SEEN_AUDIT), flush=True)
+FRESH_MEAN_NOTE = ("moyenne fraîche = fc2, fresh_en, fresh_fr, test20k strict SEULEMENT (test_v3 et queries non mesurés par les bras) : "
+ "l'écart seen − moyenne fraîche n'est PAS comparable à celui du banc v4 (qui inclut test_v3) ; décision non affectée")
+gap = {}
+for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GAPW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GAPW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt), "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GAPW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+R2 = np.random.default_rng(25); BP = {}
+for w in WIN:
+ k, ha_, hb_, iv_ = KEEP[w]; m_ = k & iv_; r_ = ha_[m_].astype(np.float64); c_ = hb_[m_].astype(np.float64); n_ = len(r_); ar = np.empty(NB); ac = np.empty(NB)
+ for t in range(NB):
+ i = R2.integers(0, n_, n_); ar[t] = r_[i].mean(); ac[t] = c_[i].mean()
+ BP[w] = (100 * ar, 100 * ac)
+dgp = (BP["seen"][1] - np.mean([BP[w][1] for w in GAPW], axis=0)) - (BP["seen"][0] - np.mean([BP[w][0] for w in GAPW], axis=0))
+gap["cand_minus_ref"]["ci95_boot_positions_seed25"] = [float(x) for x in np.percentile(dgp, [2.5, 97.5])]
+gap["windows"] = GAPW; gap["note"] = FRESH_MEAN_NOTE + " ; neither_code exclu"; gap["comparable_to_bench_v4"] = False
+L = [w for w in WIN if R[w]["sig_loss"]]; G = [w for w in WIN if R[w]["sig_gain"]]; GF = [w for w in FRESH if R[w]["sig_gain"]]
+dec = "ADOPTÉ" if (SEEN_OK and R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+why = []
+if not SEEN_OK: why.append("seen NON COMPARABLE (audit trained_frac < 0,99 ou non vérifiable)")
+if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+if not GF: why.append("aucun gain significatif sur une fenêtre fraîche")
+if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+out = {"cand": DESC, "ref": "ref (eta_ah=0, budget égal)", "corpus": "broad/old_local_v1", "snn_tokens": 24000, "epochs": 2, "max_positions": 4000,
+ "windows_measured": WIN, "windows_not_measured": NOT_MEASURED, "excluded": ["neither_code"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05) sur seen ET sur >=1 fenêtre fraîche (fc2, fresh_en, fresh_fr, test20k strict) ET aucune perte significative sur une fenêtre valide",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED, "stat": "acc invocab fused, blocs = tgt_start//512, apparié"}, "per_window": R, "seen_fresh_gap": gap, "seen_trained_audit": SEEN_AUDIT,
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D if a == RT else DC}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN},
+ "mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest(), "mask_path": MASKP}
+json.dump(out, open(f"{OP}/verdict_{CT}.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict levier 2 — {DESC} contre ref (eta_ah = 0, budget égal), old_local_v1 court\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), 4000 positions par fenêtre, appariement par position (tokenisation identique vérifiée).", "",
+ f"| fenêtre | n apparié | {CT} % | réf % | Δ pts | b (réf seule) / c ({CT} seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|"]
+for w in WIN:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ nm = "test20k strict (old_local_v1/test.bin, union old ∪ broad)" if w == "test20k" else w
+ md.append(f"| {nm} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd}{' ⚠ conflit bootstrap' if r['boot_conflict'] else ''} |")
+md += ["| queries | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "| test_v3 | — | non mesuré | non mesuré | — | — | — | — | non mesurable (fenêtre absente du run) |", "",
+ f"test20k strict : {EX['excluded_union']} positions exclues sur 4000 ({EX['excluded_by_old_local_v1']} par old_local_v1, {EX['excluded_by_broad_local_v1']} par broad_local_v1), octets évalués jusqu'à {EX['max_byte_evaluated']}.", "",
+ f"Audit seen (trained_frac, positions in-vocab des deux bras dont le patch de contexte est dans ids[:snn_tokens]) : réf {SEEN_AUDIT['trained_frac_ref']} ({SEEN_AUDIT['trained_invocab_n_ref']}/{SEEN_AUDIT['invocab_both_n']}), {CT} {SEEN_AUDIT['trained_frac_cand']} ({SEEN_AUDIT['trained_invocab_n_cand']}/{SEEN_AUDIT['invocab_both_n']}) ; snn_tokens {SEEN_AUDIT['snn_tokens']} ; patch de contexte max {SEEN_AUDIT['max_ctx_patch_index']} ; fenêtre = train[:200000] {SEEN_AUDIT['window_is_train_prefix_200000']} ; cibles contiguës {SEEN_AUDIT['targets_contiguous_from_patch1']} → seen {'COMPARABLE' if SEEN_OK else 'NON COMPARABLE'}.", "",
+ f"Note : {FRESH_MEAN_NOTE}.", "",
+ f"Écart seen − moyenne fraîche ({', '.join(GAPW)} ; test_v3 non mesuré) : {CT} {gap['cand']['gap_pct']:+.3f} pts [IC95 {gap['cand']['ci95'][0]:+.3f} ; {gap['cand']['ci95'][1]:+.3f}] (fraîche {gap['cand']['fresh_mean_pct']:.3f} %) ; réf {gap['ref']['gap_pct']:+.3f} pts [{gap['ref']['ci95'][0]:+.3f} ; {gap['ref']['ci95'][1]:+.3f}] (fraîche {gap['ref']['fresh_mean_pct']:.3f} %) ; différence {CT} − réf {gap['cand_minus_ref']['gap_diff_pct']:+.3f} [blocs 512 o seed 0 : {gap['cand_minus_ref']['ci95'][0]:+.3f} ; {gap['cand_minus_ref']['ci95'][1]:+.3f}] [positions seed 25 : {gap['cand_minus_ref']['ci95_boot_positions_seed25'][0]:+.3f} ; {gap['cand_minus_ref']['ci95_boot_positions_seed25'][1]:+.3f}].", "",
+ f"Script sha256 {out['script_sha256']} ; masque sha256 {out['mask_sha256']}.", ""]
+open(f"{OP}/verdict_{CT}.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m8_v1b/gate_m8v1b.sh b/results/hashing/m8_v1b/gate_m8v1b.sh
new file mode 100644
index 0000000000000000000000000000000000000000..baf2b60c0f650c97b4dca279499438bf1aa33add
--- /dev/null
+++ b/results/hashing/m8_v1b/gate_m8v1b.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# SPIRA Hashing — porte M8 v1b. Lance les deux bras (ctl, cm) de train_m8v1b.py sur sample/v1b_sample.bin, puis le verdict figé.
+# Conditions (TOUTES) : (a) drapeau m8_v1b/GO_CHECKER_PASS présent (posé à la main par Hashing après PASS écrit de Checker sur recompte v1b
+# ET audit du script de verdict — ce script ne le crée JAMAIS) ; (b) lourds (python RSS >= 500 Mo) < 4 ; (c) MemAvailable >= 4,4 GiB + pic
+# mesuré du bras (et >= 5,2 Go), + la marge restante du bras déjà en cours (pic − RSS actuel) => parallèle seulement si les deux tiennent.
+# Chaque bras passe par code/run_guarded.sh (re-vérifie la porte, setsid nice 10, chien de garde 4,4 GiB qui ne tue que son groupe).
+# Reprise : en cas d'échec (ex. chien de garde), relance <= 3 fois ; train_m8v1b.py reprend à la dernière époque complète (équivalence bit à bit testée).
+export TZ=America/Toronto OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0 TMPDIR=/workspace/spira_shared/hashing_gen/m8_v1b/tmp
+D=/workspace/spira_shared/hashing_gen/m8_v1b; PY=/workspace/SPIRA-venv/bin/python; G=$D/code/run_guarded.sh
+FLAG=$D/GO_CHECKER_PASS; ST=$D/STATUS; GL=$D/logs/gate_m8v1b.log; FLOOR=4724464025
+declare -A PEAK=( [ctl]=1600000000 [cm]=2500000000 ) # pics mesurés au smoke : ctl 1 261 Mo, cm 2 140 Mo (ru_maxrss) ; marge ~+17-27 %
+declare -A S=( [ctl]=pending [cm]=pending ); declare -A TRY=( [ctl]=0 [cm]=0 )
+log(){ echo "$(date '+%F %H:%M:%S %Z') $*" >> $GL; }
+status(){ echo "$(date '+%F %H:%M:%S %Z') $* | ctl=${S[ctl]}(try ${TRY[ctl]}) cm=${S[cm]}(try ${TRY[cm]}) | gate pid $$" > $ST; }
+mem(){ awk '/MemAvailable/{print $2*1024}' /proc/meminfo; }
+nheavy(){ ps -eo rss,comm | awk '$2 ~ /^python/ && $1>=500000' | wc -l; }
+armrss(){ pgrep -f "train_m8v1b.py --arm $1 " | xargs -r ps -o rss= -p 2>/dev/null | awk '{s+=$1}END{print s*1024+0}'; }
+log "ARMÉ pid=$$ ; drapeau attendu $FLAG (non créé par ce script) ; pics ctl=${PEAK[ctl]} cm=${PEAK[cm]}"
+while :; do
+ for arm in ctl cm; do
+ if [ "${S[$arm]}" = running ] && [ -e $D/logs/arm_$arm.exit ]; then
+ e=$(cat $D/logs/arm_$arm.exit); rm -f $D/logs/arm_$arm.exit; log "bras $arm fin code $e"
+ if [ "$e" = 0 ]; then S[$arm]=done; elif [ "$e" = 3 ]; then S[$arm]=pending; TRY[$arm]=$((TRY[$arm]-1));
+ elif [ ${TRY[$arm]} -ge 3 ]; then S[$arm]=failed; else S[$arm]=pending; fi
+ fi
+ done
+ if [ "${S[ctl]}" = done ] && [ "${S[cm]}" = done ]; then
+ status "VERDICT en cours"; log "deux bras faits -> verdict"
+ nice -n 10 $PY -u $D/code/verdict_M8v1b.py > $D/logs/verdict_M8v1b_run.log 2>&1; e=$?
+ log "verdict code $e"; status "FINI verdict code $e (verdict/verdict_M8v1b.md)"; exit $e
+ fi
+ if [ "${S[ctl]}" = failed ] || [ "${S[cm]}" = failed ]; then
+ if [ "${S[ctl]}" != running ] && [ "${S[cm]}" != running ]; then status "ÉCHEC (3 essais) — voir $GL"; log "ÉCHEC"; exit 1; fi
+ fi
+ if [ ! -e $FLAG ]; then status "ATTENTE drapeau GO_CHECKER_PASS (posé par Hashing après PASS Checker)"; sleep 60; continue; fi
+ for arm in ctl cm; do
+ [ "${S[$arm]}" = pending ] || continue
+ m=$(mem); nh=$(nheavy); extra=0
+ for o in ctl cm; do [ "${S[$o]}" = running ] && { r=$(armrss $o); x=$(( PEAK[$o] - r )); [ $x -gt 0 ] && extra=$((extra + x)); }; done
+ need=$(( FLOOR + PEAK[$arm] + extra )); [ $need -lt 5200000000 ] && need=5200000000
+ if [ $nh -lt 4 ] && [ $m -ge $need ]; then
+ TRY[$arm]=$((TRY[$arm]+1)); S[$arm]=running
+ log "LANCE $arm essai ${TRY[$arm]} MemAvailable=$m need=$need lourds=$nh"
+ ( $G m8v1b_$arm ${PEAK[$arm]} $D/logs/arm_${arm}_try${TRY[$arm]}.log -- $PY -u $D/code/train_m8v1b.py --arm $arm --data $D/sample/v1b_sample.bin \
+ --outdir $D/runs --snn-tokens 600000 --am-tokens 1200000 --epochs 2 --maxpos 4000 --windows seen,fc2,fresh_en,fresh_fr,test20k,test_v3,queries
+ echo $? > $D/logs/arm_$arm.exit ) &
+ sleep 120 # laisser le RSS du bras lancé apparaître avant de juger l'autre
+ else status "ATTENTE ressources pour $arm : MemAvailable=$m need=$need lourds=$nh"; fi
+ done
+ { [ "${S[ctl]}" = running ] || [ "${S[cm]}" = running ]; } && status "EN COURS"; sleep 60
+done
diff --git a/results/hashing/m8_v1b/gen_bench_plan.md b/results/hashing/m8_v1b/gen_bench_plan.md
new file mode 100644
index 0000000000000000000000000000000000000000..a8bfe85e6ba3e15206653d2617f8fe8b2b6e3fba
--- /dev/null
+++ b/results/hashing/m8_v1b/gen_bench_plan.md
@@ -0,0 +1,29 @@
+# Plan — banc de génération sur le checkpoint ctl M8 v1b (5 prompts × 200 o) — SPIRA Hashing
+Rédigé le 2026-10-24 vers 14 h 22 (Toronto). **PLAN SEULEMENT** : rien n'est lancé ; aucun résultat ni checkpoint M8 n'a été ouvert pour l'écrire.
+Statut : **EN ATTENTE DE VALIDATION PAR CHECKER**. Proposé par Relay (5 prompts × 200 o).
+
+## 1. Quand
+- **Seulement APRÈS la publication du verdict M8 v1b** (verdict_M8v1b.py r3B), pour ne rien regarder des sorties du modèle avant le verdict.
+- Avec le PASS écrit de Checker sur ce plan ; avec moins de 4 lourds sur la box et MemAvailable ≥ 5,2 Go ; nice 10, OMP_NUM_THREADS=1.
+
+## 2. Quoi
+- Modèle : checkpoint du bras **ctl** de M8 v1b (sortie de train_m8v1b.py b2b12c8c…, arm ctl, v1b_sample.bin 9ea562e4…). Chemin et sha256 relevés au moment du banc, après le verdict, et cités dans le rapport.
+- **Décodage par défaut du modèle seulement** : boucle = SPIRA.generate (top_k = cfg.top_k, T = cfg.temperature du checkpoint), graine 0, 200 octets par prompt. **Pas de variante de décodage** : pas de v2b, pas de n-gramme, pas de réglage de T / top_k. Le banc n'est pas un levier.
+- Script : copie dans hashing_gen/m8_v1b/gen_bench/ de la seule partie « fused » de checker/gen/gen_eval.py (54a9f865…), avec le chargement du modèle adapté au format du checkpoint train_m8v1b. checker/ n'est pas modifié ; diff publié. Le contrôle « boucle == m.generate sur le 1er prompt » est gardé.
+
+## 3. Prompts fixes, NON issus des fenêtres d'éval
+- **Écart avec la proposition de Relay** : les prompts de checker/gen/prompts_v1.json (en1, en2, fr1, fr2, code) sont extraits de fresh_en, fresh_fr et fc2, qui sont des fenêtres d'éval. Ils sont donc **exclus** ici.
+- 5 prompts rédigés à la main ci-dessous, figés dans ce plan (le sha de ce fichier fait foi). Ils seront copiés tels quels, en UTF-8 sans saut de ligne final, dans gen_bench/prompts_gen_bench.json :
+ - en1 : `The old lighthouse keeper climbed the stairs one last time, and when he reached the top he`
+ - en2 : `To repair a bicycle chain that keeps slipping, the first thing you should check is`
+ - fr1 : `Le matin du départ, la gare était presque vide et le contrôleur, en voyant notre billet,`
+ - fr2 : `Pour réussir une pâte brisée, il faut d'abord mélanger la farine et le beurre froid, puis`
+ - code : `def merge_sorted(a, b):\n """Return a new sorted list with the items of a and b."""\n out = []\n` (« \n » = saut de ligne)
+- Contrôle avant génération, écrit au rapport : aucune sous-chaîne de 32 o d'un prompt présente dans les fenêtres d'éval (fc2, fresh_en, fresh_fr, test20k, test_v3, queries, seen) ni dans v1b_sample.bin. Les prompts font 82 à 99 o ; le seuil de 32 o est plus strict que le recompte 64 o habituel. Si un prompt échoue, il est réécrit et le plan est révisé (révision datée) **avant** toute génération.
+
+## 4. Mesures et sortie
+- Pas de « vraie continuation » : ce sont des prompts libres. Mesures rapportées : octets générés, UTF-8 valide, taux de mots valides (lexique checker/gen/lexicon_v3.json, lu seulement), rep_rate (8-grammes d'octets), langue et domaine de la génération contre ceux du prompt, plus longue copie présente dans v1b_sample.bin.
+- Sorties : hashing_gen/m8_v1b/gen_bench/{results.jsonl, samples/*.txt, report.md}, avec les sha de tout. **Indicatif, non décisionnel** : aucune règle d'adoption ne s'y appuie, et le verdict M8 ne change pas.
+- Aucun push HF sans PASS de push écrit de Checker.
+
+— SPIRA Hashing, 2026-10-24 (Toronto)
diff --git a/results/hashing/m8_v1b/runs/results.jsonl b/results/hashing/m8_v1b/runs/results.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..2e70987c1647695ac70d5a8f981c9a4903fccd3a
--- /dev/null
+++ b/results/hashing/m8_v1b/runs/results.jsonl
@@ -0,0 +1,7 @@
+{"arm": "ctl", "window": "seen", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 2, "ticks_per_epoch": [600000, 600000], "n": 4000, "fused_invocab_pct": 98.44, "fused_all_pct": 97.725, "snn_invocab_pct": 29.693, "cal": {"scale": 0.028181870546416927, "sigma_fast": 0.027239631921833294, "sigma_slow": 0.9665657883485158}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.09603666666666667, 0.08653666666666666], "ticks_per_sec": [83.25117062374575, 83.89241676855215], "eval_s": 46.1, "peak_rss_mb": 1192.8, "ckpt_sha256": "49e0910f3ca4c837b64f901e8b44929f63ef677121a1b2a6c499d284eefaf252", "wall_s": 14520.9}
+{"arm": "ctl", "window": "fc2", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 2, "ticks_per_epoch": [600000, 600000], "n": 4000, "fused_invocab_pct": 4.684, "fused_all_pct": 2.5, "snn_invocab_pct": 3.67, "cal": {"scale": 0.028181870546416927, "sigma_fast": 0.027239631921833294, "sigma_slow": 0.9665657883485158}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.09603666666666667, 0.08653666666666666], "ticks_per_sec": [83.25117062374575, 83.89241676855215], "eval_s": 45.6, "peak_rss_mb": 1192.8, "ckpt_sha256": "49e0910f3ca4c837b64f901e8b44929f63ef677121a1b2a6c499d284eefaf252", "wall_s": 14566.5}
+{"arm": "ctl", "window": "fresh_en", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 2, "ticks_per_epoch": [600000, 600000], "n": 4000, "fused_invocab_pct": 1.606, "fused_all_pct": 0.9, "snn_invocab_pct": 1.651, "cal": {"scale": 0.028181870546416927, "sigma_fast": 0.027239631921833294, "sigma_slow": 0.9665657883485158}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.09603666666666667, 0.08653666666666666], "ticks_per_sec": [83.25117062374575, 83.89241676855215], "eval_s": 47.0, "peak_rss_mb": 1192.8, "ckpt_sha256": "49e0910f3ca4c837b64f901e8b44929f63ef677121a1b2a6c499d284eefaf252", "wall_s": 14613.5}
+{"arm": "ctl", "window": "fresh_fr", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 2, "ticks_per_epoch": [600000, 600000], "n": 4000, "fused_invocab_pct": 1.638, "fused_all_pct": 0.825, "snn_invocab_pct": 1.769, "cal": {"scale": 0.028181870546416927, "sigma_fast": 0.027239631921833294, "sigma_slow": 0.9665657883485158}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.09603666666666667, 0.08653666666666666], "ticks_per_sec": [83.25117062374575, 83.89241676855215], "eval_s": 43.8, "peak_rss_mb": 1192.8, "ckpt_sha256": "49e0910f3ca4c837b64f901e8b44929f63ef677121a1b2a6c499d284eefaf252", "wall_s": 14657.3}
+{"arm": "ctl", "window": "test20k", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 2, "ticks_per_epoch": [600000, 600000], "n": 4000, "fused_invocab_pct": 1.256, "fused_all_pct": 0.65, "snn_invocab_pct": 1.401, "cal": {"scale": 0.028181870546416927, "sigma_fast": 0.027239631921833294, "sigma_slow": 0.9665657883485158}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.09603666666666667, 0.08653666666666666], "ticks_per_sec": [83.25117062374575, 83.89241676855215], "eval_s": 43.1, "peak_rss_mb": 1192.8, "ckpt_sha256": "49e0910f3ca4c837b64f901e8b44929f63ef677121a1b2a6c499d284eefaf252", "wall_s": 14700.4}
+{"arm": "ctl", "window": "test_v3", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 2, "ticks_per_epoch": [600000, 600000], "n": 4000, "fused_invocab_pct": 0.875, "fused_all_pct": 0.375, "snn_invocab_pct": 0.758, "cal": {"scale": 0.028181870546416927, "sigma_fast": 0.027239631921833294, "sigma_slow": 0.9665657883485158}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.09603666666666667, 0.08653666666666666], "ticks_per_sec": [83.25117062374575, 83.89241676855215], "eval_s": 47.5, "peak_rss_mb": 1192.8, "ckpt_sha256": "49e0910f3ca4c837b64f901e8b44929f63ef677121a1b2a6c499d284eefaf252", "wall_s": 14747.9}
+{"arm": "ctl", "window": "queries", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 2, "ticks_per_epoch": [600000, 600000], "n": 4000, "fused_invocab_pct": 2.156, "fused_all_pct": 0.8, "snn_invocab_pct": 2.156, "cal": {"scale": 0.028181870546416927, "sigma_fast": 0.027239631921833294, "sigma_slow": 0.9665657883485158}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.09603666666666667, 0.08653666666666666], "ticks_per_sec": [83.25117062374575, 83.89241676855215], "eval_s": 43.0, "peak_rss_mb": 1192.8, "ckpt_sha256": "49e0910f3ca4c837b64f901e8b44929f63ef677121a1b2a6c499d284eefaf252", "wall_s": 14790.8}
diff --git a/results/hashing/m8_v1b/runs/rss_cm.tsv b/results/hashing/m8_v1b/runs/rss_cm.tsv
new file mode 100644
index 0000000000000000000000000000000000000000..1b785c2d0d3616f79648c7602c6126cab11182f6
--- /dev/null
+++ b/results/hashing/m8_v1b/runs/rss_cm.tsv
@@ -0,0 +1,2785 @@
+1792876905 0.0 33392 load 0
+1792876915 10.0 712572 build 0
+1792876925 20.1 820244 build 0
+1792876935 30.1 338456 prepare 0
+1792876945 40.1 951712 snn_ep1 0
+1792876955 50.1 951716 snn_ep1 0
+1792876965 60.1 951716 snn_ep1 0
+1792876975 70.1 951716 snn_ep1 0
+1792876985 80.1 951716 snn_ep1 0
+1792876995 90.1 951716 snn_ep1 0
+1792877005 100.1 951716 snn_ep1 0
+1792877015 110.1 951716 snn_ep1 0
+1792877025 120.1 951716 snn_ep1 0
+1792877035 130.1 951716 snn_ep1 0
+1792877045 140.1 951716 snn_ep1 0
+1792877055 150.1 951716 snn_ep1 0
+1792877065 160.1 951716 snn_ep1 0
+1792877075 170.1 951716 snn_ep1 0
+1792877085 180.1 951716 snn_ep1 0
+1792877095 190.1 951716 snn_ep1 0
+1792877105 200.1 951716 snn_ep1 0
+1792877115 210.1 951716 snn_ep1 0
+1792877125 220.1 951716 snn_ep1 0
+1792877135 230.1 951716 snn_ep1 0
+1792877145 240.1 951716 snn_ep1 0
+1792877155 250.1 951716 snn_ep1 0
+1792877165 260.1 951716 snn_ep1 0
+1792877175 270.1 951716 snn_ep1 0
+1792877185 280.1 951716 snn_ep1 0
+1792877195 290.1 951716 snn_ep1 0
+1792877284 379.1 951716 snn_ep1 0
+1792877294 389.2 951716 snn_ep1 0
+1792877304 399.2 951716 snn_ep1 0
+1792877369 409.2 951716 snn_ep1 0
+1792877379 419.2 951652 snn_ep1 0
+1792878719 0.0 33348 load 0
+1792878729 10.0 668536 build 0
+1792878739 20.0 667288 build 0
+1792878749 30.0 298192 build 0
+1792878759 40.1 951792 snn_ep1 0
+1792878769 50.1 951796 snn_ep1 0
+1792878779 60.1 951796 snn_ep1 0
+1792878789 70.1 951796 snn_ep1 0
+1792878799 80.1 951796 snn_ep1 0
+1792878809 90.1 951796 snn_ep1 0
+1792878819 100.1 951796 snn_ep1 0
+1792878829 110.1 951796 snn_ep1 0
+1792878839 120.1 951796 snn_ep1 0
+1792878849 130.1 951796 snn_ep1 0
+1792878859 140.1 951796 snn_ep1 0
+1792878869 150.1 951796 snn_ep1 0
+1792878879 160.1 951796 snn_ep1 0
+1792878889 170.1 951796 snn_ep1 0
+1792878899 180.1 951796 snn_ep1 0
+1792878909 190.1 951796 snn_ep1 0
+1792878919 200.1 951796 snn_ep1 0
+1792878929 210.1 951796 snn_ep1 0
+1792878939 220.1 951796 snn_ep1 0
+1792878949 230.1 951796 snn_ep1 0
+1792878959 240.1 951796 snn_ep1 0
+1792878969 250.1 951796 snn_ep1 0
+1792878979 260.1 951796 snn_ep1 0
+1792878989 270.1 951796 snn_ep1 0
+1792878999 280.1 951796 snn_ep1 0
+1792879009 290.1 951796 snn_ep1 0
+1792879019 300.1 951796 snn_ep1 0
+1792879029 310.1 951796 snn_ep1 0
+1792879039 320.1 951796 snn_ep1 0
+1792879049 330.1 951796 snn_ep1 0
+1792879059 340.1 951796 snn_ep1 0
+1792879069 350.1 951796 snn_ep1 0
+1792879079 360.1 951796 snn_ep1 0
+1792879089 370.1 951796 snn_ep1 0
+1792879099 380.1 951796 snn_ep1 0
+1792879109 390.1 951796 snn_ep1 0
+1792879119 400.1 951796 snn_ep1 10000
+1792879129 410.1 951796 snn_ep1 10000
+1792879139 420.1 951796 snn_ep1 10000
+1792879149 430.1 951796 snn_ep1 10000
+1792879159 440.1 951796 snn_ep1 10000
+1792879169 450.1 951796 snn_ep1 10000
+1792879179 460.1 951796 snn_ep1 10000
+1792879189 470.1 951796 snn_ep1 10000
+1792879199 480.1 951796 snn_ep1 10000
+1792879209 490.1 951796 snn_ep1 10000
+1792879219 500.1 951796 snn_ep1 10000
+1792879229 510.1 951796 snn_ep1 10000
+1792879239 520.1 951796 snn_ep1 10000
+1792879249 530.1 951796 snn_ep1 10000
+1792879259 540.1 951796 snn_ep1 10000
+1792879269 550.1 951796 snn_ep1 10000
+1792879279 560.1 951796 snn_ep1 10000
+1792879289 570.1 951796 snn_ep1 10000
+1792879299 580.1 951796 snn_ep1 10000
+1792879309 590.1 951796 snn_ep1 10000
+1792879319 600.1 951796 snn_ep1 10000
+1792879329 610.1 951796 snn_ep1 10000
+1792879339 620.1 951796 snn_ep1 10000
+1792879349 630.1 951796 snn_ep1 10000
+1792879359 640.1 951792 snn_ep1 10000
+1792879369 650.1 951792 snn_ep1 10000
+1792879379 660.1 951792 snn_ep1 10000
+1792879389 670.1 951792 snn_ep1 10000
+1792879399 680.1 951792 snn_ep1 10000
+1792879409 690.1 951792 snn_ep1 10000
+1792879419 700.1 951792 snn_ep1 10000
+1792879429 710.1 951792 snn_ep1 10000
+1792879439 720.1 951792 snn_ep1 10000
+1792879449 730.1 951792 snn_ep1 10000
+1792879459 740.1 951792 snn_ep1 10000
+1792879469 750.1 951792 snn_ep1 10000
+1792879479 760.1 951792 snn_ep1 10000
+1792879489 770.1 951792 snn_ep1 10000
+1792879499 780.1 951792 snn_ep1 20000
+1792879509 790.1 951792 snn_ep1 20000
+1792879519 800.1 951792 snn_ep1 20000
+1792879529 810.1 951792 snn_ep1 20000
+1792879539 820.1 951792 snn_ep1 20000
+1792879549 830.1 951792 snn_ep1 20000
+1792879559 840.1 951792 snn_ep1 20000
+1792879569 850.1 951792 snn_ep1 20000
+1792879579 860.1 951792 snn_ep1 20000
+1792879589 870.1 951792 snn_ep1 20000
+1792879599 880.1 951792 snn_ep1 20000
+1792879609 890.1 951792 snn_ep1 20000
+1792879619 900.1 951792 snn_ep1 20000
+1792879629 910.1 951792 snn_ep1 20000
+1792879639 920.1 951792 snn_ep1 20000
+1792879649 930.1 951792 snn_ep1 20000
+1792879659 940.1 951792 snn_ep1 20000
+1792879669 950.1 951792 snn_ep1 20000
+1792879679 960.1 951792 snn_ep1 20000
+1792879689 970.1 951792 snn_ep1 20000
+1792879699 980.1 951792 snn_ep1 20000
+1792879709 990.1 951792 snn_ep1 20000
+1792879719 1000.1 951796 snn_ep1 20000
+1792879729 1010.1 951796 snn_ep1 20000
+1792879739 1020.1 951796 snn_ep1 20000
+1792879749 1030.1 951796 snn_ep1 20000
+1792879759 1040.1 951796 snn_ep1 20000
+1792879769 1050.1 951796 snn_ep1 20000
+1792879779 1060.1 951796 snn_ep1 20000
+1792879789 1070.1 951796 snn_ep1 20000
+1792879799 1080.1 951796 snn_ep1 20000
+1792879809 1090.1 951800 snn_ep1 20000
+1792879819 1100.1 951800 snn_ep1 20000
+1792879829 1110.1 951800 snn_ep1 20000
+1792879839 1120.1 951800 snn_ep1 20000
+1792879849 1130.1 951800 snn_ep1 20000
+1792879859 1140.1 951800 snn_ep1 20000
+1792879869 1150.1 951800 snn_ep1 30000
+1792879879 1160.1 951800 snn_ep1 30000
+1792879889 1170.1 951804 snn_ep1 30000
+1792879899 1180.1 951812 snn_ep1 30000
+1792879909 1190.1 951812 snn_ep1 30000
+1792879919 1200.1 951812 snn_ep1 30000
+1792879929 1210.1 951812 snn_ep1 30000
+1792879939 1220.1 951816 snn_ep1 30000
+1792879949 1230.1 951816 snn_ep1 30000
+1792879959 1240.1 951816 snn_ep1 30000
+1792879969 1250.1 951816 snn_ep1 30000
+1792879979 1260.1 951816 snn_ep1 30000
+1792879989 1270.1 951816 snn_ep1 30000
+1792879999 1280.1 951816 snn_ep1 30000
+1792880009 1290.1 951816 snn_ep1 30000
+1792880019 1300.1 951816 snn_ep1 30000
+1792880029 1310.1 951816 snn_ep1 30000
+1792880039 1320.1 951816 snn_ep1 30000
+1792880049 1330.1 951816 snn_ep1 30000
+1792880059 1340.1 951816 snn_ep1 30000
+1792880069 1350.1 951816 snn_ep1 30000
+1792880079 1360.1 951816 snn_ep1 30000
+1792880089 1370.1 951816 snn_ep1 30000
+1792880099 1380.1 951816 snn_ep1 30000
+1792880109 1390.1 951816 snn_ep1 30000
+1792880119 1400.1 951816 snn_ep1 30000
+1792880129 1410.1 951816 snn_ep1 30000
+1792880139 1420.1 951816 snn_ep1 30000
+1792880149 1430.1 951816 snn_ep1 30000
+1792880159 1440.1 951816 snn_ep1 30000
+1792880169 1450.1 951816 snn_ep1 30000
+1792880179 1460.1 951816 snn_ep1 30000
+1792880189 1470.1 951816 snn_ep1 30000
+1792880199 1480.1 951816 snn_ep1 40000
+1792880209 1490.1 951816 snn_ep1 40000
+1792880219 1500.1 951816 snn_ep1 40000
+1792880229 1510.2 951816 snn_ep1 40000
+1792880239 1520.2 951816 snn_ep1 40000
+1792880249 1530.2 951816 snn_ep1 40000
+1792880259 1540.2 951816 snn_ep1 40000
+1792880269 1550.2 951816 snn_ep1 40000
+1792880279 1560.2 951816 snn_ep1 40000
+1792880289 1570.2 951816 snn_ep1 40000
+1792880299 1580.2 951816 snn_ep1 40000
+1792880309 1590.2 951816 snn_ep1 40000
+1792880319 1600.2 951816 snn_ep1 40000
+1792880329 1610.2 951816 snn_ep1 40000
+1792880339 1620.2 951816 snn_ep1 40000
+1792880349 1630.2 951816 snn_ep1 40000
+1792880359 1640.2 951816 snn_ep1 40000
+1792880369 1650.2 951816 snn_ep1 40000
+1792880379 1660.2 951816 snn_ep1 40000
+1792880389 1670.2 951816 snn_ep1 40000
+1792880399 1680.2 951816 snn_ep1 40000
+1792880409 1690.2 951816 snn_ep1 40000
+1792880419 1700.2 951816 snn_ep1 40000
+1792880429 1710.2 951816 snn_ep1 40000
+1792880439 1720.2 951816 snn_ep1 40000
+1792880449 1730.2 951816 snn_ep1 40000
+1792880459 1740.2 951816 snn_ep1 40000
+1792880469 1750.2 951816 snn_ep1 40000
+1792880479 1760.2 951816 snn_ep1 40000
+1792880489 1770.2 951816 snn_ep1 40000
+1792880499 1780.2 951816 snn_ep1 40000
+1792880509 1790.2 951816 snn_ep1 40000
+1792880519 1800.2 951816 snn_ep1 40000
+1792880529 1810.2 951816 snn_ep1 40000
+1792880539 1820.2 951816 snn_ep1 50000
+1792880549 1830.2 951816 snn_ep1 50000
+1792880559 1840.2 951816 snn_ep1 50000
+1792880569 1850.2 951816 snn_ep1 50000
+1792880579 1860.2 951816 snn_ep1 50000
+1792880589 1870.2 951816 snn_ep1 50000
+1792880599 1880.2 951816 snn_ep1 50000
+1792880609 1890.2 951816 snn_ep1 50000
+1792880619 1900.2 951816 snn_ep1 50000
+1792880629 1910.2 951816 snn_ep1 50000
+1792880639 1920.2 951816 snn_ep1 50000
+1792880649 1930.2 951816 snn_ep1 50000
+1792880659 1940.2 951816 snn_ep1 50000
+1792880669 1950.2 951816 snn_ep1 50000
+1792880679 1960.2 951816 snn_ep1 50000
+1792880689 1970.2 951816 snn_ep1 50000
+1792880699 1980.2 951816 snn_ep1 50000
+1792880709 1990.2 951816 snn_ep1 50000
+1792880719 2000.2 951816 snn_ep1 50000
+1792880729 2010.2 951816 snn_ep1 50000
+1792880739 2020.2 951816 snn_ep1 50000
+1792880749 2030.2 951816 snn_ep1 50000
+1792880759 2040.2 951816 snn_ep1 50000
+1792880769 2050.2 951816 snn_ep1 50000
+1792880779 2060.2 951816 snn_ep1 50000
+1792880789 2070.2 951816 snn_ep1 50000
+1792880799 2080.2 951816 snn_ep1 50000
+1792880809 2090.2 951816 snn_ep1 50000
+1792880819 2100.2 951816 snn_ep1 50000
+1792880829 2110.2 951816 snn_ep1 50000
+1792880839 2120.2 951816 snn_ep1 50000
+1792880849 2130.2 951816 snn_ep1 50000
+1792880859 2140.2 951816 snn_ep1 50000
+1792880869 2150.2 951816 snn_ep1 60000
+1792880879 2160.2 951816 snn_ep1 60000
+1792880889 2170.2 951816 snn_ep1 60000
+1792880899 2180.2 951816 snn_ep1 60000
+1792880909 2190.2 951816 snn_ep1 60000
+1792880919 2200.2 951816 snn_ep1 60000
+1792880929 2210.2 951816 snn_ep1 60000
+1792880939 2220.2 951816 snn_ep1 60000
+1792880949 2230.2 951816 snn_ep1 60000
+1792880959 2240.2 951816 snn_ep1 60000
+1792880969 2250.2 951816 snn_ep1 60000
+1792880979 2260.2 951816 snn_ep1 60000
+1792880989 2270.2 951816 snn_ep1 60000
+1792880999 2280.2 951816 snn_ep1 60000
+1792881009 2290.2 951816 snn_ep1 60000
+1792881019 2300.2 951816 snn_ep1 60000
+1792881029 2310.2 951816 snn_ep1 60000
+1792881039 2320.2 951816 snn_ep1 60000
+1792881049 2330.2 951816 snn_ep1 60000
+1792881059 2340.2 951816 snn_ep1 60000
+1792881069 2350.2 951816 snn_ep1 60000
+1792881079 2360.2 951816 snn_ep1 60000
+1792881089 2370.2 951816 snn_ep1 60000
+1792881099 2380.2 951816 snn_ep1 60000
+1792881109 2390.2 951816 snn_ep1 60000
+1792881119 2400.2 951816 snn_ep1 60000
+1792881129 2410.2 951816 snn_ep1 60000
+1792881139 2420.2 951816 snn_ep1 60000
+1792881149 2430.2 951816 snn_ep1 60000
+1792881159 2440.2 951816 snn_ep1 60000
+1792881169 2450.2 951816 snn_ep1 60000
+1792881179 2460.2 951816 snn_ep1 60000
+1792881189 2470.2 951816 snn_ep1 60000
+1792881199 2480.2 951816 snn_ep1 70000
+1792881209 2490.2 951816 snn_ep1 70000
+1792881219 2500.2 951816 snn_ep1 70000
+1792881229 2510.2 951816 snn_ep1 70000
+1792881239 2520.2 951816 snn_ep1 70000
+1792881249 2530.2 951816 snn_ep1 70000
+1792881259 2540.2 951816 snn_ep1 70000
+1792881269 2550.2 951816 snn_ep1 70000
+1792881279 2560.2 951816 snn_ep1 70000
+1792881289 2570.2 951816 snn_ep1 70000
+1792881299 2580.2 951816 snn_ep1 70000
+1792881309 2590.2 951816 snn_ep1 70000
+1792881319 2600.2 951816 snn_ep1 70000
+1792881329 2610.2 951816 snn_ep1 70000
+1792881339 2620.2 951816 snn_ep1 70000
+1792881349 2630.2 951816 snn_ep1 70000
+1792881359 2640.2 951816 snn_ep1 70000
+1792881369 2650.2 951816 snn_ep1 70000
+1792881380 2661.2 951816 snn_ep1 70000
+1792881390 2671.2 951816 snn_ep1 70000
+1792881400 2681.2 951816 snn_ep1 70000
+1792881410 2691.2 951816 snn_ep1 70000
+1792881420 2701.2 951808 snn_ep1 70000
+1792881430 2711.2 950924 snn_ep1 70000
+1792881440 2721.2 947876 snn_ep1 70000
+1792881450 2731.2 947876 snn_ep1 70000
+1792881460 2741.2 947876 snn_ep1 70000
+1792881470 2751.2 947876 snn_ep1 70000
+1792881480 2761.2 947876 snn_ep1 70000
+1792881490 2771.2 947876 snn_ep1 70000
+1792881500 2781.2 947876 snn_ep1 70000
+1792881510 2791.2 947876 snn_ep1 70000
+1792881520 2801.2 947876 snn_ep1 70000
+1792881530 2811.2 947876 snn_ep1 70000
+1792881540 2821.2 947876 snn_ep1 80000
+1792881550 2831.2 947876 snn_ep1 80000
+1792881560 2841.2 947876 snn_ep1 80000
+1792881570 2851.2 947876 snn_ep1 80000
+1792881580 2861.2 947876 snn_ep1 80000
+1792881590 2871.2 947876 snn_ep1 80000
+1792881600 2881.2 947876 snn_ep1 80000
+1792881610 2891.2 947876 snn_ep1 80000
+1792881620 2901.2 947876 snn_ep1 80000
+1792881630 2911.2 947876 snn_ep1 80000
+1792881640 2921.2 947876 snn_ep1 80000
+1792881650 2931.2 947876 snn_ep1 80000
+1792881660 2941.2 947876 snn_ep1 80000
+1792881670 2951.2 947876 snn_ep1 80000
+1792881680 2961.2 947876 snn_ep1 80000
+1792881690 2971.2 947876 snn_ep1 80000
+1792881700 2981.2 947876 snn_ep1 80000
+1792881710 2991.2 947876 snn_ep1 80000
+1792881720 3001.2 947876 snn_ep1 80000
+1792881730 3011.2 947876 snn_ep1 80000
+1792881740 3021.2 947876 snn_ep1 80000
+1792881750 3031.2 947876 snn_ep1 80000
+1792881760 3041.2 947876 snn_ep1 80000
+1792881770 3051.2 947876 snn_ep1 80000
+1792881780 3061.2 947876 snn_ep1 80000
+1792881790 3071.2 947876 snn_ep1 80000
+1792881800 3081.2 947876 snn_ep1 80000
+1792881810 3091.2 947876 snn_ep1 80000
+1792881820 3101.2 947876 snn_ep1 80000
+1792881830 3111.2 947876 snn_ep1 80000
+1792881840 3121.2 947876 snn_ep1 80000
+1792881850 3131.2 947876 snn_ep1 80000
+1792881860 3141.2 947876 snn_ep1 80000
+1792881870 3151.2 947876 snn_ep1 80000
+1792881880 3161.2 947876 snn_ep1 90000
+1792881890 3171.2 947876 snn_ep1 90000
+1792881900 3181.2 947876 snn_ep1 90000
+1792881910 3191.2 947876 snn_ep1 90000
+1792881920 3201.2 947876 snn_ep1 90000
+1792881930 3211.2 947876 snn_ep1 90000
+1792881940 3221.2 947876 snn_ep1 90000
+1792881950 3231.2 947876 snn_ep1 90000
+1792881960 3241.2 947876 snn_ep1 90000
+1792881970 3251.2 947876 snn_ep1 90000
+1792881980 3261.2 947876 snn_ep1 90000
+1792881990 3271.2 947876 snn_ep1 90000
+1792882000 3281.2 947876 snn_ep1 90000
+1792882010 3291.2 947876 snn_ep1 90000
+1792882020 3301.2 947876 snn_ep1 90000
+1792882030 3311.2 947876 snn_ep1 90000
+1792882040 3321.2 947876 snn_ep1 90000
+1792882050 3331.2 947876 snn_ep1 90000
+1792882060 3341.2 947876 snn_ep1 90000
+1792882070 3351.2 947876 snn_ep1 90000
+1792882080 3361.2 947876 snn_ep1 90000
+1792882090 3371.2 947876 snn_ep1 90000
+1792882100 3381.2 947876 snn_ep1 90000
+1792882110 3391.2 947876 snn_ep1 90000
+1792882120 3401.2 947876 snn_ep1 90000
+1792882130 3411.2 947876 snn_ep1 90000
+1792882140 3421.2 947876 snn_ep1 90000
+1792882150 3431.2 947876 snn_ep1 90000
+1792882160 3441.2 947876 snn_ep1 90000
+1792882170 3451.2 947876 snn_ep1 90000
+1792882180 3461.2 947876 snn_ep1 90000
+1792882190 3471.2 947876 snn_ep1 90000
+1792882200 3481.2 947876 snn_ep1 90000
+1792882210 3491.2 947876 snn_ep1 100000
+1792882220 3501.2 947876 snn_ep1 100000
+1792882230 3511.2 947876 snn_ep1 100000
+1792882240 3521.2 947876 snn_ep1 100000
+1792882250 3531.2 947876 snn_ep1 100000
+1792882260 3541.2 947876 snn_ep1 100000
+1792882270 3551.2 947876 snn_ep1 100000
+1792882280 3561.2 947876 snn_ep1 100000
+1792882290 3571.2 947876 snn_ep1 100000
+1792882300 3581.2 947876 snn_ep1 100000
+1792882310 3591.2 947876 snn_ep1 100000
+1792882320 3601.2 947876 snn_ep1 100000
+1792882330 3611.2 947876 snn_ep1 100000
+1792882340 3621.2 947876 snn_ep1 100000
+1792882350 3631.2 947876 snn_ep1 100000
+1792882360 3641.2 947876 snn_ep1 100000
+1792882370 3651.2 947876 snn_ep1 100000
+1792882380 3661.2 947876 snn_ep1 100000
+1792882390 3671.2 947876 snn_ep1 100000
+1792882400 3681.2 947876 snn_ep1 100000
+1792882410 3691.2 947876 snn_ep1 100000
+1792882420 3701.2 947876 snn_ep1 100000
+1792882430 3711.2 947876 snn_ep1 100000
+1792882440 3721.2 947876 snn_ep1 100000
+1792882450 3731.2 947876 snn_ep1 100000
+1792882460 3741.2 947876 snn_ep1 100000
+1792882470 3751.2 947876 snn_ep1 100000
+1792882480 3761.2 947876 snn_ep1 100000
+1792882490 3771.2 947876 snn_ep1 100000
+1792882500 3781.2 947876 snn_ep1 100000
+1792882510 3791.2 947876 snn_ep1 100000
+1792882520 3801.2 947876 snn_ep1 100000
+1792882530 3811.2 947876 snn_ep1 100000
+1792882540 3821.2 947876 snn_ep1 100000
+1792882550 3831.2 947876 snn_ep1 110000
+1792882560 3841.2 947876 snn_ep1 110000
+1792882570 3851.2 947876 snn_ep1 110000
+1792882580 3861.2 947876 snn_ep1 110000
+1792882590 3871.2 947876 snn_ep1 110000
+1792882600 3881.2 947876 snn_ep1 110000
+1792882610 3891.2 947876 snn_ep1 110000
+1792882620 3901.2 947876 snn_ep1 110000
+1792882630 3911.2 947876 snn_ep1 110000
+1792882640 3921.2 947876 snn_ep1 110000
+1792882650 3931.2 947876 snn_ep1 110000
+1792882660 3941.2 947876 snn_ep1 110000
+1792882670 3951.2 947876 snn_ep1 110000
+1792882680 3961.2 947876 snn_ep1 110000
+1792882690 3971.2 947876 snn_ep1 110000
+1792882700 3981.2 947876 snn_ep1 110000
+1792882710 3991.2 947876 snn_ep1 110000
+1792882720 4001.2 947876 snn_ep1 110000
+1792882730 4011.2 947876 snn_ep1 110000
+1792882740 4021.2 947876 snn_ep1 110000
+1792882750 4031.2 947876 snn_ep1 110000
+1792882760 4041.2 947876 snn_ep1 110000
+1792882770 4051.2 947876 snn_ep1 110000
+1792882780 4061.2 947876 snn_ep1 110000
+1792882790 4071.2 947876 snn_ep1 110000
+1792882800 4081.2 947876 snn_ep1 110000
+1792882810 4091.2 947876 snn_ep1 110000
+1792882820 4101.2 947876 snn_ep1 110000
+1792882830 4111.2 947876 snn_ep1 110000
+1792882840 4121.2 947876 snn_ep1 110000
+1792882850 4131.2 947876 snn_ep1 110000
+1792882860 4141.2 947876 snn_ep1 110000
+1792882870 4151.2 947876 snn_ep1 120000
+1792882880 4161.2 947876 snn_ep1 120000
+1792882890 4171.2 947876 snn_ep1 120000
+1792882900 4181.2 947876 snn_ep1 120000
+1792882910 4191.2 947876 snn_ep1 120000
+1792882920 4201.2 947876 snn_ep1 120000
+1792882930 4211.2 947876 snn_ep1 120000
+1792882940 4221.2 947876 snn_ep1 120000
+1792882950 4231.2 947876 snn_ep1 120000
+1792882960 4241.2 947876 snn_ep1 120000
+1792882970 4251.2 947876 snn_ep1 120000
+1792882980 4261.2 947876 snn_ep1 120000
+1792882990 4271.2 947876 snn_ep1 120000
+1792883000 4281.2 947876 snn_ep1 120000
+1792883010 4291.2 947876 snn_ep1 120000
+1792883020 4301.2 947876 snn_ep1 120000
+1792883030 4311.2 947876 snn_ep1 120000
+1792883040 4321.2 947876 snn_ep1 120000
+1792883050 4331.2 947876 snn_ep1 120000
+1792883060 4341.2 947876 snn_ep1 120000
+1792883070 4351.2 947876 snn_ep1 120000
+1792883080 4361.2 947876 snn_ep1 120000
+1792883090 4371.2 947876 snn_ep1 120000
+1792883100 4381.2 947876 snn_ep1 120000
+1792883110 4391.2 947876 snn_ep1 120000
+1792883120 4401.2 947876 snn_ep1 120000
+1792883130 4411.2 947876 snn_ep1 120000
+1792883140 4421.2 947876 snn_ep1 120000
+1792883150 4431.2 947876 snn_ep1 120000
+1792883160 4441.2 947876 snn_ep1 120000
+1792883170 4451.2 947876 snn_ep1 120000
+1792883180 4461.2 947876 snn_ep1 120000
+1792883190 4471.2 947876 snn_ep1 130000
+1792883200 4481.2 947876 snn_ep1 130000
+1792883210 4491.2 947876 snn_ep1 130000
+1792883220 4501.2 947876 snn_ep1 130000
+1792883230 4511.2 947876 snn_ep1 130000
+1792883240 4521.2 947876 snn_ep1 130000
+1792883250 4531.2 947876 snn_ep1 130000
+1792883260 4541.2 947876 snn_ep1 130000
+1792883270 4551.2 947876 snn_ep1 130000
+1792883280 4561.2 947876 snn_ep1 130000
+1792883290 4571.2 947876 snn_ep1 130000
+1792883300 4581.2 947876 snn_ep1 130000
+1792883310 4591.2 947876 snn_ep1 130000
+1792883320 4601.2 947876 snn_ep1 130000
+1792883330 4611.3 947876 snn_ep1 130000
+1792883340 4621.3 947876 snn_ep1 130000
+1792883350 4631.3 947876 snn_ep1 130000
+1792883360 4641.3 947876 snn_ep1 130000
+1792883370 4651.3 947876 snn_ep1 130000
+1792883380 4661.3 947876 snn_ep1 130000
+1792883390 4671.3 947876 snn_ep1 130000
+1792883400 4681.3 947876 snn_ep1 130000
+1792883410 4691.3 947876 snn_ep1 130000
+1792883420 4701.3 947876 snn_ep1 130000
+1792883430 4711.3 947876 snn_ep1 130000
+1792883440 4721.3 947876 snn_ep1 130000
+1792883450 4731.3 947876 snn_ep1 130000
+1792883460 4741.3 947876 snn_ep1 130000
+1792883470 4751.3 947876 snn_ep1 130000
+1792883480 4761.3 947876 snn_ep1 130000
+1792883490 4771.3 947876 snn_ep1 130000
+1792883500 4781.3 947876 snn_ep1 130000
+1792883510 4791.3 947876 snn_ep1 140000
+1792883521 4801.3 947876 snn_ep1 140000
+1792883531 4811.3 947876 snn_ep1 140000
+1792883541 4821.3 947876 snn_ep1 140000
+1792883551 4831.3 947876 snn_ep1 140000
+1792883561 4841.3 947876 snn_ep1 140000
+1792883571 4851.3 947876 snn_ep1 140000
+1792883581 4861.3 947876 snn_ep1 140000
+1792883591 4871.3 947876 snn_ep1 140000
+1792883601 4881.3 947876 snn_ep1 140000
+1792883611 4891.3 947876 snn_ep1 140000
+1792883621 4901.3 947876 snn_ep1 140000
+1792883631 4911.3 947876 snn_ep1 140000
+1792883641 4921.3 947876 snn_ep1 140000
+1792883651 4931.3 947876 snn_ep1 140000
+1792883661 4941.3 947876 snn_ep1 140000
+1792883671 4951.3 947876 snn_ep1 140000
+1792883681 4961.3 947876 snn_ep1 140000
+1792883691 4971.3 947876 snn_ep1 140000
+1792883701 4981.3 947876 snn_ep1 140000
+1792883711 4991.3 947876 snn_ep1 140000
+1792883721 5001.3 947876 snn_ep1 140000
+1792883731 5011.3 947876 snn_ep1 140000
+1792883741 5021.3 947876 snn_ep1 140000
+1792883751 5031.3 947876 snn_ep1 140000
+1792883761 5041.3 947876 snn_ep1 140000
+1792883771 5051.3 947876 snn_ep1 140000
+1792883781 5061.3 947876 snn_ep1 140000
+1792883791 5071.3 947876 snn_ep1 140000
+1792883801 5081.3 947876 snn_ep1 140000
+1792883811 5091.3 947876 snn_ep1 140000
+1792883821 5101.3 947876 snn_ep1 140000
+1792883831 5111.3 947876 snn_ep1 140000
+1792883841 5121.3 947876 snn_ep1 140000
+1792883851 5131.3 947876 snn_ep1 150000
+1792883861 5141.3 947876 snn_ep1 150000
+1792883871 5151.3 947876 snn_ep1 150000
+1792883881 5161.3 947876 snn_ep1 150000
+1792883891 5171.3 946888 snn_ep1 150000
+1792883901 5181.3 946888 snn_ep1 150000
+1792883911 5191.3 946888 snn_ep1 150000
+1792883921 5201.3 946888 snn_ep1 150000
+1792883931 5211.3 946888 snn_ep1 150000
+1792883941 5221.3 946888 snn_ep1 150000
+1792883951 5231.3 946888 snn_ep1 150000
+1792883961 5241.3 946888 snn_ep1 150000
+1792883971 5251.3 946888 snn_ep1 150000
+1792883981 5261.3 946888 snn_ep1 150000
+1792883991 5271.3 946888 snn_ep1 150000
+1792884001 5281.3 946888 snn_ep1 150000
+1792884011 5291.3 946888 snn_ep1 150000
+1792884021 5301.3 946888 snn_ep1 150000
+1792884031 5311.3 946888 snn_ep1 150000
+1792884041 5321.3 946888 snn_ep1 150000
+1792884051 5331.3 946888 snn_ep1 150000
+1792884061 5341.3 946888 snn_ep1 150000
+1792884071 5351.3 946888 snn_ep1 150000
+1792884081 5361.3 946888 snn_ep1 150000
+1792884091 5371.3 946888 snn_ep1 150000
+1792884101 5381.3 946888 snn_ep1 150000
+1792884111 5391.3 946888 snn_ep1 150000
+1792884121 5401.3 946888 snn_ep1 150000
+1792884131 5411.3 946888 snn_ep1 150000
+1792884141 5421.3 946888 snn_ep1 150000
+1792884151 5431.3 946888 snn_ep1 150000
+1792884161 5441.3 946888 snn_ep1 150000
+1792884171 5451.3 946888 snn_ep1 160000
+1792884181 5461.3 946888 snn_ep1 160000
+1792884191 5471.3 946888 snn_ep1 160000
+1792884201 5481.3 946888 snn_ep1 160000
+1792884211 5491.3 946888 snn_ep1 160000
+1792884221 5501.3 946888 snn_ep1 160000
+1792884231 5511.3 946888 snn_ep1 160000
+1792884241 5521.3 946888 snn_ep1 160000
+1792884251 5531.3 946888 snn_ep1 160000
+1792884261 5541.3 946888 snn_ep1 160000
+1792884271 5551.3 946888 snn_ep1 160000
+1792884281 5561.3 946888 snn_ep1 160000
+1792884291 5571.3 946888 snn_ep1 160000
+1792884301 5581.3 946888 snn_ep1 160000
+1792884311 5591.3 946888 snn_ep1 160000
+1792884321 5601.3 946888 snn_ep1 160000
+1792884331 5611.3 946888 snn_ep1 160000
+1792884341 5621.3 946888 snn_ep1 160000
+1792884351 5631.3 946888 snn_ep1 160000
+1792884361 5641.3 946888 snn_ep1 160000
+1792884371 5651.3 946888 snn_ep1 160000
+1792884381 5661.3 946888 snn_ep1 160000
+1792884391 5671.3 946888 snn_ep1 160000
+1792884401 5681.3 946888 snn_ep1 160000
+1792884411 5691.3 946888 snn_ep1 160000
+1792884421 5701.3 946888 snn_ep1 160000
+1792884431 5711.3 946888 snn_ep1 160000
+1792884441 5721.3 946888 snn_ep1 160000
+1792884451 5731.3 946888 snn_ep1 160000
+1792884461 5741.3 946888 snn_ep1 160000
+1792884471 5751.3 946888 snn_ep1 160000
+1792884481 5761.3 946888 snn_ep1 160000
+1792884491 5771.3 946888 snn_ep1 160000
+1792884501 5781.3 946888 snn_ep1 160000
+1792884511 5791.3 946888 snn_ep1 170000
+1792884521 5801.3 946888 snn_ep1 170000
+1792884531 5811.3 946888 snn_ep1 170000
+1792884541 5821.3 946888 snn_ep1 170000
+1792884551 5831.3 946888 snn_ep1 170000
+1792884561 5841.3 946888 snn_ep1 170000
+1792884571 5851.3 946888 snn_ep1 170000
+1792884581 5861.3 946888 snn_ep1 170000
+1792884591 5871.3 946888 snn_ep1 170000
+1792884601 5881.3 946888 snn_ep1 170000
+1792884611 5891.3 946888 snn_ep1 170000
+1792884621 5901.3 946888 snn_ep1 170000
+1792884631 5911.3 946888 snn_ep1 170000
+1792884641 5921.3 946888 snn_ep1 170000
+1792884651 5931.3 946888 snn_ep1 170000
+1792884661 5941.3 946888 snn_ep1 170000
+1792884671 5951.3 946888 snn_ep1 170000
+1792884681 5961.3 946888 snn_ep1 170000
+1792884691 5971.3 946888 snn_ep1 170000
+1792884701 5981.4 946888 snn_ep1 170000
+1792884711 5991.4 946888 snn_ep1 170000
+1792884721 6001.4 946888 snn_ep1 170000
+1792884731 6011.4 946888 snn_ep1 170000
+1792884741 6021.4 946888 snn_ep1 170000
+1792884751 6031.4 946888 snn_ep1 170000
+1792884761 6041.4 946888 snn_ep1 170000
+1792884771 6051.4 946888 snn_ep1 170000
+1792884781 6061.4 946888 snn_ep1 170000
+1792884791 6071.4 946888 snn_ep1 170000
+1792884801 6081.4 946888 snn_ep1 170000
+1792884811 6091.4 946888 snn_ep1 170000
+1792884821 6101.4 946888 snn_ep1 170000
+1792884831 6111.4 946888 snn_ep1 170000
+1792884841 6121.4 946888 snn_ep1 180000
+1792884851 6131.4 946888 snn_ep1 180000
+1792884861 6141.4 946888 snn_ep1 180000
+1792884871 6151.4 946888 snn_ep1 180000
+1792884881 6161.4 946888 snn_ep1 180000
+1792884891 6171.4 946888 snn_ep1 180000
+1792884901 6181.4 946888 snn_ep1 180000
+1792884911 6191.4 946888 snn_ep1 180000
+1792884921 6201.4 946888 snn_ep1 180000
+1792884931 6211.4 946888 snn_ep1 180000
+1792884941 6221.4 946888 snn_ep1 180000
+1792884951 6231.4 946888 snn_ep1 180000
+1792884961 6241.4 946888 snn_ep1 180000
+1792884971 6251.4 946888 snn_ep1 180000
+1792884981 6261.4 946888 snn_ep1 180000
+1792884991 6271.4 946888 snn_ep1 180000
+1792885001 6281.4 946888 snn_ep1 180000
+1792885011 6291.4 946888 snn_ep1 180000
+1792885021 6301.4 946888 snn_ep1 180000
+1792885031 6311.4 946888 snn_ep1 180000
+1792885041 6321.4 946888 snn_ep1 180000
+1792885051 6331.4 946888 snn_ep1 180000
+1792885061 6341.4 946888 snn_ep1 180000
+1792885071 6351.4 946888 snn_ep1 180000
+1792885081 6361.4 946888 snn_ep1 180000
+1792885091 6371.4 946888 snn_ep1 180000
+1792885101 6381.4 946888 snn_ep1 180000
+1792885111 6391.4 946888 snn_ep1 180000
+1792885121 6401.4 946888 snn_ep1 180000
+1792885131 6411.4 946888 snn_ep1 180000
+1792885141 6421.4 946888 snn_ep1 180000
+1792885151 6431.4 946888 snn_ep1 180000
+1792885161 6441.4 946888 snn_ep1 180000
+1792885171 6451.4 946888 snn_ep1 180000
+1792885181 6461.4 946888 snn_ep1 190000
+1792885191 6471.4 946888 snn_ep1 190000
+1792885201 6481.4 946888 snn_ep1 190000
+1792885211 6491.4 946888 snn_ep1 190000
+1792885221 6501.4 946888 snn_ep1 190000
+1792885231 6511.4 946888 snn_ep1 190000
+1792885241 6521.4 946888 snn_ep1 190000
+1792885251 6531.4 946888 snn_ep1 190000
+1792885261 6541.4 946888 snn_ep1 190000
+1792885271 6551.4 946888 snn_ep1 190000
+1792885281 6561.4 946888 snn_ep1 190000
+1792885291 6571.4 946888 snn_ep1 190000
+1792885301 6581.4 946888 snn_ep1 190000
+1792885311 6591.4 946888 snn_ep1 190000
+1792885321 6601.4 946888 snn_ep1 190000
+1792885331 6611.4 946888 snn_ep1 190000
+1792885341 6621.4 946888 snn_ep1 190000
+1792885351 6631.4 946888 snn_ep1 190000
+1792885361 6641.4 946888 snn_ep1 190000
+1792885371 6651.4 946888 snn_ep1 190000
+1792885381 6661.4 946888 snn_ep1 190000
+1792885391 6671.4 946888 snn_ep1 190000
+1792885401 6681.4 946888 snn_ep1 190000
+1792885411 6691.4 946888 snn_ep1 190000
+1792885421 6701.4 946888 snn_ep1 190000
+1792885431 6711.4 946888 snn_ep1 190000
+1792885441 6721.4 946888 snn_ep1 190000
+1792885451 6731.4 946888 snn_ep1 190000
+1792885461 6741.4 946888 snn_ep1 190000
+1792885471 6751.4 946888 snn_ep1 190000
+1792885481 6761.4 946888 snn_ep1 190000
+1792885491 6771.4 946888 snn_ep1 190000
+1792885501 6781.4 946888 snn_ep1 190000
+1792885511 6791.4 946888 snn_ep1 190000
+1792885521 6801.4 946888 snn_ep1 200000
+1792885531 6811.4 946888 snn_ep1 200000
+1792885541 6821.4 946888 snn_ep1 200000
+1792885551 6831.4 946888 snn_ep1 200000
+1792885561 6841.4 946888 snn_ep1 200000
+1792885571 6851.4 946888 snn_ep1 200000
+1792885636 6917.1 946888 snn_ep1 200000
+1792885646 6927.1 946888 snn_ep1 200000
+1792885656 6937.1 946888 snn_ep1 200000
+1792885666 6947.1 946888 snn_ep1 200000
+1792885676 6957.1 946888 snn_ep1 200000
+1792885686 6967.1 946888 snn_ep1 200000
+1792885696 6977.1 946888 snn_ep1 200000
+1792885706 6987.1 946888 snn_ep1 200000
+1792885716 6997.1 946888 snn_ep1 200000
+1792885726 7007.1 946888 snn_ep1 200000
+1792885736 7017.1 946888 snn_ep1 200000
+1792885746 7027.1 946888 snn_ep1 200000
+1792885756 7037.1 946888 snn_ep1 200000
+1792885766 7047.1 946888 snn_ep1 200000
+1792885776 7057.1 946888 snn_ep1 200000
+1792885786 7067.1 946888 snn_ep1 200000
+1792885796 7077.1 946888 snn_ep1 200000
+1792885806 7087.1 946888 snn_ep1 200000
+1792885816 7097.1 946888 snn_ep1 200000
+1792885826 7107.1 946888 snn_ep1 200000
+1792885836 7117.1 946888 snn_ep1 200000
+1792885846 7127.1 946888 snn_ep1 200000
+1792885856 7137.1 946888 snn_ep1 200000
+1792885866 7147.1 946888 snn_ep1 200000
+1792885876 7157.1 946888 snn_ep1 200000
+1792885886 7167.1 946888 snn_ep1 200000
+1792885896 7177.1 946888 snn_ep1 200000
+1792885906 7187.1 946888 snn_ep1 210000
+1792885916 7197.1 946888 snn_ep1 210000
+1792885926 7207.1 946888 snn_ep1 210000
+1792885936 7217.1 946888 snn_ep1 210000
+1792885946 7227.1 946888 snn_ep1 210000
+1792885956 7237.1 946888 snn_ep1 210000
+1792885966 7247.1 946888 snn_ep1 210000
+1792885976 7257.1 946888 snn_ep1 210000
+1792885986 7267.1 946888 snn_ep1 210000
+1792885996 7277.1 946888 snn_ep1 210000
+1792886006 7287.1 946888 snn_ep1 210000
+1792886016 7297.1 946888 snn_ep1 210000
+1792886026 7307.1 946888 snn_ep1 210000
+1792886036 7317.1 946888 snn_ep1 210000
+1792886046 7327.1 946888 snn_ep1 210000
+1792886056 7337.1 946888 snn_ep1 210000
+1792886066 7347.1 946888 snn_ep1 210000
+1792886076 7357.1 946888 snn_ep1 210000
+1792886086 7367.1 946888 snn_ep1 210000
+1792886096 7377.1 946888 snn_ep1 210000
+1792886106 7387.1 946888 snn_ep1 210000
+1792886116 7397.1 946888 snn_ep1 210000
+1792886126 7407.1 946888 snn_ep1 210000
+1792886136 7417.1 946888 snn_ep1 210000
+1792886146 7427.1 946888 snn_ep1 210000
+1792886156 7437.1 946888 snn_ep1 210000
+1792886166 7447.1 946888 snn_ep1 210000
+1792886176 7457.1 946888 snn_ep1 210000
+1792886186 7467.1 946888 snn_ep1 210000
+1792886196 7477.1 946888 snn_ep1 210000
+1792886206 7487.1 946888 snn_ep1 210000
+1792886216 7497.1 946888 snn_ep1 220000
+1792886226 7507.1 946888 snn_ep1 220000
+1792886236 7517.1 946888 snn_ep1 220000
+1792886246 7527.1 946888 snn_ep1 220000
+1792886256 7537.1 946888 snn_ep1 220000
+1792886266 7547.1 946888 snn_ep1 220000
+1792886276 7557.1 946888 snn_ep1 220000
+1792886286 7567.1 946888 snn_ep1 220000
+1792886296 7577.1 946888 snn_ep1 220000
+1792886306 7587.1 946888 snn_ep1 220000
+1792886316 7597.1 946888 snn_ep1 220000
+1792886326 7607.1 946888 snn_ep1 220000
+1792886336 7617.1 946888 snn_ep1 220000
+1792886346 7627.1 946888 snn_ep1 220000
+1792886356 7637.1 946888 snn_ep1 220000
+1792886366 7647.1 946888 snn_ep1 220000
+1792886376 7657.1 946888 snn_ep1 220000
+1792886386 7667.1 946888 snn_ep1 220000
+1792886396 7677.1 946888 snn_ep1 220000
+1792886406 7687.1 946888 snn_ep1 220000
+1792886416 7697.1 946888 snn_ep1 220000
+1792886426 7707.1 946888 snn_ep1 220000
+1792886436 7717.1 946888 snn_ep1 220000
+1792886446 7727.1 946888 snn_ep1 220000
+1792886456 7737.1 946888 snn_ep1 220000
+1792886466 7747.1 946888 snn_ep1 220000
+1792886476 7757.1 946888 snn_ep1 220000
+1792886486 7767.1 946888 snn_ep1 220000
+1792886496 7777.1 946888 snn_ep1 220000
+1792886506 7787.1 946888 snn_ep1 220000
+1792886516 7797.1 946888 snn_ep1 220000
+1792886526 7807.1 946888 snn_ep1 220000
+1792886536 7817.1 946888 snn_ep1 230000
+1792886546 7827.1 946888 snn_ep1 230000
+1792886556 7837.1 946888 snn_ep1 230000
+1792886566 7847.1 946888 snn_ep1 230000
+1792886576 7857.1 946888 snn_ep1 230000
+1792886586 7867.1 946888 snn_ep1 230000
+1792886596 7877.1 946888 snn_ep1 230000
+1792886606 7887.1 946888 snn_ep1 230000
+1792886616 7897.1 946888 snn_ep1 230000
+1792886626 7907.1 946888 snn_ep1 230000
+1792886636 7917.1 946888 snn_ep1 230000
+1792886646 7927.1 946888 snn_ep1 230000
+1792886656 7937.1 946888 snn_ep1 230000
+1792886666 7947.1 946888 snn_ep1 230000
+1792886676 7957.1 946888 snn_ep1 230000
+1792886686 7967.1 946888 snn_ep1 230000
+1792886696 7977.1 946888 snn_ep1 230000
+1792886706 7987.1 946888 snn_ep1 230000
+1792886716 7997.1 946888 snn_ep1 230000
+1792886726 8007.1 946888 snn_ep1 230000
+1792886736 8017.1 946888 snn_ep1 230000
+1792886746 8027.1 946888 snn_ep1 230000
+1792886756 8037.1 946888 snn_ep1 230000
+1792886766 8047.1 946888 snn_ep1 230000
+1792886776 8057.1 946888 snn_ep1 230000
+1792886786 8067.1 946888 snn_ep1 230000
+1792886796 8077.1 946888 snn_ep1 230000
+1792886806 8087.1 946888 snn_ep1 230000
+1792886816 8097.1 946888 snn_ep1 230000
+1792886826 8107.1 946888 snn_ep1 230000
+1792886836 8117.1 946888 snn_ep1 230000
+1792886846 8127.1 946888 snn_ep1 230000
+1792886856 8137.1 946888 snn_ep1 240000
+1792886866 8147.1 946888 snn_ep1 240000
+1792886876 8157.1 946888 snn_ep1 240000
+1792886886 8167.1 946888 snn_ep1 240000
+1792886896 8177.1 946888 snn_ep1 240000
+1792886906 8187.1 946888 snn_ep1 240000
+1792886916 8197.1 946888 snn_ep1 240000
+1792886926 8207.1 946888 snn_ep1 240000
+1792886936 8217.1 946888 snn_ep1 240000
+1792886946 8227.1 946888 snn_ep1 240000
+1792886956 8237.1 946888 snn_ep1 240000
+1792886966 8247.1 946888 snn_ep1 240000
+1792886976 8257.1 946888 snn_ep1 240000
+1792886986 8267.1 946888 snn_ep1 240000
+1792886996 8277.1 946888 snn_ep1 240000
+1792887006 8287.1 946888 snn_ep1 240000
+1792887016 8297.1 946888 snn_ep1 240000
+1792887026 8307.1 946888 snn_ep1 240000
+1792887036 8317.1 946888 snn_ep1 240000
+1792887046 8327.1 946888 snn_ep1 240000
+1792887056 8337.1 946888 snn_ep1 240000
+1792887066 8347.1 946888 snn_ep1 240000
+1792887076 8357.1 946888 snn_ep1 240000
+1792887086 8367.1 946888 snn_ep1 240000
+1792887096 8377.1 946888 snn_ep1 240000
+1792887106 8387.1 946888 snn_ep1 240000
+1792887116 8397.1 946888 snn_ep1 240000
+1792887126 8407.1 946888 snn_ep1 240000
+1792887136 8417.1 946888 snn_ep1 240000
+1792887146 8427.1 946888 snn_ep1 240000
+1792887156 8437.1 946888 snn_ep1 240000
+1792887166 8447.1 946888 snn_ep1 240000
+1792887176 8457.1 946888 snn_ep1 250000
+1792887186 8467.1 946888 snn_ep1 250000
+1792887196 8477.1 946888 snn_ep1 250000
+1792887206 8487.1 946888 snn_ep1 250000
+1792887216 8497.1 946888 snn_ep1 250000
+1792887226 8507.1 946888 snn_ep1 250000
+1792887236 8517.1 946888 snn_ep1 250000
+1792887246 8527.1 946888 snn_ep1 250000
+1792887256 8537.1 946888 snn_ep1 250000
+1792887266 8547.1 946888 snn_ep1 250000
+1792887276 8557.1 946888 snn_ep1 250000
+1792887286 8567.1 946888 snn_ep1 250000
+1792887296 8577.1 946888 snn_ep1 250000
+1792887306 8587.1 946888 snn_ep1 250000
+1792887316 8597.1 946888 snn_ep1 250000
+1792887326 8607.2 946888 snn_ep1 250000
+1792887336 8617.2 946888 snn_ep1 250000
+1792887346 8627.2 946888 snn_ep1 250000
+1792887356 8637.2 946888 snn_ep1 250000
+1792887366 8647.2 946888 snn_ep1 250000
+1792887376 8657.2 946888 snn_ep1 250000
+1792887386 8667.2 946888 snn_ep1 250000
+1792887396 8677.2 946888 snn_ep1 250000
+1792887406 8687.2 946888 snn_ep1 250000
+1792887416 8697.2 946888 snn_ep1 250000
+1792887426 8707.2 946888 snn_ep1 250000
+1792887436 8717.2 946888 snn_ep1 250000
+1792887446 8727.2 946888 snn_ep1 250000
+1792887456 8737.2 946888 snn_ep1 250000
+1792887466 8747.2 946888 snn_ep1 250000
+1792887476 8757.2 946888 snn_ep1 250000
+1792887486 8767.2 946888 snn_ep1 250000
+1792887496 8777.2 946888 snn_ep1 250000
+1792887506 8787.2 946888 snn_ep1 260000
+1792887516 8797.2 946888 snn_ep1 260000
+1792887526 8807.2 946888 snn_ep1 260000
+1792887536 8817.2 946888 snn_ep1 260000
+1792887546 8827.2 946888 snn_ep1 260000
+1792887556 8837.2 946888 snn_ep1 260000
+1792887566 8847.2 946888 snn_ep1 260000
+1792887576 8857.2 946888 snn_ep1 260000
+1792887586 8867.2 946888 snn_ep1 260000
+1792887596 8877.2 946888 snn_ep1 260000
+1792887606 8887.2 946888 snn_ep1 260000
+1792887616 8897.2 946888 snn_ep1 260000
+1792887626 8907.2 946888 snn_ep1 260000
+1792887636 8917.2 946888 snn_ep1 260000
+1792887646 8927.2 946888 snn_ep1 260000
+1792887656 8937.2 946888 snn_ep1 260000
+1792887666 8947.2 946888 snn_ep1 260000
+1792887676 8957.2 946888 snn_ep1 260000
+1792887686 8967.2 946888 snn_ep1 260000
+1792887696 8977.2 946888 snn_ep1 260000
+1792887706 8987.2 946888 snn_ep1 260000
+1792887716 8997.2 946888 snn_ep1 260000
+1792887726 9007.2 946888 snn_ep1 260000
+1792887736 9017.2 946888 snn_ep1 260000
+1792887746 9027.2 946888 snn_ep1 260000
+1792887756 9037.2 946888 snn_ep1 260000
+1792887766 9047.2 946888 snn_ep1 260000
+1792887776 9057.2 946888 snn_ep1 260000
+1792887786 9067.2 946880 snn_ep1 260000
+1792887796 9077.2 946880 snn_ep1 260000
+1792887806 9087.2 946880 snn_ep1 260000
+1792887816 9097.2 946880 snn_ep1 260000
+1792887826 9107.2 946880 snn_ep1 260000
+1792887836 9117.2 946880 snn_ep1 270000
+1792887846 9127.2 946880 snn_ep1 270000
+1792887856 9137.2 946880 snn_ep1 270000
+1792887866 9147.2 946880 snn_ep1 270000
+1792887876 9157.2 946880 snn_ep1 270000
+1792887886 9167.2 946880 snn_ep1 270000
+1792887896 9177.2 946880 snn_ep1 270000
+1792887906 9187.2 946880 snn_ep1 270000
+1792887916 9197.2 946880 snn_ep1 270000
+1792887926 9207.2 946880 snn_ep1 270000
+1792887936 9217.2 946880 snn_ep1 270000
+1792887946 9227.2 946880 snn_ep1 270000
+1792887956 9237.2 946880 snn_ep1 270000
+1792887966 9247.2 946840 snn_ep1 270000
+1792887976 9257.2 946840 snn_ep1 270000
+1792887986 9267.2 946840 snn_ep1 270000
+1792887996 9277.2 946840 snn_ep1 270000
+1792888006 9287.2 946840 snn_ep1 270000
+1792888016 9297.2 946840 snn_ep1 270000
+1792888026 9307.2 946840 snn_ep1 270000
+1792888036 9317.2 946840 snn_ep1 270000
+1792888046 9327.2 946840 snn_ep1 270000
+1792888056 9337.2 946840 snn_ep1 270000
+1792888066 9347.2 946840 snn_ep1 270000
+1792888076 9357.2 946840 snn_ep1 270000
+1792888086 9367.2 946840 snn_ep1 270000
+1792888096 9377.2 946840 snn_ep1 270000
+1792888106 9387.2 946840 snn_ep1 270000
+1792888116 9397.2 946840 snn_ep1 270000
+1792888126 9407.2 946840 snn_ep1 270000
+1792888136 9417.2 946840 snn_ep1 270000
+1792888146 9427.2 946840 snn_ep1 270000
+1792888156 9437.2 946840 snn_ep1 270000
+1792888166 9447.2 946840 snn_ep1 270000
+1792888176 9457.2 946840 snn_ep1 280000
+1792888186 9467.2 946840 snn_ep1 280000
+1792888196 9477.2 946840 snn_ep1 280000
+1792888206 9487.2 946840 snn_ep1 280000
+1792888216 9497.2 946840 snn_ep1 280000
+1792888226 9507.2 946840 snn_ep1 280000
+1792888236 9517.2 946840 snn_ep1 280000
+1792888246 9527.2 946840 snn_ep1 280000
+1792888256 9537.2 946840 snn_ep1 280000
+1792888266 9547.2 946840 snn_ep1 280000
+1792888276 9557.2 946840 snn_ep1 280000
+1792888286 9567.2 946840 snn_ep1 280000
+1792888296 9577.2 946840 snn_ep1 280000
+1792888306 9587.2 946840 snn_ep1 280000
+1792888316 9597.2 946840 snn_ep1 280000
+1792888326 9607.2 946840 snn_ep1 280000
+1792888336 9617.2 946840 snn_ep1 280000
+1792888346 9627.2 946840 snn_ep1 280000
+1792888356 9637.2 946840 snn_ep1 280000
+1792888366 9647.2 946840 snn_ep1 280000
+1792888376 9657.2 946840 snn_ep1 280000
+1792888386 9667.2 946840 snn_ep1 280000
+1792888396 9677.2 946840 snn_ep1 280000
+1792888406 9687.2 946840 snn_ep1 280000
+1792888416 9697.2 946840 snn_ep1 280000
+1792888426 9707.2 946840 snn_ep1 280000
+1792888436 9717.2 946840 snn_ep1 280000
+1792888446 9727.2 946840 snn_ep1 280000
+1792888456 9737.2 946840 snn_ep1 280000
+1792888466 9747.2 946840 snn_ep1 280000
+1792888476 9757.2 946840 snn_ep1 280000
+1792888486 9767.2 946840 snn_ep1 280000
+1792888496 9777.2 946840 snn_ep1 280000
+1792888506 9787.2 946840 snn_ep1 280000
+1792888516 9797.2 946840 snn_ep1 280000
+1792888526 9807.2 946840 snn_ep1 290000
+1792888536 9817.2 946840 snn_ep1 290000
+1792888546 9827.2 946840 snn_ep1 290000
+1792888556 9837.2 946840 snn_ep1 290000
+1792888566 9847.2 946840 snn_ep1 290000
+1792888576 9857.2 946840 snn_ep1 290000
+1792888586 9867.2 946840 snn_ep1 290000
+1792888596 9877.2 946840 snn_ep1 290000
+1792888606 9887.2 946840 snn_ep1 290000
+1792888616 9897.2 946840 snn_ep1 290000
+1792888626 9907.2 946840 snn_ep1 290000
+1792888636 9917.2 946840 snn_ep1 290000
+1792888646 9927.2 946840 snn_ep1 290000
+1792888656 9937.2 946840 snn_ep1 290000
+1792888666 9947.2 946840 snn_ep1 290000
+1792888676 9957.2 946840 snn_ep1 290000
+1792888686 9967.2 946840 snn_ep1 290000
+1792888696 9977.2 946840 snn_ep1 290000
+1792888706 9987.2 946840 snn_ep1 290000
+1792888716 9997.2 946840 snn_ep1 290000
+1792888726 10007.2 946840 snn_ep1 290000
+1792888736 10017.2 946840 snn_ep1 290000
+1792888746 10027.2 946840 snn_ep1 290000
+1792888756 10037.2 946840 snn_ep1 290000
+1792888766 10047.2 946840 snn_ep1 290000
+1792888776 10057.2 946840 snn_ep1 290000
+1792888786 10067.2 946840 snn_ep1 290000
+1792888796 10077.2 946840 snn_ep1 290000
+1792888806 10087.2 946840 snn_ep1 290000
+1792888816 10097.2 946840 snn_ep1 290000
+1792888826 10107.2 946840 snn_ep1 290000
+1792888836 10117.2 946840 snn_ep1 290000
+1792888846 10127.2 946840 snn_ep1 300000
+1792888856 10137.2 946840 snn_ep1 300000
+1792888866 10147.2 946840 snn_ep1 300000
+1792888876 10157.2 946840 snn_ep1 300000
+1792888886 10167.2 946840 snn_ep1 300000
+1792888896 10177.2 946840 snn_ep1 300000
+1792888906 10187.2 946840 snn_ep1 300000
+1792888916 10197.2 946840 snn_ep1 300000
+1792888926 10207.2 946840 snn_ep1 300000
+1792888936 10217.2 946840 snn_ep1 300000
+1792888946 10227.2 946840 snn_ep1 300000
+1792888956 10237.2 946840 snn_ep1 300000
+1792888966 10247.2 946840 snn_ep1 300000
+1792888976 10257.2 946840 snn_ep1 300000
+1792888986 10267.2 946840 snn_ep1 300000
+1792888996 10277.2 946840 snn_ep1 300000
+1792889006 10287.2 946840 snn_ep1 300000
+1792889016 10297.2 946840 snn_ep1 300000
+1792889026 10307.2 946840 snn_ep1 300000
+1792889036 10317.2 946840 snn_ep1 300000
+1792889046 10327.2 946840 snn_ep1 300000
+1792889056 10337.2 946840 snn_ep1 300000
+1792889066 10347.2 946840 snn_ep1 300000
+1792889076 10357.2 946840 snn_ep1 300000
+1792889086 10367.2 946840 snn_ep1 300000
+1792889096 10377.2 946840 snn_ep1 300000
+1792889106 10387.2 946840 snn_ep1 300000
+1792889116 10397.2 946840 snn_ep1 300000
+1792889126 10407.2 946840 snn_ep1 300000
+1792889136 10417.2 946840 snn_ep1 300000
+1792889146 10427.2 946840 snn_ep1 300000
+1792889156 10437.2 946840 snn_ep1 300000
+1792889166 10447.2 946840 snn_ep1 300000
+1792889176 10457.2 946840 snn_ep1 300000
+1792889186 10467.2 946840 snn_ep1 310000
+1792889196 10477.2 946840 snn_ep1 310000
+1792889206 10487.3 946840 snn_ep1 310000
+1792889216 10497.3 946840 snn_ep1 310000
+1792889226 10507.3 946840 snn_ep1 310000
+1792889236 10517.3 946840 snn_ep1 310000
+1792889246 10527.3 946840 snn_ep1 310000
+1792889256 10537.3 946840 snn_ep1 310000
+1792889266 10547.3 946840 snn_ep1 310000
+1792889276 10557.3 946840 snn_ep1 310000
+1792889286 10567.3 946840 snn_ep1 310000
+1792889296 10577.3 946840 snn_ep1 310000
+1792889306 10587.3 946840 snn_ep1 310000
+1792889316 10597.3 946840 snn_ep1 310000
+1792889326 10607.3 946840 snn_ep1 310000
+1792889336 10617.3 946840 snn_ep1 310000
+1792889346 10627.3 946840 snn_ep1 310000
+1792889356 10637.3 946840 snn_ep1 310000
+1792889366 10647.3 946840 snn_ep1 310000
+1792889376 10657.3 946840 snn_ep1 310000
+1792889386 10667.3 946840 snn_ep1 310000
+1792889396 10677.3 946840 snn_ep1 310000
+1792889406 10687.3 946840 snn_ep1 310000
+1792889416 10697.3 946840 snn_ep1 310000
+1792889426 10707.3 946840 snn_ep1 310000
+1792889436 10717.3 946840 snn_ep1 310000
+1792889446 10727.3 946840 snn_ep1 310000
+1792889456 10737.3 946840 snn_ep1 310000
+1792889466 10747.3 946840 snn_ep1 310000
+1792889476 10757.3 946840 snn_ep1 310000
+1792889486 10767.3 946840 snn_ep1 310000
+1792889496 10777.3 946840 snn_ep1 310000
+1792889506 10787.3 946840 snn_ep1 310000
+1792889516 10797.3 946840 snn_ep1 320000
+1792889527 10807.3 946840 snn_ep1 320000
+1792889537 10817.3 946840 snn_ep1 320000
+1792889547 10827.3 946840 snn_ep1 320000
+1792889557 10837.3 946840 snn_ep1 320000
+1792889567 10847.3 946840 snn_ep1 320000
+1792889577 10857.3 946840 snn_ep1 320000
+1792889587 10867.3 946840 snn_ep1 320000
+1792889597 10877.3 946840 snn_ep1 320000
+1792889607 10887.3 946840 snn_ep1 320000
+1792889617 10897.3 946840 snn_ep1 320000
+1792889627 10907.3 946840 snn_ep1 320000
+1792889637 10917.3 946840 snn_ep1 320000
+1792889647 10927.3 946840 snn_ep1 320000
+1792889657 10937.3 946840 snn_ep1 320000
+1792889667 10947.3 946840 snn_ep1 320000
+1792889677 10957.3 946840 snn_ep1 320000
+1792889687 10967.3 946840 snn_ep1 320000
+1792889697 10977.3 946840 snn_ep1 320000
+1792889707 10987.3 946840 snn_ep1 320000
+1792889717 10997.3 946840 snn_ep1 320000
+1792889727 11007.3 946840 snn_ep1 320000
+1792889737 11017.3 946840 snn_ep1 320000
+1792889747 11027.3 946840 snn_ep1 320000
+1792889757 11037.3 946840 snn_ep1 320000
+1792889767 11047.3 946840 snn_ep1 320000
+1792889777 11057.3 946840 snn_ep1 320000
+1792889787 11067.3 946840 snn_ep1 320000
+1792889797 11077.3 946840 snn_ep1 320000
+1792889807 11087.3 946840 snn_ep1 320000
+1792889817 11097.3 946840 snn_ep1 320000
+1792889827 11107.3 946840 snn_ep1 320000
+1792889837 11117.3 946840 snn_ep1 320000
+1792889847 11127.3 946840 snn_ep1 330000
+1792889857 11137.3 946840 snn_ep1 330000
+1792889867 11147.3 946840 snn_ep1 330000
+1792889877 11157.3 946840 snn_ep1 330000
+1792889887 11167.3 946840 snn_ep1 330000
+1792889897 11177.3 946840 snn_ep1 330000
+1792889907 11187.3 946840 snn_ep1 330000
+1792889917 11197.3 946840 snn_ep1 330000
+1792889927 11207.3 946840 snn_ep1 330000
+1792889937 11217.3 946840 snn_ep1 330000
+1792889947 11227.3 946840 snn_ep1 330000
+1792889957 11237.3 946840 snn_ep1 330000
+1792889967 11247.3 946840 snn_ep1 330000
+1792889977 11257.3 946840 snn_ep1 330000
+1792889987 11267.3 946840 snn_ep1 330000
+1792889997 11277.3 946840 snn_ep1 330000
+1792890007 11287.3 946840 snn_ep1 330000
+1792890017 11297.3 946840 snn_ep1 330000
+1792890027 11307.3 946840 snn_ep1 330000
+1792890037 11317.3 946840 snn_ep1 330000
+1792890047 11327.3 946840 snn_ep1 330000
+1792890057 11337.3 946840 snn_ep1 330000
+1792890067 11347.3 946840 snn_ep1 330000
+1792890077 11357.3 946840 snn_ep1 330000
+1792890087 11367.3 946840 snn_ep1 330000
+1792890097 11377.3 946840 snn_ep1 330000
+1792890107 11387.3 946840 snn_ep1 330000
+1792890117 11397.3 946840 snn_ep1 330000
+1792890127 11407.3 946840 snn_ep1 330000
+1792890137 11417.3 946840 snn_ep1 330000
+1792890147 11427.3 946840 snn_ep1 330000
+1792890157 11437.3 946840 snn_ep1 330000
+1792890167 11447.3 946840 snn_ep1 340000
+1792890177 11457.3 946840 snn_ep1 340000
+1792890187 11467.3 946840 snn_ep1 340000
+1792890197 11477.3 946840 snn_ep1 340000
+1792890207 11487.3 946840 snn_ep1 340000
+1792890217 11497.3 946840 snn_ep1 340000
+1792890227 11507.3 946840 snn_ep1 340000
+1792890238 11518.6 946840 snn_ep1 340000
+1792890248 11528.6 946840 snn_ep1 340000
+1792890258 11538.6 946840 snn_ep1 340000
+1792890303 11548.6 946840 snn_ep1 340000
+1792890313 11558.6 946840 snn_ep1 340000
+1792890412 0.0 33228 load 0
+1792890422 10.0 694384 build 0
+1792890432 20.0 689288 build 0
+1792890442 30.0 328712 prepare 0
+1792890452 40.0 951672 snn_ep1 0
+1792890462 50.0 951676 snn_ep1 0
+1792890472 60.0 951676 snn_ep1 0
+1792890482 70.0 951676 snn_ep1 0
+1792890492 80.0 951676 snn_ep1 0
+1792890502 90.0 951676 snn_ep1 0
+1792890512 100.0 951676 snn_ep1 0
+1792890522 110.0 951676 snn_ep1 0
+1792890532 120.0 951676 snn_ep1 0
+1792890542 130.0 951676 snn_ep1 0
+1792890552 140.1 951676 snn_ep1 0
+1792890562 150.1 951676 snn_ep1 0
+1792890572 160.1 951676 snn_ep1 0
+1792890582 170.1 951676 snn_ep1 0
+1792890592 180.1 951676 snn_ep1 0
+1792890602 190.1 951676 snn_ep1 0
+1792890612 200.1 951676 snn_ep1 0
+1792890622 210.1 951676 snn_ep1 0
+1792890632 220.1 951676 snn_ep1 0
+1792890642 230.1 951676 snn_ep1 0
+1792890652 240.1 951676 snn_ep1 0
+1792890662 250.1 951676 snn_ep1 0
+1792890672 260.1 951676 snn_ep1 0
+1792890682 270.1 951676 snn_ep1 0
+1792890692 280.1 951676 snn_ep1 0
+1792890702 290.1 951676 snn_ep1 0
+1792890712 300.1 951676 snn_ep1 0
+1792890722 310.1 951676 snn_ep1 0
+1792890732 320.1 951676 snn_ep1 0
+1792890742 330.1 951676 snn_ep1 0
+1792890752 340.1 951676 snn_ep1 0
+1792890762 350.1 951676 snn_ep1 0
+1792890772 360.1 951676 snn_ep1 0
+1792890782 370.1 951676 snn_ep1 0
+1792890792 380.1 951676 snn_ep1 0
+1792890802 390.1 951676 snn_ep1 0
+1792890812 400.1 951676 snn_ep1 0
+1792890822 410.1 951676 snn_ep1 0
+1792890832 420.1 951676 snn_ep1 0
+1792890842 430.1 951676 snn_ep1 0
+1792890852 440.1 951676 snn_ep1 10000
+1792890862 450.1 951676 snn_ep1 10000
+1792890872 460.1 951676 snn_ep1 10000
+1792890882 470.1 951676 snn_ep1 10000
+1792890892 480.1 951676 snn_ep1 10000
+1792890902 490.1 951676 snn_ep1 10000
+1792890912 500.1 951676 snn_ep1 10000
+1792890922 510.1 951676 snn_ep1 10000
+1792890932 520.1 951676 snn_ep1 10000
+1792890942 530.1 951676 snn_ep1 10000
+1792890952 540.1 951676 snn_ep1 10000
+1792890962 550.1 951676 snn_ep1 10000
+1792890972 560.1 951676 snn_ep1 10000
+1792890982 570.1 951676 snn_ep1 10000
+1792890992 580.1 951676 snn_ep1 10000
+1792891002 590.1 951676 snn_ep1 10000
+1792891012 600.1 951676 snn_ep1 10000
+1792891022 610.1 951676 snn_ep1 10000
+1792891032 620.1 951676 snn_ep1 10000
+1792891042 630.1 951676 snn_ep1 10000
+1792891052 640.1 951676 snn_ep1 10000
+1792891062 650.1 951676 snn_ep1 10000
+1792891072 660.1 951676 snn_ep1 10000
+1792891082 670.1 951676 snn_ep1 10000
+1792891092 680.1 951676 snn_ep1 10000
+1792891102 690.1 951676 snn_ep1 10000
+1792891112 700.1 951676 snn_ep1 10000
+1792891122 710.1 951676 snn_ep1 10000
+1792891132 720.1 951676 snn_ep1 10000
+1792891142 730.1 951676 snn_ep1 10000
+1792891152 740.1 951676 snn_ep1 10000
+1792891162 750.1 951676 snn_ep1 10000
+1792891172 760.1 951676 snn_ep1 10000
+1792891182 770.1 951676 snn_ep1 10000
+1792891192 780.1 951676 snn_ep1 10000
+1792891202 790.1 951676 snn_ep1 10000
+1792891212 800.1 951676 snn_ep1 10000
+1792891222 810.1 951676 snn_ep1 10000
+1792891232 820.1 951676 snn_ep1 10000
+1792891242 830.1 951676 snn_ep1 10000
+1792891252 840.1 951676 snn_ep1 20000
+1792891262 850.1 951676 snn_ep1 20000
+1792891272 860.1 951676 snn_ep1 20000
+1792891282 870.1 951676 snn_ep1 20000
+1792891292 880.1 951676 snn_ep1 20000
+1792891302 890.1 951676 snn_ep1 20000
+1792891312 900.1 951676 snn_ep1 20000
+1792891323 910.9 951676 snn_ep1 20000
+1792891333 920.9 951676 snn_ep1 20000
+1792891343 930.9 951676 snn_ep1 20000
+1792891353 940.9 951676 snn_ep1 20000
+1792891363 950.9 951676 snn_ep1 20000
+1792891373 960.9 951676 snn_ep1 20000
+1792891383 970.9 951676 snn_ep1 20000
+1792891393 980.9 951676 snn_ep1 20000
+1792891403 990.9 951676 snn_ep1 20000
+1792891413 1000.9 951676 snn_ep1 20000
+1792891423 1010.9 951676 snn_ep1 20000
+1792891433 1020.9 951676 snn_ep1 20000
+1792891443 1030.9 951676 snn_ep1 20000
+1792891453 1040.9 951676 snn_ep1 20000
+1792891463 1050.9 951676 snn_ep1 20000
+1792891473 1060.9 951676 snn_ep1 20000
+1792891483 1070.9 951680 snn_ep1 20000
+1792891493 1080.9 951680 snn_ep1 20000
+1792891503 1090.9 951680 snn_ep1 20000
+1792891513 1100.9 951680 snn_ep1 20000
+1792891523 1110.9 951680 snn_ep1 20000
+1792891533 1120.9 951680 snn_ep1 20000
+1792891543 1130.9 951680 snn_ep1 20000
+1792891553 1140.9 951680 snn_ep1 20000
+1792891563 1150.9 951680 snn_ep1 20000
+1792891573 1160.9 951684 snn_ep1 20000
+1792891583 1170.9 951684 snn_ep1 20000
+1792891593 1180.9 951684 snn_ep1 20000
+1792891603 1190.9 951684 snn_ep1 20000
+1792891613 1200.9 951684 snn_ep1 20000
+1792891623 1210.9 951684 snn_ep1 20000
+1792891633 1220.9 951684 snn_ep1 30000
+1792891643 1230.9 951684 snn_ep1 30000
+1792891653 1240.9 951684 snn_ep1 30000
+1792891663 1250.9 951688 snn_ep1 30000
+1792891673 1260.9 951692 snn_ep1 30000
+1792891683 1270.9 951692 snn_ep1 30000
+1792891693 1280.9 951692 snn_ep1 30000
+1792891703 1290.9 951692 snn_ep1 30000
+1792891713 1300.9 951696 snn_ep1 30000
+1792891723 1310.9 951696 snn_ep1 30000
+1792891733 1320.9 951696 snn_ep1 30000
+1792891743 1330.9 951696 snn_ep1 30000
+1792891753 1340.9 951696 snn_ep1 30000
+1792891763 1350.9 951696 snn_ep1 30000
+1792891773 1360.9 951696 snn_ep1 30000
+1792891783 1370.9 951696 snn_ep1 30000
+1792891793 1380.9 951696 snn_ep1 30000
+1792891803 1390.9 951696 snn_ep1 30000
+1792891813 1400.9 951696 snn_ep1 30000
+1792891823 1410.9 951696 snn_ep1 30000
+1792891833 1420.9 951696 snn_ep1 30000
+1792891843 1430.9 951696 snn_ep1 30000
+1792891853 1440.9 951696 snn_ep1 30000
+1792891863 1450.9 951696 snn_ep1 30000
+1792891873 1460.9 951696 snn_ep1 30000
+1792891883 1470.9 951696 snn_ep1 30000
+1792891893 1480.9 951696 snn_ep1 30000
+1792891903 1490.9 951696 snn_ep1 30000
+1792891913 1500.9 951696 snn_ep1 30000
+1792891923 1510.9 951696 snn_ep1 30000
+1792891933 1520.9 951696 snn_ep1 30000
+1792891943 1530.9 951696 snn_ep1 30000
+1792891953 1540.9 951696 snn_ep1 30000
+1792891963 1550.9 951696 snn_ep1 30000
+1792891973 1560.9 951696 snn_ep1 30000
+1792891983 1570.9 951696 snn_ep1 40000
+1792891993 1580.9 951696 snn_ep1 40000
+1792892003 1590.9 951696 snn_ep1 40000
+1792892013 1600.9 951696 snn_ep1 40000
+1792892023 1610.9 951696 snn_ep1 40000
+1792892033 1620.9 951696 snn_ep1 40000
+1792892043 1630.9 951696 snn_ep1 40000
+1792892053 1640.9 951696 snn_ep1 40000
+1792892063 1650.9 951696 snn_ep1 40000
+1792892073 1660.9 951696 snn_ep1 40000
+1792892083 1670.9 951696 snn_ep1 40000
+1792892093 1680.9 951696 snn_ep1 40000
+1792892103 1690.9 951696 snn_ep1 40000
+1792892113 1700.9 951696 snn_ep1 40000
+1792892123 1710.9 951696 snn_ep1 40000
+1792892133 1720.9 951696 snn_ep1 40000
+1792892143 1730.9 951696 snn_ep1 40000
+1792892153 1740.9 951696 snn_ep1 40000
+1792892163 1750.9 951696 snn_ep1 40000
+1792892173 1760.9 951696 snn_ep1 40000
+1792892183 1770.9 951696 snn_ep1 40000
+1792892193 1780.9 951696 snn_ep1 40000
+1792892203 1790.9 951696 snn_ep1 40000
+1792892213 1800.9 951696 snn_ep1 40000
+1792892223 1810.9 951696 snn_ep1 40000
+1792892233 1820.9 951696 snn_ep1 40000
+1792892243 1830.9 951696 snn_ep1 40000
+1792892253 1840.9 951696 snn_ep1 40000
+1792892263 1850.9 951696 snn_ep1 40000
+1792892273 1860.9 951696 snn_ep1 40000
+1792892283 1870.9 951696 snn_ep1 40000
+1792892293 1880.9 951696 snn_ep1 40000
+1792892303 1890.9 951696 snn_ep1 40000
+1792892313 1900.9 951696 snn_ep1 40000
+1792892323 1910.9 951696 snn_ep1 40000
+1792892333 1920.9 951696 snn_ep1 50000
+1792892343 1930.9 951696 snn_ep1 50000
+1792892353 1940.9 951696 snn_ep1 50000
+1792892363 1950.9 951696 snn_ep1 50000
+1792892373 1960.9 951696 snn_ep1 50000
+1792892383 1970.9 951696 snn_ep1 50000
+1792892393 1980.9 951696 snn_ep1 50000
+1792892403 1990.9 951696 snn_ep1 50000
+1792892413 2000.9 951696 snn_ep1 50000
+1792892423 2010.9 951696 snn_ep1 50000
+1792892433 2020.9 951696 snn_ep1 50000
+1792892443 2031.0 951696 snn_ep1 50000
+1792892453 2041.0 951696 snn_ep1 50000
+1792892463 2051.0 951696 snn_ep1 50000
+1792892473 2061.0 951696 snn_ep1 50000
+1792892483 2071.0 951696 snn_ep1 50000
+1792892493 2081.0 951696 snn_ep1 50000
+1792892503 2091.0 951696 snn_ep1 50000
+1792892513 2101.0 951696 snn_ep1 50000
+1792892523 2111.0 951696 snn_ep1 50000
+1792892533 2121.0 951696 snn_ep1 50000
+1792892543 2131.0 951696 snn_ep1 50000
+1792892553 2141.0 951696 snn_ep1 50000
+1792892563 2151.0 951696 snn_ep1 50000
+1792892573 2161.0 951696 snn_ep1 50000
+1792892583 2171.0 951696 snn_ep1 50000
+1792892593 2181.0 951696 snn_ep1 50000
+1792892603 2191.0 951696 snn_ep1 50000
+1792892613 2201.0 951696 snn_ep1 50000
+1792892623 2211.0 951696 snn_ep1 50000
+1792892633 2221.0 951696 snn_ep1 50000
+1792892643 2231.0 951696 snn_ep1 50000
+1792892653 2241.0 951696 snn_ep1 50000
+1792892663 2251.1 951696 snn_ep1 50000
+1792892673 2261.1 951696 snn_ep1 60000
+1792892683 2271.1 951696 snn_ep1 60000
+1792892693 2281.1 951696 snn_ep1 60000
+1792892703 2291.1 951696 snn_ep1 60000
+1792892713 2301.1 951696 snn_ep1 60000
+1792892723 2311.1 951696 snn_ep1 60000
+1792892733 2321.1 951696 snn_ep1 60000
+1792892743 2331.1 951696 snn_ep1 60000
+1792892753 2341.1 951696 snn_ep1 60000
+1792892763 2351.1 951696 snn_ep1 60000
+1792892773 2361.1 951696 snn_ep1 60000
+1792892783 2371.1 951696 snn_ep1 60000
+1792892793 2381.1 951696 snn_ep1 60000
+1792892803 2391.1 951696 snn_ep1 60000
+1792892813 2401.1 951696 snn_ep1 60000
+1792892823 2411.1 951696 snn_ep1 60000
+1792892833 2421.1 951696 snn_ep1 60000
+1792892843 2431.1 951696 snn_ep1 60000
+1792892853 2441.1 951696 snn_ep1 60000
+1792892863 2451.1 951696 snn_ep1 60000
+1792892873 2461.1 951696 snn_ep1 60000
+1792892883 2471.1 951696 snn_ep1 60000
+1792892893 2481.1 951696 snn_ep1 60000
+1792892903 2491.1 951696 snn_ep1 60000
+1792892913 2501.1 951696 snn_ep1 60000
+1792892923 2511.1 951696 snn_ep1 60000
+1792892933 2521.1 951696 snn_ep1 60000
+1792892943 2531.1 951696 snn_ep1 60000
+1792892953 2541.1 951696 snn_ep1 60000
+1792892963 2551.1 951696 snn_ep1 60000
+1792892973 2561.1 951696 snn_ep1 60000
+1792892983 2571.1 951696 snn_ep1 60000
+1792892993 2581.1 951696 snn_ep1 60000
+1792893003 2591.1 951696 snn_ep1 60000
+1792893013 2601.1 951696 snn_ep1 70000
+1792893023 2611.1 951696 snn_ep1 70000
+1792893033 2621.1 951696 snn_ep1 70000
+1792893043 2631.1 951696 snn_ep1 70000
+1792893053 2641.1 951696 snn_ep1 70000
+1792893063 2651.1 951696 snn_ep1 70000
+1792893073 2661.1 951696 snn_ep1 70000
+1792893083 2671.1 951696 snn_ep1 70000
+1792893093 2681.1 951696 snn_ep1 70000
+1792893103 2691.1 951696 snn_ep1 70000
+1792893113 2701.1 951696 snn_ep1 70000
+1792893123 2711.1 951696 snn_ep1 70000
+1792893133 2721.1 951696 snn_ep1 70000
+1792893143 2731.1 951696 snn_ep1 70000
+1792893153 2741.1 951696 snn_ep1 70000
+1792893163 2751.1 951696 snn_ep1 70000
+1792893173 2761.1 951696 snn_ep1 70000
+1792893183 2771.1 951696 snn_ep1 70000
+1792893193 2781.1 951696 snn_ep1 70000
+1792893203 2791.1 951696 snn_ep1 70000
+1792893213 2801.1 951696 snn_ep1 70000
+1792893223 2811.1 951696 snn_ep1 70000
+1792893233 2821.1 951696 snn_ep1 70000
+1792893243 2831.1 951696 snn_ep1 70000
+1792893253 2841.1 951696 snn_ep1 70000
+1792893263 2851.1 951696 snn_ep1 70000
+1792893273 2861.1 951696 snn_ep1 70000
+1792893283 2871.1 951696 snn_ep1 70000
+1792893293 2881.1 951696 snn_ep1 70000
+1792893303 2891.1 951696 snn_ep1 70000
+1792893313 2901.1 951696 snn_ep1 70000
+1792893323 2911.1 951696 snn_ep1 70000
+1792893333 2921.1 951696 snn_ep1 70000
+1792893343 2931.1 951696 snn_ep1 80000
+1792893353 2941.1 951696 snn_ep1 80000
+1792893363 2951.1 951696 snn_ep1 80000
+1792893373 2961.1 951696 snn_ep1 80000
+1792893383 2971.1 951696 snn_ep1 80000
+1792893393 2981.1 951696 snn_ep1 80000
+1792893403 2991.1 951696 snn_ep1 80000
+1792893413 3001.1 951696 snn_ep1 80000
+1792893423 3011.1 951696 snn_ep1 80000
+1792893433 3021.1 951696 snn_ep1 80000
+1792893443 3031.1 951696 snn_ep1 80000
+1792893453 3041.1 951696 snn_ep1 80000
+1792893463 3051.1 951696 snn_ep1 80000
+1792893473 3061.1 951696 snn_ep1 80000
+1792893483 3071.1 951696 snn_ep1 80000
+1792893493 3081.1 951696 snn_ep1 80000
+1792893503 3091.1 951696 snn_ep1 80000
+1792893513 3101.1 951696 snn_ep1 80000
+1792893523 3111.1 951696 snn_ep1 80000
+1792893533 3121.1 951696 snn_ep1 80000
+1792893543 3131.1 951696 snn_ep1 80000
+1792893553 3141.1 951696 snn_ep1 80000
+1792893563 3151.1 951696 snn_ep1 80000
+1792893573 3161.1 951696 snn_ep1 80000
+1792893583 3171.1 951696 snn_ep1 80000
+1792893593 3181.1 951696 snn_ep1 80000
+1792893603 3191.1 951696 snn_ep1 80000
+1792893613 3201.1 951696 snn_ep1 80000
+1792893623 3211.1 951696 snn_ep1 80000
+1792893633 3221.1 951696 snn_ep1 80000
+1792893643 3231.1 951696 snn_ep1 80000
+1792893653 3241.1 951696 snn_ep1 80000
+1792893663 3251.1 951696 snn_ep1 80000
+1792893673 3261.1 951696 snn_ep1 90000
+1792893683 3271.1 951696 snn_ep1 90000
+1792893693 3281.1 951696 snn_ep1 90000
+1792893703 3291.1 951696 snn_ep1 90000
+1792893713 3301.1 951696 snn_ep1 90000
+1792893723 3311.1 951696 snn_ep1 90000
+1792893733 3321.1 951696 snn_ep1 90000
+1792893743 3331.1 951696 snn_ep1 90000
+1792893753 3341.1 951696 snn_ep1 90000
+1792893763 3351.1 951696 snn_ep1 90000
+1792893773 3361.1 951696 snn_ep1 90000
+1792893783 3371.1 951696 snn_ep1 90000
+1792893793 3381.1 951696 snn_ep1 90000
+1792893803 3391.1 951696 snn_ep1 90000
+1792893813 3401.1 951696 snn_ep1 90000
+1792893823 3411.1 951696 snn_ep1 90000
+1792893833 3421.1 951696 snn_ep1 90000
+1792893843 3431.1 951696 snn_ep1 90000
+1792893853 3441.1 951696 snn_ep1 90000
+1792893863 3451.1 951696 snn_ep1 90000
+1792893873 3461.1 951696 snn_ep1 90000
+1792893883 3471.1 951696 snn_ep1 90000
+1792893893 3481.1 951696 snn_ep1 90000
+1792893903 3491.1 951696 snn_ep1 90000
+1792893913 3501.1 951696 snn_ep1 90000
+1792893923 3511.1 951696 snn_ep1 90000
+1792893933 3521.1 951696 snn_ep1 90000
+1792893943 3531.1 951696 snn_ep1 90000
+1792893953 3541.1 951696 snn_ep1 90000
+1792893963 3551.1 951696 snn_ep1 90000
+1792893973 3561.1 951696 snn_ep1 100000
+1792893983 3571.1 951696 snn_ep1 100000
+1792893993 3581.1 951696 snn_ep1 100000
+1792894003 3591.1 951696 snn_ep1 100000
+1792894013 3601.1 951696 snn_ep1 100000
+1792894023 3611.1 951696 snn_ep1 100000
+1792894033 3621.1 951696 snn_ep1 100000
+1792894043 3631.1 951696 snn_ep1 100000
+1792894053 3641.1 951696 snn_ep1 100000
+1792894063 3651.1 951696 snn_ep1 100000
+1792894073 3661.1 951696 snn_ep1 100000
+1792894083 3671.1 951696 snn_ep1 100000
+1792894093 3681.1 951696 snn_ep1 100000
+1792894103 3691.1 951696 snn_ep1 100000
+1792894113 3701.1 951696 snn_ep1 100000
+1792894123 3711.1 951696 snn_ep1 100000
+1792894133 3721.1 951696 snn_ep1 100000
+1792894143 3731.1 951696 snn_ep1 100000
+1792894153 3741.1 951696 snn_ep1 100000
+1792894163 3751.1 951696 snn_ep1 100000
+1792894173 3761.1 951696 snn_ep1 100000
+1792894183 3771.1 951696 snn_ep1 100000
+1792894193 3781.1 951696 snn_ep1 100000
+1792894203 3791.1 951696 snn_ep1 100000
+1792894213 3801.1 951696 snn_ep1 100000
+1792894223 3811.1 951696 snn_ep1 100000
+1792894233 3821.1 951696 snn_ep1 100000
+1792894243 3831.1 951696 snn_ep1 100000
+1792894253 3841.1 951696 snn_ep1 100000
+1792894263 3851.1 951696 snn_ep1 100000
+1792894273 3861.1 951696 snn_ep1 100000
+1792894283 3871.1 951696 snn_ep1 100000
+1792894293 3881.1 951696 snn_ep1 100000
+1792894303 3891.1 951696 snn_ep1 100000
+1792894313 3901.1 951696 snn_ep1 100000
+1792894323 3911.1 951696 snn_ep1 110000
+1792894333 3921.1 951696 snn_ep1 110000
+1792894343 3931.1 951696 snn_ep1 110000
+1792894353 3941.1 951696 snn_ep1 110000
+1792894363 3951.1 951696 snn_ep1 110000
+1792894373 3961.1 951696 snn_ep1 110000
+1792894383 3971.1 951696 snn_ep1 110000
+1792894393 3981.1 951696 snn_ep1 110000
+1792894403 3991.1 951696 snn_ep1 110000
+1792894413 4001.1 951696 snn_ep1 110000
+1792894423 4011.1 951696 snn_ep1 110000
+1792894433 4021.1 951696 snn_ep1 110000
+1792894443 4031.1 951696 snn_ep1 110000
+1792894453 4041.1 951696 snn_ep1 110000
+1792894463 4051.1 951696 snn_ep1 110000
+1792894473 4061.1 951696 snn_ep1 110000
+1792894483 4071.1 951696 snn_ep1 110000
+1792894493 4081.1 951696 snn_ep1 110000
+1792894503 4091.1 951696 snn_ep1 110000
+1792894513 4101.1 951696 snn_ep1 110000
+1792894523 4111.1 951696 snn_ep1 110000
+1792894533 4121.1 951696 snn_ep1 110000
+1792894543 4131.1 951696 snn_ep1 110000
+1792894553 4141.1 951696 snn_ep1 110000
+1792894563 4151.1 951696 snn_ep1 110000
+1792894573 4161.1 951696 snn_ep1 110000
+1792894583 4171.1 951696 snn_ep1 110000
+1792894593 4181.1 951696 snn_ep1 110000
+1792894603 4191.1 951696 snn_ep1 110000
+1792894613 4201.1 951696 snn_ep1 110000
+1792894623 4211.1 951696 snn_ep1 110000
+1792894633 4221.1 951696 snn_ep1 110000
+1792894643 4231.1 951696 snn_ep1 110000
+1792894653 4241.1 951696 snn_ep1 110000
+1792894663 4251.1 951696 snn_ep1 120000
+1792894673 4261.1 951696 snn_ep1 120000
+1792894683 4271.1 951696 snn_ep1 120000
+1792894693 4281.1 951696 snn_ep1 120000
+1792894703 4291.1 951696 snn_ep1 120000
+1792894713 4301.2 951696 snn_ep1 120000
+1792894723 4311.2 951696 snn_ep1 120000
+1792894733 4321.2 951696 snn_ep1 120000
+1792894743 4331.2 951696 snn_ep1 120000
+1792894753 4341.2 951696 snn_ep1 120000
+1792894763 4351.2 951696 snn_ep1 120000
+1792894773 4361.2 951696 snn_ep1 120000
+1792894783 4371.2 951696 snn_ep1 120000
+1792894793 4381.2 951696 snn_ep1 120000
+1792894803 4391.2 951696 snn_ep1 120000
+1792894813 4401.2 951696 snn_ep1 120000
+1792894823 4411.2 951696 snn_ep1 120000
+1792894833 4421.2 951696 snn_ep1 120000
+1792894843 4431.2 951696 snn_ep1 120000
+1792894853 4441.2 951696 snn_ep1 120000
+1792894863 4451.2 951696 snn_ep1 120000
+1792894873 4461.2 951696 snn_ep1 120000
+1792894883 4471.2 951696 snn_ep1 120000
+1792894893 4481.2 951696 snn_ep1 120000
+1792894903 4491.2 951696 snn_ep1 120000
+1792894913 4501.2 951696 snn_ep1 120000
+1792894923 4511.2 951696 snn_ep1 120000
+1792894933 4521.2 951696 snn_ep1 120000
+1792894943 4531.2 951696 snn_ep1 120000
+1792894953 4541.2 951696 snn_ep1 120000
+1792894963 4551.2 951696 snn_ep1 120000
+1792894973 4561.2 951696 snn_ep1 120000
+1792894983 4571.2 951696 snn_ep1 120000
+1792894993 4581.2 951696 snn_ep1 120000
+1792895003 4591.2 951696 snn_ep1 120000
+1792895013 4601.2 951696 snn_ep1 130000
+1792895023 4611.2 951696 snn_ep1 130000
+1792895033 4621.2 951696 snn_ep1 130000
+1792895043 4631.2 951696 snn_ep1 130000
+1792895053 4641.2 951696 snn_ep1 130000
+1792895063 4651.2 951696 snn_ep1 130000
+1792895073 4661.2 951696 snn_ep1 130000
+1792895083 4671.2 951696 snn_ep1 130000
+1792895093 4681.2 951696 snn_ep1 130000
+1792895103 4691.2 951696 snn_ep1 130000
+1792895113 4701.2 951696 snn_ep1 130000
+1792895123 4711.2 951696 snn_ep1 130000
+1792895133 4721.2 951696 snn_ep1 130000
+1792895143 4731.2 951696 snn_ep1 130000
+1792895153 4741.2 951696 snn_ep1 130000
+1792895163 4751.2 951696 snn_ep1 130000
+1792895173 4761.2 951696 snn_ep1 130000
+1792895183 4771.2 951696 snn_ep1 130000
+1792895193 4781.2 951696 snn_ep1 130000
+1792895203 4791.2 951696 snn_ep1 130000
+1792895213 4801.2 951696 snn_ep1 130000
+1792895223 4811.2 951696 snn_ep1 130000
+1792895233 4821.2 951696 snn_ep1 130000
+1792895243 4831.2 951696 snn_ep1 130000
+1792895253 4841.2 951696 snn_ep1 130000
+1792895263 4851.2 951696 snn_ep1 130000
+1792895273 4861.2 951696 snn_ep1 130000
+1792895283 4871.2 951696 snn_ep1 130000
+1792895293 4881.2 951696 snn_ep1 130000
+1792895303 4891.2 951696 snn_ep1 130000
+1792895313 4901.2 951696 snn_ep1 130000
+1792895323 4911.2 951696 snn_ep1 130000
+1792895333 4921.2 951696 snn_ep1 130000
+1792895343 4931.2 951696 snn_ep1 140000
+1792895353 4941.2 951696 snn_ep1 140000
+1792895363 4951.2 951696 snn_ep1 140000
+1792895373 4961.2 951696 snn_ep1 140000
+1792895383 4971.2 951696 snn_ep1 140000
+1792895393 4981.2 951696 snn_ep1 140000
+1792895403 4991.2 951696 snn_ep1 140000
+1792895413 5001.2 951696 snn_ep1 140000
+1792895423 5011.2 951696 snn_ep1 140000
+1792895433 5021.2 951696 snn_ep1 140000
+1792895443 5031.2 951696 snn_ep1 140000
+1792895453 5041.2 951696 snn_ep1 140000
+1792895463 5051.2 951696 snn_ep1 140000
+1792895473 5061.2 951696 snn_ep1 140000
+1792895483 5071.2 951696 snn_ep1 140000
+1792895493 5081.2 951696 snn_ep1 140000
+1792895503 5091.2 951696 snn_ep1 140000
+1792895513 5101.2 951696 snn_ep1 140000
+1792895523 5111.2 951696 snn_ep1 140000
+1792895533 5121.2 951696 snn_ep1 140000
+1792895543 5131.2 951696 snn_ep1 140000
+1792895553 5141.2 951696 snn_ep1 140000
+1792895563 5151.2 951696 snn_ep1 140000
+1792895573 5161.2 951696 snn_ep1 140000
+1792895583 5171.2 951696 snn_ep1 140000
+1792895593 5181.2 951696 snn_ep1 140000
+1792895603 5191.2 951696 snn_ep1 140000
+1792895613 5201.2 951696 snn_ep1 140000
+1792895623 5211.2 951696 snn_ep1 140000
+1792895633 5221.2 951696 snn_ep1 140000
+1792895643 5231.2 951696 snn_ep1 140000
+1792895653 5241.2 951696 snn_ep1 140000
+1792895663 5251.2 951696 snn_ep1 140000
+1792895673 5261.2 951696 snn_ep1 150000
+1792895683 5271.2 951696 snn_ep1 150000
+1792895693 5281.2 951696 snn_ep1 150000
+1792895703 5291.2 951696 snn_ep1 150000
+1792895713 5301.2 951696 snn_ep1 150000
+1792895723 5311.2 951696 snn_ep1 150000
+1792895733 5321.2 951696 snn_ep1 150000
+1792895743 5331.2 951696 snn_ep1 150000
+1792895753 5341.2 951696 snn_ep1 150000
+1792895763 5351.2 951696 snn_ep1 150000
+1792895773 5361.2 951696 snn_ep1 150000
+1792895783 5371.2 951696 snn_ep1 150000
+1792895793 5381.2 951696 snn_ep1 150000
+1792895803 5391.2 951696 snn_ep1 150000
+1792895813 5401.2 951696 snn_ep1 150000
+1792895823 5411.2 951696 snn_ep1 150000
+1792895833 5421.2 951696 snn_ep1 150000
+1792895843 5431.2 951696 snn_ep1 150000
+1792895853 5441.2 951696 snn_ep1 150000
+1792895863 5451.2 951696 snn_ep1 150000
+1792895873 5461.2 951696 snn_ep1 150000
+1792895883 5471.2 951696 snn_ep1 150000
+1792895893 5481.2 951696 snn_ep1 150000
+1792895903 5491.2 951696 snn_ep1 150000
+1792895913 5501.2 951696 snn_ep1 150000
+1792895923 5511.2 951696 snn_ep1 150000
+1792895933 5521.2 951696 snn_ep1 150000
+1792895943 5531.2 951696 snn_ep1 150000
+1792895953 5541.2 951696 snn_ep1 150000
+1792895963 5551.2 951696 snn_ep1 150000
+1792895973 5561.2 951696 snn_ep1 150000
+1792895983 5571.2 951696 snn_ep1 150000
+1792895993 5581.2 951696 snn_ep1 150000
+1792896003 5591.2 951696 snn_ep1 160000
+1792896013 5601.2 951696 snn_ep1 160000
+1792896023 5611.2 951696 snn_ep1 160000
+1792896033 5621.2 951696 snn_ep1 160000
+1792896043 5631.2 951696 snn_ep1 160000
+1792896053 5641.3 951696 snn_ep1 160000
+1792896063 5651.3 951696 snn_ep1 160000
+1792896073 5661.3 951696 snn_ep1 160000
+1792896083 5671.3 951696 snn_ep1 160000
+1792896093 5681.3 951696 snn_ep1 160000
+1792896103 5691.3 951696 snn_ep1 160000
+1792896113 5701.3 951696 snn_ep1 160000
+1792896123 5711.3 951696 snn_ep1 160000
+1792896133 5721.3 951696 snn_ep1 160000
+1792896143 5731.3 951696 snn_ep1 160000
+1792896153 5741.3 951696 snn_ep1 160000
+1792896163 5751.3 951696 snn_ep1 160000
+1792896173 5761.3 951696 snn_ep1 160000
+1792896183 5771.3 951696 snn_ep1 160000
+1792896193 5781.3 951696 snn_ep1 160000
+1792896203 5791.3 951696 snn_ep1 160000
+1792896213 5801.3 951696 snn_ep1 160000
+1792896223 5811.3 951696 snn_ep1 160000
+1792896233 5821.3 951696 snn_ep1 160000
+1792896243 5831.3 951696 snn_ep1 160000
+1792896253 5841.3 951696 snn_ep1 160000
+1792896263 5851.3 951696 snn_ep1 160000
+1792896273 5861.3 951696 snn_ep1 160000
+1792896283 5871.3 951696 snn_ep1 160000
+1792896293 5881.3 951696 snn_ep1 160000
+1792896303 5891.4 951696 snn_ep1 160000
+1792896313 5901.4 951696 snn_ep1 160000
+1792896323 5911.4 951696 snn_ep1 160000
+1792896333 5921.4 951696 snn_ep1 160000
+1792896343 5931.4 951696 snn_ep1 170000
+1792896353 5941.4 951696 snn_ep1 170000
+1792896363 5951.4 951696 snn_ep1 170000
+1792896373 5961.4 951696 snn_ep1 170000
+1792896383 5971.4 951696 snn_ep1 170000
+1792896393 5981.4 951696 snn_ep1 170000
+1792896403 5991.4 951696 snn_ep1 170000
+1792896413 6001.4 951696 snn_ep1 170000
+1792896423 6011.4 951696 snn_ep1 170000
+1792896433 6021.4 951696 snn_ep1 170000
+1792896443 6031.4 951696 snn_ep1 170000
+1792896453 6041.4 951696 snn_ep1 170000
+1792896463 6051.4 951696 snn_ep1 170000
+1792896473 6061.4 951696 snn_ep1 170000
+1792896483 6071.4 951696 snn_ep1 170000
+1792896493 6081.4 951696 snn_ep1 170000
+1792896503 6091.4 951696 snn_ep1 170000
+1792896513 6101.4 951696 snn_ep1 170000
+1792896523 6111.4 951696 snn_ep1 170000
+1792896533 6121.4 951696 snn_ep1 170000
+1792896543 6131.4 951696 snn_ep1 170000
+1792896553 6141.4 951696 snn_ep1 170000
+1792896563 6151.4 951696 snn_ep1 170000
+1792896573 6161.4 951696 snn_ep1 170000
+1792896583 6171.4 951696 snn_ep1 170000
+1792896593 6181.4 951696 snn_ep1 170000
+1792896603 6191.4 951696 snn_ep1 170000
+1792896613 6201.4 951696 snn_ep1 170000
+1792896623 6211.4 951696 snn_ep1 170000
+1792896633 6221.4 951696 snn_ep1 170000
+1792896643 6231.4 951696 snn_ep1 170000
+1792896653 6241.4 951696 snn_ep1 170000
+1792896663 6251.4 951696 snn_ep1 180000
+1792896673 6261.4 951696 snn_ep1 180000
+1792896683 6271.4 951696 snn_ep1 180000
+1792896693 6281.4 951696 snn_ep1 180000
+1792896703 6291.4 951696 snn_ep1 180000
+1792896713 6301.4 951696 snn_ep1 180000
+1792896723 6311.4 951696 snn_ep1 180000
+1792896733 6321.4 951696 snn_ep1 180000
+1792896743 6331.4 951696 snn_ep1 180000
+1792896753 6341.4 951696 snn_ep1 180000
+1792896763 6351.4 951696 snn_ep1 180000
+1792896773 6361.4 951696 snn_ep1 180000
+1792896783 6371.4 951696 snn_ep1 180000
+1792896793 6381.4 951696 snn_ep1 180000
+1792896803 6391.4 951696 snn_ep1 180000
+1792896813 6401.4 951696 snn_ep1 180000
+1792896823 6411.4 951696 snn_ep1 180000
+1792896833 6421.4 951696 snn_ep1 180000
+1792896843 6431.4 951696 snn_ep1 180000
+1792896853 6441.4 951696 snn_ep1 180000
+1792896863 6451.4 951696 snn_ep1 180000
+1792896873 6461.4 951696 snn_ep1 180000
+1792896883 6471.4 951696 snn_ep1 180000
+1792896893 6481.4 951696 snn_ep1 180000
+1792896903 6491.4 951696 snn_ep1 180000
+1792896913 6501.4 951696 snn_ep1 180000
+1792896923 6511.4 951696 snn_ep1 180000
+1792896933 6521.4 951696 snn_ep1 180000
+1792896943 6531.4 951696 snn_ep1 180000
+1792896953 6541.4 951696 snn_ep1 180000
+1792896963 6551.4 951696 snn_ep1 180000
+1792896973 6561.4 951696 snn_ep1 180000
+1792896983 6571.4 951696 snn_ep1 190000
+1792897061 6648.8 951696 snn_ep1 190000
+1792897071 6658.8 951696 snn_ep1 190000
+1792897081 6668.8 951696 snn_ep1 190000
+1792897091 6678.8 951696 snn_ep1 190000
+1792897101 6688.8 951696 snn_ep1 190000
+1792897111 6698.8 951696 snn_ep1 190000
+1792897121 6708.8 951696 snn_ep1 190000
+1792897131 6718.8 951696 snn_ep1 190000
+1792897141 6728.8 951696 snn_ep1 190000
+1792897151 6738.8 951696 snn_ep1 190000
+1792897161 6748.8 951696 snn_ep1 190000
+1792897171 6758.8 951696 snn_ep1 190000
+1792897181 6768.8 951696 snn_ep1 190000
+1792897191 6778.8 951696 snn_ep1 190000
+1792897201 6788.8 951696 snn_ep1 190000
+1792897211 6798.8 951696 snn_ep1 190000
+1792897221 6808.8 951696 snn_ep1 190000
+1792897231 6818.8 951696 snn_ep1 190000
+1792897241 6828.8 951696 snn_ep1 190000
+1792897251 6838.8 951696 snn_ep1 190000
+1792897261 6848.8 951696 snn_ep1 190000
+1792897271 6858.8 951696 snn_ep1 190000
+1792897281 6868.8 951696 snn_ep1 190000
+1792897291 6878.8 951696 snn_ep1 190000
+1792897301 6888.8 951696 snn_ep1 190000
+1792897311 6898.8 951696 snn_ep1 190000
+1792897321 6908.8 951696 snn_ep1 190000
+1792897331 6918.8 951696 snn_ep1 190000
+1792897341 6928.8 951696 snn_ep1 190000
+1792897351 6938.8 951696 snn_ep1 190000
+1792897361 6948.8 951696 snn_ep1 190000
+1792897371 6958.8 951696 snn_ep1 190000
+1792897381 6968.8 951696 snn_ep1 200000
+1792897391 6978.8 951696 snn_ep1 200000
+1792897401 6988.8 951696 snn_ep1 200000
+1792897411 6998.8 951696 snn_ep1 200000
+1792897421 7008.8 951696 snn_ep1 200000
+1792897431 7018.8 951696 snn_ep1 200000
+1792897441 7028.8 951696 snn_ep1 200000
+1792897451 7038.8 951696 snn_ep1 200000
+1792897461 7048.8 951696 snn_ep1 200000
+1792897471 7058.8 951696 snn_ep1 200000
+1792897481 7068.8 951696 snn_ep1 200000
+1792897491 7078.8 951696 snn_ep1 200000
+1792897501 7088.8 951696 snn_ep1 200000
+1792897511 7098.8 951696 snn_ep1 200000
+1792897521 7108.8 951696 snn_ep1 200000
+1792897531 7118.8 951696 snn_ep1 200000
+1792897541 7128.8 951696 snn_ep1 200000
+1792897551 7138.8 951696 snn_ep1 200000
+1792897561 7148.8 951696 snn_ep1 200000
+1792897571 7158.8 951696 snn_ep1 200000
+1792897581 7168.8 951696 snn_ep1 200000
+1792897591 7178.8 951696 snn_ep1 200000
+1792897601 7188.8 951696 snn_ep1 200000
+1792897611 7198.8 951696 snn_ep1 200000
+1792897621 7208.8 951696 snn_ep1 200000
+1792897631 7218.8 951696 snn_ep1 200000
+1792897641 7228.8 951696 snn_ep1 200000
+1792897651 7238.8 951696 snn_ep1 200000
+1792897661 7248.8 951696 snn_ep1 200000
+1792897671 7258.8 951696 snn_ep1 200000
+1792897681 7268.8 951696 snn_ep1 200000
+1792897691 7278.8 951696 snn_ep1 200000
+1792897701 7288.8 951696 snn_ep1 210000
+1792897711 7298.8 951696 snn_ep1 210000
+1792897721 7308.8 951696 snn_ep1 210000
+1792897731 7318.8 951696 snn_ep1 210000
+1792897741 7328.8 951696 snn_ep1 210000
+1792897751 7338.8 951696 snn_ep1 210000
+1792897761 7348.8 951696 snn_ep1 210000
+1792897771 7358.8 951696 snn_ep1 210000
+1792897781 7368.8 951696 snn_ep1 210000
+1792897791 7378.8 951696 snn_ep1 210000
+1792897801 7388.8 951696 snn_ep1 210000
+1792897811 7398.8 951696 snn_ep1 210000
+1792897821 7408.8 951696 snn_ep1 210000
+1792897831 7418.8 951696 snn_ep1 210000
+1792897841 7428.8 951696 snn_ep1 210000
+1792897851 7438.8 951696 snn_ep1 210000
+1792897861 7448.8 951696 snn_ep1 210000
+1792897871 7458.8 951696 snn_ep1 210000
+1792897881 7468.8 951696 snn_ep1 210000
+1792897891 7478.8 951696 snn_ep1 210000
+1792897901 7488.8 951696 snn_ep1 210000
+1792897911 7498.8 951696 snn_ep1 210000
+1792897921 7508.8 951696 snn_ep1 210000
+1792897931 7518.8 951696 snn_ep1 210000
+1792897941 7528.8 951696 snn_ep1 210000
+1792897951 7538.8 951696 snn_ep1 210000
+1792897961 7548.8 951696 snn_ep1 210000
+1792897971 7558.8 951696 snn_ep1 210000
+1792897981 7568.8 951696 snn_ep1 210000
+1792897991 7578.8 951696 snn_ep1 210000
+1792898001 7588.8 951696 snn_ep1 210000
+1792898011 7598.8 951696 snn_ep1 210000
+1792898021 7608.8 951696 snn_ep1 220000
+1792898031 7618.8 951696 snn_ep1 220000
+1792898041 7628.8 951696 snn_ep1 220000
+1792898051 7638.8 951696 snn_ep1 220000
+1792898061 7648.8 951696 snn_ep1 220000
+1792898071 7658.8 951696 snn_ep1 220000
+1792898081 7668.8 951696 snn_ep1 220000
+1792898091 7678.8 951696 snn_ep1 220000
+1792898101 7688.8 951696 snn_ep1 220000
+1792898111 7698.8 951696 snn_ep1 220000
+1792898121 7708.8 951696 snn_ep1 220000
+1792898131 7718.8 951696 snn_ep1 220000
+1792898141 7728.8 951696 snn_ep1 220000
+1792898151 7738.8 951696 snn_ep1 220000
+1792898161 7748.8 951696 snn_ep1 220000
+1792898171 7758.8 951696 snn_ep1 220000
+1792898181 7768.8 951696 snn_ep1 220000
+1792898191 7778.8 951696 snn_ep1 220000
+1792898201 7788.8 951696 snn_ep1 220000
+1792898211 7798.8 951696 snn_ep1 220000
+1792898221 7808.8 951696 snn_ep1 220000
+1792898231 7818.8 951696 snn_ep1 220000
+1792898241 7828.8 951696 snn_ep1 220000
+1792898251 7838.8 951696 snn_ep1 220000
+1792898261 7848.8 951696 snn_ep1 220000
+1792898271 7858.8 951696 snn_ep1 220000
+1792898281 7868.8 951696 snn_ep1 220000
+1792898291 7878.8 951696 snn_ep1 220000
+1792898301 7888.8 951696 snn_ep1 220000
+1792898311 7898.8 951696 snn_ep1 220000
+1792898321 7908.8 951696 snn_ep1 220000
+1792898331 7918.8 951696 snn_ep1 230000
+1792898341 7928.8 951696 snn_ep1 230000
+1792898351 7938.8 951696 snn_ep1 230000
+1792898361 7948.8 951696 snn_ep1 230000
+1792898371 7958.8 951696 snn_ep1 230000
+1792898381 7968.8 951696 snn_ep1 230000
+1792898391 7978.8 951696 snn_ep1 230000
+1792898401 7988.8 951696 snn_ep1 230000
+1792898411 7998.8 951696 snn_ep1 230000
+1792898421 8008.8 951696 snn_ep1 230000
+1792898431 8018.8 951696 snn_ep1 230000
+1792898441 8028.8 951696 snn_ep1 230000
+1792898451 8038.8 951696 snn_ep1 230000
+1792898461 8048.8 951696 snn_ep1 230000
+1792898471 8058.8 951696 snn_ep1 230000
+1792898481 8068.8 951696 snn_ep1 230000
+1792898491 8078.8 951696 snn_ep1 230000
+1792898501 8088.8 951696 snn_ep1 230000
+1792898511 8098.8 951696 snn_ep1 230000
+1792898521 8108.8 951696 snn_ep1 230000
+1792898531 8118.8 951696 snn_ep1 230000
+1792898541 8128.8 951696 snn_ep1 230000
+1792898551 8138.8 951696 snn_ep1 230000
+1792898561 8148.8 951696 snn_ep1 230000
+1792898571 8158.8 951696 snn_ep1 230000
+1792898581 8168.8 951696 snn_ep1 230000
+1792898591 8178.8 951696 snn_ep1 230000
+1792898601 8188.8 951696 snn_ep1 230000
+1792898611 8198.8 951696 snn_ep1 230000
+1792898621 8208.8 951696 snn_ep1 230000
+1792898631 8218.8 951696 snn_ep1 230000
+1792898641 8228.8 951696 snn_ep1 230000
+1792898651 8238.8 951696 snn_ep1 240000
+1792898661 8248.8 951696 snn_ep1 240000
+1792898671 8258.8 951696 snn_ep1 240000
+1792898681 8268.8 951696 snn_ep1 240000
+1792898691 8278.8 951696 snn_ep1 240000
+1792898701 8288.8 951696 snn_ep1 240000
+1792898711 8298.8 951696 snn_ep1 240000
+1792898721 8308.8 951696 snn_ep1 240000
+1792898731 8318.8 951696 snn_ep1 240000
+1792898741 8328.8 951696 snn_ep1 240000
+1792898751 8338.8 951696 snn_ep1 240000
+1792898761 8348.8 951696 snn_ep1 240000
+1792898771 8358.8 951696 snn_ep1 240000
+1792898781 8368.8 951696 snn_ep1 240000
+1792898791 8378.8 951696 snn_ep1 240000
+1792898801 8388.8 951696 snn_ep1 240000
+1792898811 8398.8 951696 snn_ep1 240000
+1792898821 8408.8 951696 snn_ep1 240000
+1792898831 8418.8 951696 snn_ep1 240000
+1792898841 8428.8 951696 snn_ep1 240000
+1792898851 8438.8 951696 snn_ep1 240000
+1792898861 8448.8 951696 snn_ep1 240000
+1792898871 8458.8 951696 snn_ep1 240000
+1792898881 8468.8 951696 snn_ep1 240000
+1792898891 8478.8 951696 snn_ep1 240000
+1792898901 8488.8 951696 snn_ep1 240000
+1792898911 8498.8 951696 snn_ep1 240000
+1792898921 8508.8 951696 snn_ep1 240000
+1792898931 8518.8 951696 snn_ep1 240000
+1792898941 8528.8 951696 snn_ep1 240000
+1792898951 8538.8 951696 snn_ep1 240000
+1792898961 8548.8 951696 snn_ep1 240000
+1792898971 8558.8 951696 snn_ep1 240000
+1792898981 8568.8 951696 snn_ep1 250000
+1792898991 8578.8 951696 snn_ep1 250000
+1792899001 8588.8 951696 snn_ep1 250000
+1792899011 8598.8 951696 snn_ep1 250000
+1792899021 8608.8 951696 snn_ep1 250000
+1792899031 8618.8 951696 snn_ep1 250000
+1792899041 8628.8 951696 snn_ep1 250000
+1792899051 8638.8 951696 snn_ep1 250000
+1792899061 8648.8 951696 snn_ep1 250000
+1792899071 8658.8 951696 snn_ep1 250000
+1792899081 8668.8 951696 snn_ep1 250000
+1792899091 8678.8 951696 snn_ep1 250000
+1792899101 8688.8 951696 snn_ep1 250000
+1792899111 8698.8 951696 snn_ep1 250000
+1792899121 8708.8 951696 snn_ep1 250000
+1792899131 8718.8 951696 snn_ep1 250000
+1792899141 8728.8 951696 snn_ep1 250000
+1792899151 8738.8 951696 snn_ep1 250000
+1792899161 8748.8 951696 snn_ep1 250000
+1792899171 8758.8 951696 snn_ep1 250000
+1792899181 8768.8 951696 snn_ep1 250000
+1792899191 8778.8 951696 snn_ep1 250000
+1792899201 8788.8 951696 snn_ep1 250000
+1792899211 8798.8 951696 snn_ep1 250000
+1792899221 8808.8 951696 snn_ep1 250000
+1792899231 8818.8 951696 snn_ep1 250000
+1792899241 8828.8 951696 snn_ep1 250000
+1792899251 8838.8 951696 snn_ep1 250000
+1792899261 8848.8 951696 snn_ep1 250000
+1792899271 8858.9 951696 snn_ep1 250000
+1792899281 8868.9 951696 snn_ep1 250000
+1792899291 8878.9 951696 snn_ep1 250000
+1792899301 8888.9 951696 snn_ep1 250000
+1792899311 8898.9 951696 snn_ep1 260000
+1792899321 8908.9 951696 snn_ep1 260000
+1792899331 8918.9 951696 snn_ep1 260000
+1792899341 8928.9 951696 snn_ep1 260000
+1792899351 8938.9 951696 snn_ep1 260000
+1792899361 8948.9 951696 snn_ep1 260000
+1792899371 8958.9 951696 snn_ep1 260000
+1792899381 8968.9 951696 snn_ep1 260000
+1792899391 8978.9 951696 snn_ep1 260000
+1792899401 8988.9 951696 snn_ep1 260000
+1792899411 8998.9 951696 snn_ep1 260000
+1792899421 9008.9 951696 snn_ep1 260000
+1792899431 9018.9 951696 snn_ep1 260000
+1792899441 9028.9 951696 snn_ep1 260000
+1792899451 9038.9 951696 snn_ep1 260000
+1792899461 9048.9 951696 snn_ep1 260000
+1792899471 9058.9 951696 snn_ep1 260000
+1792899481 9068.9 951696 snn_ep1 260000
+1792899491 9078.9 951696 snn_ep1 260000
+1792899501 9088.9 951696 snn_ep1 260000
+1792899511 9098.9 951696 snn_ep1 260000
+1792899521 9108.9 951696 snn_ep1 260000
+1792899531 9118.9 951696 snn_ep1 260000
+1792899541 9128.9 951696 snn_ep1 260000
+1792899551 9138.9 951696 snn_ep1 260000
+1792899561 9148.9 951696 snn_ep1 260000
+1792899571 9158.9 951696 snn_ep1 260000
+1792899581 9168.9 951696 snn_ep1 260000
+1792899591 9178.9 951696 snn_ep1 260000
+1792899601 9188.9 951696 snn_ep1 260000
+1792899611 9198.9 951696 snn_ep1 260000
+1792899621 9208.9 951696 snn_ep1 270000
+1792899631 9218.9 951696 snn_ep1 270000
+1792899641 9228.9 951696 snn_ep1 270000
+1792899651 9238.9 951696 snn_ep1 270000
+1792899661 9248.9 951696 snn_ep1 270000
+1792899671 9258.9 951696 snn_ep1 270000
+1792899681 9268.9 951696 snn_ep1 270000
+1792899691 9278.9 951696 snn_ep1 270000
+1792899701 9288.9 951696 snn_ep1 270000
+1792899711 9298.9 951696 snn_ep1 270000
+1792899721 9308.9 951696 snn_ep1 270000
+1792899731 9318.9 951696 snn_ep1 270000
+1792899741 9328.9 951696 snn_ep1 270000
+1792899751 9338.9 951696 snn_ep1 270000
+1792899761 9348.9 951696 snn_ep1 270000
+1792899771 9358.9 951696 snn_ep1 270000
+1792899781 9368.9 951696 snn_ep1 270000
+1792899791 9378.9 951696 snn_ep1 270000
+1792899801 9388.9 951696 snn_ep1 270000
+1792899811 9398.9 951696 snn_ep1 270000
+1792899821 9408.9 951696 snn_ep1 270000
+1792899831 9418.9 951696 snn_ep1 270000
+1792899841 9428.9 951696 snn_ep1 270000
+1792899851 9438.9 951696 snn_ep1 270000
+1792899861 9448.9 951696 snn_ep1 270000
+1792899871 9458.9 951696 snn_ep1 270000
+1792899881 9468.9 951696 snn_ep1 270000
+1792899891 9478.9 951696 snn_ep1 270000
+1792899901 9488.9 951696 snn_ep1 270000
+1792899911 9498.9 951696 snn_ep1 270000
+1792899921 9508.9 951696 snn_ep1 270000
+1792899931 9518.9 951696 snn_ep1 270000
+1792899941 9528.9 951696 snn_ep1 280000
+1792899951 9538.9 951696 snn_ep1 280000
+1792899961 9548.9 951696 snn_ep1 280000
+1792899971 9558.9 951696 snn_ep1 280000
+1792899981 9568.9 951696 snn_ep1 280000
+1792899991 9578.9 951696 snn_ep1 280000
+1792900001 9588.9 951696 snn_ep1 280000
+1792900011 9598.9 951696 snn_ep1 280000
+1792900021 9608.9 951696 snn_ep1 280000
+1792900031 9618.9 951696 snn_ep1 280000
+1792900041 9628.9 951696 snn_ep1 280000
+1792900051 9638.9 951696 snn_ep1 280000
+1792900061 9648.9 951696 snn_ep1 280000
+1792900071 9658.9 951696 snn_ep1 280000
+1792900081 9668.9 951696 snn_ep1 280000
+1792900091 9678.9 951696 snn_ep1 280000
+1792900101 9688.9 951696 snn_ep1 280000
+1792900111 9698.9 951696 snn_ep1 280000
+1792900121 9708.9 951696 snn_ep1 280000
+1792900131 9718.9 951696 snn_ep1 280000
+1792900141 9728.9 951696 snn_ep1 280000
+1792900151 9738.9 951696 snn_ep1 280000
+1792900161 9748.9 951696 snn_ep1 280000
+1792900171 9758.9 951696 snn_ep1 280000
+1792900181 9768.9 951696 snn_ep1 280000
+1792900191 9778.9 951696 snn_ep1 280000
+1792900201 9788.9 951696 snn_ep1 280000
+1792900211 9798.9 951696 snn_ep1 280000
+1792900221 9808.9 951696 snn_ep1 280000
+1792900231 9818.9 951696 snn_ep1 280000
+1792900241 9828.9 951696 snn_ep1 280000
+1792900251 9838.9 951696 snn_ep1 280000
+1792900261 9848.9 951696 snn_ep1 290000
+1792900271 9858.9 951696 snn_ep1 290000
+1792900281 9868.9 951696 snn_ep1 290000
+1792900291 9878.9 951696 snn_ep1 290000
+1792900301 9888.9 951696 snn_ep1 290000
+1792900311 9898.9 951696 snn_ep1 290000
+1792900321 9908.9 951696 snn_ep1 290000
+1792900331 9918.9 951696 snn_ep1 290000
+1792900341 9928.9 951696 snn_ep1 290000
+1792900351 9938.9 951696 snn_ep1 290000
+1792900361 9948.9 951696 snn_ep1 290000
+1792900371 9958.9 951696 snn_ep1 290000
+1792900381 9968.9 951696 snn_ep1 290000
+1792900391 9978.9 951696 snn_ep1 290000
+1792900401 9988.9 951696 snn_ep1 290000
+1792900411 9998.9 951696 snn_ep1 290000
+1792900421 10008.9 951696 snn_ep1 290000
+1792900431 10018.9 951696 snn_ep1 290000
+1792900441 10028.9 951696 snn_ep1 290000
+1792900451 10038.9 951696 snn_ep1 290000
+1792900461 10048.9 951696 snn_ep1 290000
+1792900471 10058.9 951696 snn_ep1 290000
+1792900481 10068.9 951696 snn_ep1 290000
+1792900491 10078.9 951696 snn_ep1 290000
+1792900501 10088.9 951696 snn_ep1 290000
+1792900511 10098.9 951696 snn_ep1 290000
+1792900521 10108.9 951696 snn_ep1 290000
+1792900531 10118.9 951696 snn_ep1 290000
+1792900541 10128.9 951696 snn_ep1 290000
+1792900551 10138.9 951696 snn_ep1 290000
+1792900561 10148.9 951696 snn_ep1 300000
+1792900571 10158.9 951696 snn_ep1 300000
+1792900581 10168.9 951696 snn_ep1 300000
+1792900591 10178.9 951696 snn_ep1 300000
+1792900601 10188.9 951696 snn_ep1 300000
+1792900611 10198.9 951696 snn_ep1 300000
+1792900621 10208.9 951696 snn_ep1 300000
+1792900631 10218.9 951696 snn_ep1 300000
+1792900641 10228.9 951696 snn_ep1 300000
+1792900651 10238.9 951696 snn_ep1 300000
+1792900661 10248.9 951696 snn_ep1 300000
+1792900671 10258.9 951696 snn_ep1 300000
+1792900681 10268.9 951696 snn_ep1 300000
+1792900691 10279.0 951696 snn_ep1 300000
+1792900701 10289.0 951696 snn_ep1 300000
+1792900711 10299.0 951696 snn_ep1 300000
+1792900721 10309.0 951696 snn_ep1 300000
+1792900731 10319.0 951696 snn_ep1 300000
+1792900741 10329.0 951696 snn_ep1 300000
+1792900751 10339.0 951696 snn_ep1 300000
+1792900761 10349.0 951696 snn_ep1 300000
+1792900771 10359.0 951696 snn_ep1 300000
+1792900781 10369.0 951696 snn_ep1 300000
+1792900791 10379.0 951696 snn_ep1 300000
+1792900801 10389.0 951696 snn_ep1 300000
+1792900811 10399.0 951696 snn_ep1 300000
+1792900821 10409.0 951696 snn_ep1 300000
+1792900831 10419.0 951696 snn_ep1 300000
+1792900841 10429.0 951696 snn_ep1 300000
+1792900851 10439.0 951696 snn_ep1 300000
+1792900861 10449.0 951696 snn_ep1 300000
+1792900871 10459.0 951696 snn_ep1 310000
+1792900881 10469.0 951696 snn_ep1 310000
+1792900891 10479.0 951696 snn_ep1 310000
+1792900901 10489.0 951696 snn_ep1 310000
+1792900911 10499.0 951696 snn_ep1 310000
+1792900921 10509.0 951696 snn_ep1 310000
+1792900931 10519.0 951696 snn_ep1 310000
+1792900941 10529.0 951696 snn_ep1 310000
+1792900951 10539.0 951696 snn_ep1 310000
+1792900961 10549.0 951696 snn_ep1 310000
+1792900971 10559.0 951696 snn_ep1 310000
+1792900981 10569.0 951696 snn_ep1 310000
+1792900991 10579.0 951696 snn_ep1 310000
+1792901001 10589.0 951696 snn_ep1 310000
+1792901011 10599.0 951696 snn_ep1 310000
+1792901021 10609.0 951696 snn_ep1 310000
+1792901031 10619.0 951696 snn_ep1 310000
+1792901041 10629.0 951696 snn_ep1 310000
+1792901051 10639.0 951696 snn_ep1 310000
+1792901061 10649.0 951696 snn_ep1 310000
+1792901071 10659.0 951696 snn_ep1 310000
+1792901081 10669.0 951696 snn_ep1 310000
+1792901091 10679.0 951696 snn_ep1 310000
+1792901101 10689.0 951696 snn_ep1 310000
+1792901111 10699.0 951696 snn_ep1 310000
+1792901121 10709.0 951696 snn_ep1 310000
+1792901131 10719.0 951696 snn_ep1 310000
+1792901141 10729.0 951696 snn_ep1 310000
+1792901151 10739.0 951696 snn_ep1 310000
+1792901161 10749.0 951696 snn_ep1 310000
+1792901171 10759.0 951696 snn_ep1 320000
+1792901181 10769.0 951696 snn_ep1 320000
+1792901191 10779.0 951696 snn_ep1 320000
+1792901201 10789.0 951696 snn_ep1 320000
+1792901211 10799.0 951696 snn_ep1 320000
+1792901221 10809.0 951696 snn_ep1 320000
+1792901231 10819.0 951696 snn_ep1 320000
+1792901241 10829.0 951696 snn_ep1 320000
+1792901251 10839.0 951696 snn_ep1 320000
+1792901261 10849.0 951696 snn_ep1 320000
+1792901271 10859.0 951696 snn_ep1 320000
+1792901281 10869.0 951696 snn_ep1 320000
+1792901291 10879.0 951696 snn_ep1 320000
+1792901301 10889.0 951696 snn_ep1 320000
+1792901311 10899.0 951696 snn_ep1 320000
+1792901321 10909.0 951696 snn_ep1 320000
+1792901331 10919.0 951696 snn_ep1 320000
+1792901341 10929.0 951696 snn_ep1 320000
+1792901351 10939.0 951696 snn_ep1 320000
+1792901361 10949.0 951696 snn_ep1 320000
+1792901371 10959.0 951696 snn_ep1 320000
+1792901381 10969.0 951696 snn_ep1 320000
+1792901391 10979.0 951696 snn_ep1 320000
+1792901401 10989.0 951696 snn_ep1 320000
+1792901411 10999.0 951696 snn_ep1 320000
+1792901421 11009.0 951696 snn_ep1 320000
+1792901431 11019.0 951696 snn_ep1 320000
+1792901441 11029.0 951696 snn_ep1 320000
+1792901451 11039.0 951696 snn_ep1 320000
+1792901461 11049.0 951696 snn_ep1 320000
+1792901471 11059.0 951696 snn_ep1 320000
+1792901481 11069.0 951696 snn_ep1 320000
+1792901491 11079.0 951696 snn_ep1 330000
+1792901501 11089.0 951696 snn_ep1 330000
+1792901511 11099.0 951696 snn_ep1 330000
+1792901521 11109.0 951696 snn_ep1 330000
+1792901531 11119.0 951696 snn_ep1 330000
+1792901541 11129.0 951696 snn_ep1 330000
+1792901551 11139.0 951696 snn_ep1 330000
+1792901561 11149.0 951696 snn_ep1 330000
+1792901571 11159.0 951696 snn_ep1 330000
+1792901581 11169.0 951696 snn_ep1 330000
+1792901591 11179.0 951696 snn_ep1 330000
+1792901601 11189.0 951696 snn_ep1 330000
+1792901611 11199.0 951696 snn_ep1 330000
+1792901621 11209.0 951696 snn_ep1 330000
+1792901631 11219.0 951696 snn_ep1 330000
+1792901641 11229.0 951696 snn_ep1 330000
+1792901651 11239.0 951696 snn_ep1 330000
+1792901661 11249.0 951696 snn_ep1 330000
+1792901671 11259.0 951696 snn_ep1 330000
+1792901681 11269.0 951696 snn_ep1 330000
+1792901691 11279.0 951696 snn_ep1 330000
+1792901701 11289.0 951696 snn_ep1 330000
+1792901711 11299.0 951696 snn_ep1 330000
+1792901721 11309.0 951696 snn_ep1 330000
+1792901731 11319.0 951696 snn_ep1 330000
+1792901741 11329.0 951696 snn_ep1 330000
+1792901751 11339.0 951696 snn_ep1 330000
+1792901761 11349.0 951696 snn_ep1 330000
+1792901771 11359.0 951696 snn_ep1 330000
+1792901781 11369.0 951696 snn_ep1 330000
+1792901791 11379.0 951696 snn_ep1 330000
+1792901801 11389.0 951696 snn_ep1 330000
+1792901811 11399.0 951696 snn_ep1 330000
+1792901821 11409.0 951696 snn_ep1 340000
+1792901831 11419.0 951696 snn_ep1 340000
+1792901841 11429.0 951696 snn_ep1 340000
+1792901851 11439.0 951696 snn_ep1 340000
+1792901861 11449.0 951696 snn_ep1 340000
+1792901871 11459.0 951696 snn_ep1 340000
+1792901881 11469.0 951696 snn_ep1 340000
+1792901891 11479.0 951696 snn_ep1 340000
+1792901901 11489.0 951696 snn_ep1 340000
+1792901911 11499.0 951696 snn_ep1 340000
+1792901921 11509.0 951696 snn_ep1 340000
+1792901931 11519.0 951696 snn_ep1 340000
+1792901941 11529.0 951696 snn_ep1 340000
+1792901951 11539.0 951696 snn_ep1 340000
+1792901961 11549.0 951696 snn_ep1 340000
+1792901971 11559.0 951696 snn_ep1 340000
+1792901981 11569.0 951696 snn_ep1 340000
+1792901991 11579.0 951696 snn_ep1 340000
+1792902001 11589.0 951696 snn_ep1 340000
+1792902011 11599.1 951696 snn_ep1 340000
+1792902021 11609.1 951696 snn_ep1 340000
+1792902031 11619.1 951696 snn_ep1 340000
+1792902041 11629.1 951696 snn_ep1 340000
+1792902051 11639.1 951696 snn_ep1 340000
+1792902061 11649.1 951696 snn_ep1 340000
+1792902071 11659.1 951696 snn_ep1 340000
+1792902081 11669.1 951696 snn_ep1 340000
+1792902091 11679.1 951696 snn_ep1 340000
+1792902101 11689.1 951696 snn_ep1 340000
+1792902111 11699.1 951696 snn_ep1 340000
+1792902121 11709.1 951696 snn_ep1 340000
+1792902131 11719.1 951696 snn_ep1 340000
+1792902141 11729.1 951696 snn_ep1 350000
+1792902151 11739.1 951696 snn_ep1 350000
+1792902161 11749.1 951696 snn_ep1 350000
+1792902171 11759.1 951696 snn_ep1 350000
+1792902181 11769.1 951696 snn_ep1 350000
+1792902191 11779.1 951696 snn_ep1 350000
+1792902201 11789.1 951696 snn_ep1 350000
+1792902211 11799.1 951696 snn_ep1 350000
+1792902221 11809.1 951696 snn_ep1 350000
+1792902231 11819.1 951696 snn_ep1 350000
+1792902241 11829.1 951696 snn_ep1 350000
+1792902251 11839.1 951696 snn_ep1 350000
+1792902261 11849.1 951696 snn_ep1 350000
+1792902271 11859.1 951696 snn_ep1 350000
+1792902281 11869.1 951696 snn_ep1 350000
+1792902291 11879.1 951696 snn_ep1 350000
+1792902301 11889.1 951696 snn_ep1 350000
+1792902311 11899.1 951696 snn_ep1 350000
+1792902321 11909.1 951696 snn_ep1 350000
+1792902331 11919.1 951696 snn_ep1 350000
+1792902341 11929.1 951696 snn_ep1 350000
+1792902351 11939.1 951696 snn_ep1 350000
+1792902361 11949.1 951696 snn_ep1 350000
+1792902371 11959.1 951696 snn_ep1 350000
+1792902381 11969.1 951696 snn_ep1 350000
+1792902391 11979.1 951696 snn_ep1 350000
+1792902401 11989.1 951696 snn_ep1 350000
+1792902411 11999.1 951696 snn_ep1 350000
+1792902421 12009.1 951696 snn_ep1 350000
+1792902431 12019.1 951696 snn_ep1 350000
+1792902441 12029.1 951696 snn_ep1 350000
+1792902451 12039.1 951696 snn_ep1 350000
+1792902461 12049.1 951696 snn_ep1 350000
+1792902471 12059.1 951696 snn_ep1 360000
+1792902481 12069.1 951696 snn_ep1 360000
+1792902491 12079.1 951696 snn_ep1 360000
+1792902501 12089.1 951696 snn_ep1 360000
+1792902511 12099.1 951696 snn_ep1 360000
+1792902521 12109.1 951696 snn_ep1 360000
+1792902531 12119.1 951696 snn_ep1 360000
+1792902541 12129.1 951696 snn_ep1 360000
+1792902551 12139.1 951696 snn_ep1 360000
+1792902561 12149.1 951696 snn_ep1 360000
+1792902571 12159.1 951696 snn_ep1 360000
+1792902581 12169.1 951696 snn_ep1 360000
+1792902591 12179.1 951696 snn_ep1 360000
+1792902601 12189.1 951696 snn_ep1 360000
+1792902611 12199.1 951696 snn_ep1 360000
+1792902621 12209.1 951696 snn_ep1 360000
+1792902631 12219.1 951696 snn_ep1 360000
+1792902641 12229.1 951696 snn_ep1 360000
+1792902651 12239.1 951696 snn_ep1 360000
+1792902661 12249.1 951696 snn_ep1 360000
+1792902671 12259.1 951696 snn_ep1 360000
+1792902681 12269.1 951696 snn_ep1 360000
+1792902691 12279.1 951696 snn_ep1 360000
+1792902701 12289.1 951696 snn_ep1 360000
+1792902711 12299.1 951696 snn_ep1 360000
+1792902721 12309.1 951696 snn_ep1 360000
+1792902731 12319.1 951696 snn_ep1 360000
+1792902741 12329.1 951696 snn_ep1 360000
+1792902751 12339.1 951696 snn_ep1 360000
+1792902761 12349.1 951696 snn_ep1 360000
+1792902771 12359.1 951696 snn_ep1 360000
+1792902781 12369.1 951696 snn_ep1 360000
+1792902791 12379.1 951696 snn_ep1 360000
+1792902801 12389.1 951696 snn_ep1 370000
+1792902811 12399.1 951696 snn_ep1 370000
+1792902821 12409.1 951696 snn_ep1 370000
+1792902831 12419.1 951696 snn_ep1 370000
+1792902841 12429.1 951696 snn_ep1 370000
+1792902851 12439.1 951696 snn_ep1 370000
+1792902861 12449.1 951696 snn_ep1 370000
+1792902871 12459.1 951696 snn_ep1 370000
+1792902881 12469.1 951696 snn_ep1 370000
+1792902891 12479.1 951696 snn_ep1 370000
+1792902901 12489.1 951696 snn_ep1 370000
+1792902911 12499.1 951696 snn_ep1 370000
+1792902921 12509.1 951696 snn_ep1 370000
+1792902931 12519.1 951696 snn_ep1 370000
+1792902941 12529.1 951696 snn_ep1 370000
+1792902951 12539.1 951696 snn_ep1 370000
+1792902961 12549.1 951696 snn_ep1 370000
+1792902971 12559.1 951696 snn_ep1 370000
+1792902981 12569.1 951696 snn_ep1 370000
+1792902991 12579.1 951696 snn_ep1 370000
+1792903001 12589.1 951696 snn_ep1 370000
+1792903011 12599.1 951696 snn_ep1 370000
+1792903021 12609.1 951696 snn_ep1 370000
+1792903031 12619.1 951696 snn_ep1 370000
+1792903041 12629.1 951696 snn_ep1 370000
+1792903051 12639.1 951696 snn_ep1 370000
+1792903061 12649.1 951696 snn_ep1 370000
+1792903071 12659.1 951696 snn_ep1 370000
+1792903081 12669.1 951696 snn_ep1 370000
+1792903091 12679.1 951696 snn_ep1 370000
+1792903101 12689.1 951696 snn_ep1 370000
+1792903111 12699.1 951696 snn_ep1 370000
+1792903121 12709.1 951696 snn_ep1 370000
+1792903131 12719.1 951696 snn_ep1 380000
+1792903141 12729.1 951696 snn_ep1 380000
+1792903151 12739.1 951696 snn_ep1 380000
+1792903161 12749.1 951696 snn_ep1 380000
+1792903171 12759.1 951696 snn_ep1 380000
+1792903181 12769.1 951696 snn_ep1 380000
+1792903191 12779.1 951696 snn_ep1 380000
+1792903201 12789.1 951696 snn_ep1 380000
+1792903211 12799.1 951696 snn_ep1 380000
+1792903221 12809.1 951696 snn_ep1 380000
+1792903231 12819.1 951696 snn_ep1 380000
+1792903241 12829.1 951696 snn_ep1 380000
+1792903251 12839.1 951696 snn_ep1 380000
+1792903261 12849.1 951696 snn_ep1 380000
+1792903271 12859.1 951696 snn_ep1 380000
+1792903281 12869.1 951696 snn_ep1 380000
+1792903291 12879.1 951696 snn_ep1 380000
+1792903301 12889.1 951696 snn_ep1 380000
+1792903311 12899.1 951696 snn_ep1 380000
+1792903321 12909.1 951696 snn_ep1 380000
+1792903331 12919.1 951696 snn_ep1 380000
+1792903341 12929.1 951696 snn_ep1 380000
+1792903351 12939.1 951696 snn_ep1 380000
+1792903361 12949.1 951696 snn_ep1 380000
+1792903371 12959.1 951696 snn_ep1 380000
+1792903381 12969.1 951696 snn_ep1 380000
+1792903391 12979.1 951696 snn_ep1 380000
+1792903401 12989.2 951696 snn_ep1 380000
+1792903411 12999.2 951696 snn_ep1 380000
+1792903421 13009.2 951696 snn_ep1 380000
+1792903431 13019.2 951696 snn_ep1 380000
+1792903441 13029.2 951696 snn_ep1 380000
+1792903451 13039.2 951696 snn_ep1 380000
+1792903461 13049.2 951696 snn_ep1 390000
+1792903471 13059.2 951696 snn_ep1 390000
+1792903481 13069.2 951696 snn_ep1 390000
+1792903491 13079.2 951696 snn_ep1 390000
+1792903501 13089.2 951696 snn_ep1 390000
+1792903511 13099.2 951696 snn_ep1 390000
+1792903521 13109.2 951696 snn_ep1 390000
+1792903531 13119.2 951696 snn_ep1 390000
+1792903541 13129.2 951696 snn_ep1 390000
+1792903551 13139.2 951696 snn_ep1 390000
+1792903561 13149.2 951696 snn_ep1 390000
+1792903571 13159.2 951696 snn_ep1 390000
+1792903581 13169.2 951696 snn_ep1 390000
+1792903591 13179.2 951696 snn_ep1 390000
+1792903601 13189.2 951696 snn_ep1 390000
+1792903611 13199.2 951696 snn_ep1 390000
+1792903621 13209.2 951696 snn_ep1 390000
+1792903631 13219.2 951696 snn_ep1 390000
+1792903641 13229.2 951696 snn_ep1 390000
+1792903651 13239.2 951696 snn_ep1 390000
+1792903661 13249.2 951696 snn_ep1 390000
+1792903671 13259.2 951696 snn_ep1 390000
+1792903681 13269.2 951696 snn_ep1 390000
+1792903691 13279.2 951696 snn_ep1 390000
+1792903701 13289.2 951696 snn_ep1 390000
+1792903711 13299.2 951696 snn_ep1 390000
+1792903721 13309.2 951696 snn_ep1 390000
+1792903731 13319.2 951696 snn_ep1 390000
+1792903741 13329.2 951696 snn_ep1 390000
+1792903751 13339.2 951696 snn_ep1 390000
+1792903761 13349.2 951696 snn_ep1 390000
+1792903771 13359.2 951696 snn_ep1 390000
+1792903781 13369.2 951696 snn_ep1 400000
+1792903791 13379.2 951696 snn_ep1 400000
+1792903801 13389.2 951696 snn_ep1 400000
+1792903811 13399.2 951696 snn_ep1 400000
+1792903821 13409.2 951696 snn_ep1 400000
+1792903831 13419.2 951696 snn_ep1 400000
+1792903841 13429.2 951696 snn_ep1 400000
+1792903851 13439.2 951696 snn_ep1 400000
+1792903861 13449.2 951696 snn_ep1 400000
+1792903871 13459.2 951696 snn_ep1 400000
+1792903881 13469.2 951696 snn_ep1 400000
+1792903891 13479.2 951696 snn_ep1 400000
+1792903901 13489.2 951696 snn_ep1 400000
+1792903911 13499.2 951696 snn_ep1 400000
+1792903921 13509.2 951696 snn_ep1 400000
+1792903931 13519.2 951696 snn_ep1 400000
+1792903941 13529.2 951696 snn_ep1 400000
+1792903951 13539.2 951696 snn_ep1 400000
+1792903961 13549.2 951696 snn_ep1 400000
+1792903971 13559.2 951696 snn_ep1 400000
+1792903981 13569.2 951696 snn_ep1 400000
+1792903991 13579.2 951696 snn_ep1 400000
+1792904001 13589.2 951696 snn_ep1 400000
+1792904011 13599.2 951696 snn_ep1 400000
+1792904021 13609.2 951696 snn_ep1 400000
+1792904031 13619.2 951696 snn_ep1 400000
+1792904041 13629.2 951696 snn_ep1 400000
+1792904051 13639.2 951696 snn_ep1 400000
+1792904061 13649.2 951696 snn_ep1 400000
+1792904071 13659.2 951696 snn_ep1 400000
+1792904081 13669.2 951696 snn_ep1 400000
+1792904091 13679.2 951696 snn_ep1 400000
+1792904101 13689.2 951696 snn_ep1 410000
+1792904111 13699.2 951696 snn_ep1 410000
+1792904121 13709.2 951696 snn_ep1 410000
+1792904131 13719.2 951696 snn_ep1 410000
+1792904141 13729.2 951696 snn_ep1 410000
+1792904151 13739.2 951696 snn_ep1 410000
+1792904161 13749.2 951696 snn_ep1 410000
+1792904171 13759.2 951696 snn_ep1 410000
+1792904181 13769.2 951696 snn_ep1 410000
+1792904191 13779.2 951696 snn_ep1 410000
+1792904201 13789.2 951696 snn_ep1 410000
+1792904211 13799.2 951696 snn_ep1 410000
+1792904221 13809.2 951696 snn_ep1 410000
+1792904231 13819.2 951696 snn_ep1 410000
+1792904241 13829.2 951696 snn_ep1 410000
+1792904251 13839.2 951696 snn_ep1 410000
+1792904261 13849.2 951696 snn_ep1 410000
+1792904271 13859.2 951696 snn_ep1 410000
+1792904281 13869.2 951696 snn_ep1 410000
+1792904291 13879.2 951696 snn_ep1 410000
+1792904301 13889.2 951696 snn_ep1 410000
+1792904311 13899.2 951696 snn_ep1 410000
+1792904321 13909.2 951696 snn_ep1 410000
+1792904331 13919.2 951696 snn_ep1 410000
+1792904341 13929.2 951696 snn_ep1 410000
+1792904351 13939.2 951696 snn_ep1 410000
+1792904361 13949.2 951696 snn_ep1 410000
+1792904371 13959.2 951696 snn_ep1 410000
+1792904381 13969.2 951696 snn_ep1 410000
+1792904391 13979.2 951696 snn_ep1 410000
+1792904401 13989.2 951696 snn_ep1 420000
+1792904411 13999.2 951696 snn_ep1 420000
+1792904421 14009.2 951696 snn_ep1 420000
+1792904431 14019.2 951696 snn_ep1 420000
+1792904441 14029.2 951696 snn_ep1 420000
+1792904451 14039.2 951696 snn_ep1 420000
+1792904461 14049.2 951696 snn_ep1 420000
+1792904471 14059.2 951696 snn_ep1 420000
+1792904481 14069.2 951696 snn_ep1 420000
+1792904491 14079.2 951696 snn_ep1 420000
+1792904501 14089.2 951696 snn_ep1 420000
+1792904511 14099.2 951696 snn_ep1 420000
+1792904521 14109.2 951696 snn_ep1 420000
+1792904531 14119.2 951696 snn_ep1 420000
+1792904541 14129.2 951696 snn_ep1 420000
+1792904551 14139.2 951696 snn_ep1 420000
+1792904561 14149.2 951696 snn_ep1 420000
+1792904571 14159.2 951696 snn_ep1 420000
+1792904581 14169.2 951696 snn_ep1 420000
+1792904591 14179.2 951696 snn_ep1 420000
+1792904601 14189.2 951696 snn_ep1 420000
+1792904611 14199.2 951696 snn_ep1 420000
+1792904621 14209.2 951696 snn_ep1 420000
+1792904631 14219.2 951696 snn_ep1 420000
+1792904641 14229.2 951696 snn_ep1 420000
+1792904651 14239.2 951696 snn_ep1 420000
+1792904661 14249.2 951696 snn_ep1 420000
+1792904671 14259.2 951696 snn_ep1 420000
+1792904681 14269.2 951696 snn_ep1 420000
+1792904691 14279.2 951696 snn_ep1 430000
+1792904701 14289.2 951696 snn_ep1 430000
+1792904711 14299.2 951696 snn_ep1 430000
+1792904721 14309.2 951696 snn_ep1 430000
+1792904731 14319.2 951696 snn_ep1 430000
+1792904741 14329.2 951696 snn_ep1 430000
+1792904751 14339.2 951696 snn_ep1 430000
+1792904761 14349.2 951696 snn_ep1 430000
+1792904771 14359.2 951696 snn_ep1 430000
+1792904781 14369.2 951696 snn_ep1 430000
+1792904791 14379.2 951696 snn_ep1 430000
+1792904801 14389.2 951696 snn_ep1 430000
+1792904811 14399.2 951696 snn_ep1 430000
+1792904821 14409.2 951696 snn_ep1 430000
+1792904831 14419.2 951696 snn_ep1 430000
+1792904841 14429.2 951696 snn_ep1 430000
+1792904851 14439.2 951696 snn_ep1 430000
+1792904861 14449.2 951696 snn_ep1 430000
+1792904871 14459.2 951696 snn_ep1 430000
+1792904881 14469.2 951696 snn_ep1 430000
+1792904891 14479.2 951696 snn_ep1 430000
+1792904901 14489.2 951696 snn_ep1 430000
+1792904911 14499.2 951696 snn_ep1 430000
+1792904921 14509.2 951696 snn_ep1 430000
+1792904931 14519.2 951696 snn_ep1 430000
+1792904941 14529.2 951696 snn_ep1 430000
+1792904951 14539.2 951696 snn_ep1 430000
+1792904961 14549.2 951696 snn_ep1 430000
+1792904971 14559.2 951696 snn_ep1 430000
+1792904981 14569.2 951696 snn_ep1 430000
+1792904991 14579.2 951696 snn_ep1 430000
+1792905001 14589.2 951696 snn_ep1 440000
+1792905011 14599.2 951696 snn_ep1 440000
+1792905021 14609.2 951696 snn_ep1 440000
+1792905031 14619.2 951696 snn_ep1 440000
+1792905041 14629.2 951696 snn_ep1 440000
+1792905051 14639.2 951696 snn_ep1 440000
+1792905061 14649.2 951696 snn_ep1 440000
+1792905071 14659.2 951696 snn_ep1 440000
+1792905081 14669.2 951696 snn_ep1 440000
+1792905091 14679.2 951696 snn_ep1 440000
+1792905101 14689.2 951696 snn_ep1 440000
+1792905111 14699.2 951696 snn_ep1 440000
+1792905121 14709.2 951696 snn_ep1 440000
+1792905131 14719.2 951696 snn_ep1 440000
+1792905141 14729.2 951696 snn_ep1 440000
+1792905151 14739.2 951696 snn_ep1 440000
+1792905161 14749.2 951696 snn_ep1 440000
+1792905171 14759.2 951696 snn_ep1 440000
+1792905181 14769.2 951696 snn_ep1 440000
+1792905191 14779.2 951696 snn_ep1 440000
+1792905201 14789.2 951696 snn_ep1 440000
+1792905211 14799.2 951696 snn_ep1 440000
+1792905221 14809.2 951696 snn_ep1 440000
+1792905231 14819.2 951696 snn_ep1 440000
+1792905241 14829.2 951696 snn_ep1 440000
+1792905251 14839.2 951696 snn_ep1 440000
+1792905261 14849.2 951696 snn_ep1 440000
+1792905271 14859.2 951696 snn_ep1 440000
+1792905281 14869.2 951696 snn_ep1 440000
+1792905291 14879.2 951696 snn_ep1 440000
+1792905301 14889.2 951696 snn_ep1 440000
+1792905311 14899.2 951696 snn_ep1 440000
+1792905321 14909.2 951696 snn_ep1 450000
+1792905331 14919.2 951696 snn_ep1 450000
+1792905341 14929.2 951696 snn_ep1 450000
+1792905351 14939.2 951696 snn_ep1 450000
+1792905361 14949.2 951696 snn_ep1 450000
+1792905371 14959.2 951696 snn_ep1 450000
+1792905381 14969.2 951696 snn_ep1 450000
+1792905391 14979.2 951696 snn_ep1 450000
+1792905401 14989.2 951696 snn_ep1 450000
+1792905411 14999.2 951696 snn_ep1 450000
+1792905421 15009.2 951696 snn_ep1 450000
+1792905431 15019.2 951696 snn_ep1 450000
+1792905441 15029.2 951696 snn_ep1 450000
+1792905451 15039.2 951696 snn_ep1 450000
+1792905461 15049.2 951696 snn_ep1 450000
+1792905471 15059.2 951696 snn_ep1 450000
+1792905481 15069.2 951696 snn_ep1 450000
+1792905491 15079.2 951696 snn_ep1 450000
+1792905501 15089.2 951696 snn_ep1 450000
+1792905511 15099.2 951696 snn_ep1 450000
+1792905521 15109.2 951696 snn_ep1 450000
+1792905531 15119.2 951696 snn_ep1 450000
+1792905541 15129.2 951696 snn_ep1 450000
+1792905551 15139.2 951696 snn_ep1 450000
+1792905561 15149.2 951696 snn_ep1 450000
+1792905571 15159.2 951696 snn_ep1 450000
+1792905581 15169.2 951696 snn_ep1 450000
+1792905591 15179.2 951696 snn_ep1 450000
+1792905601 15189.2 951696 snn_ep1 450000
+1792905611 15199.2 951696 snn_ep1 450000
+1792905621 15209.2 951696 snn_ep1 450000
+1792905631 15219.2 951696 snn_ep1 450000
+1792905641 15229.2 951696 snn_ep1 460000
+1792905651 15239.2 951696 snn_ep1 460000
+1792905661 15249.2 951696 snn_ep1 460000
+1792905671 15259.2 951696 snn_ep1 460000
+1792905681 15269.2 951696 snn_ep1 460000
+1792905691 15279.2 951696 snn_ep1 460000
+1792905701 15289.2 951696 snn_ep1 460000
+1792905711 15299.2 951696 snn_ep1 460000
+1792905721 15309.2 951696 snn_ep1 460000
+1792905731 15319.2 951696 snn_ep1 460000
+1792905741 15329.2 951696 snn_ep1 460000
+1792905751 15339.2 951696 snn_ep1 460000
+1792905761 15349.2 951696 snn_ep1 460000
+1792905771 15359.2 951696 snn_ep1 460000
+1792905781 15369.2 951696 snn_ep1 460000
+1792905791 15379.2 951696 snn_ep1 460000
+1792905801 15389.2 951696 snn_ep1 460000
+1792905811 15399.2 951696 snn_ep1 460000
+1792905821 15409.2 951696 snn_ep1 460000
+1792905831 15419.2 951696 snn_ep1 460000
+1792905841 15429.2 951696 snn_ep1 460000
+1792905851 15439.2 951696 snn_ep1 460000
+1792905861 15449.2 951696 snn_ep1 460000
+1792905871 15459.2 951696 snn_ep1 460000
+1792905881 15469.2 951696 snn_ep1 460000
+1792905891 15479.2 951696 snn_ep1 460000
+1792905901 15489.2 951696 snn_ep1 460000
+1792905911 15499.2 951696 snn_ep1 460000
+1792905921 15509.2 951696 snn_ep1 460000
+1792905931 15519.2 951696 snn_ep1 460000
+1792905941 15529.2 951696 snn_ep1 460000
+1792905951 15539.2 951696 snn_ep1 470000
+1792905961 15549.2 951696 snn_ep1 470000
+1792905971 15559.2 951696 snn_ep1 470000
+1792905981 15569.2 951696 snn_ep1 470000
+1792905991 15579.3 951696 snn_ep1 470000
+1792906001 15589.3 951696 snn_ep1 470000
+1792906011 15599.3 951696 snn_ep1 470000
+1792906021 15609.3 951696 snn_ep1 470000
+1792906031 15619.3 951696 snn_ep1 470000
+1792906041 15629.3 951696 snn_ep1 470000
+1792906051 15639.3 951696 snn_ep1 470000
+1792906061 15649.3 951696 snn_ep1 470000
+1792906071 15659.3 951696 snn_ep1 470000
+1792906081 15669.3 951696 snn_ep1 470000
+1792906091 15679.3 951696 snn_ep1 470000
+1792906101 15689.3 951696 snn_ep1 470000
+1792906111 15699.3 951696 snn_ep1 470000
+1792906121 15709.3 951696 snn_ep1 470000
+1792906131 15719.3 951696 snn_ep1 470000
+1792906141 15729.3 951696 snn_ep1 470000
+1792906151 15739.3 951696 snn_ep1 470000
+1792906161 15749.3 951696 snn_ep1 470000
+1792906171 15759.3 951696 snn_ep1 470000
+1792906181 15769.3 951696 snn_ep1 470000
+1792906191 15779.3 951696 snn_ep1 470000
+1792906201 15789.3 951696 snn_ep1 470000
+1792906211 15799.3 951696 snn_ep1 470000
+1792906221 15809.3 951696 snn_ep1 470000
+1792906231 15819.3 951696 snn_ep1 470000
+1792906241 15829.3 951696 snn_ep1 470000
+1792906251 15839.3 951696 snn_ep1 480000
+1792906261 15849.3 951696 snn_ep1 480000
+1792906271 15859.3 951696 snn_ep1 480000
+1792906281 15869.3 951696 snn_ep1 480000
+1792906291 15879.3 951696 snn_ep1 480000
+1792906301 15889.3 951696 snn_ep1 480000
+1792906311 15899.3 951696 snn_ep1 480000
+1792906321 15909.3 951696 snn_ep1 480000
+1792906331 15919.3 951696 snn_ep1 480000
+1792906341 15929.3 951696 snn_ep1 480000
+1792906351 15939.3 951696 snn_ep1 480000
+1792906361 15949.3 951696 snn_ep1 480000
+1792906371 15959.3 951696 snn_ep1 480000
+1792906381 15969.3 951696 snn_ep1 480000
+1792906391 15979.3 951696 snn_ep1 480000
+1792906401 15989.3 951696 snn_ep1 480000
+1792906411 15999.3 951696 snn_ep1 480000
+1792906435 16023.6 951696 snn_ep1 480000
+1792906445 16033.6 951696 snn_ep1 480000
+1792906455 16043.6 951696 snn_ep1 480000
+1792906505 16054.4 951696 snn_ep1 480000
+1792906515 16064.4 951696 snn_ep1 480000
diff --git a/results/hashing/m8_v1b/runs/rss_ctl.tsv b/results/hashing/m8_v1b/runs/rss_ctl.tsv
new file mode 100644
index 0000000000000000000000000000000000000000..591b3735937f3be86a4a806b183133d7cbe7c2ca
--- /dev/null
+++ b/results/hashing/m8_v1b/runs/rss_ctl.tsv
@@ -0,0 +1,1476 @@
+1792862100 0.0 33384 load 0
+1792862110 10.0 721836 build 0
+1792862120 20.1 755572 build 0
+1792862130 30.1 592264 snn_ep1 0
+1792862140 40.1 592264 snn_ep1 0
+1792862150 50.1 592264 snn_ep1 0
+1792862160 60.1 592264 snn_ep1 0
+1792862170 70.1 592264 snn_ep1 0
+1792862180 80.1 592264 snn_ep1 0
+1792862190 90.1 592264 snn_ep1 0
+1792862200 100.1 592264 snn_ep1 0
+1792862210 110.1 592264 snn_ep1 0
+1792862220 120.1 592264 snn_ep1 0
+1792862230 130.1 592268 snn_ep1 0
+1792862240 140.1 592268 snn_ep1 0
+1792862250 150.1 592268 snn_ep1 0
+1792862260 160.1 592268 snn_ep1 0
+1792862270 170.1 592228 snn_ep1 10000
+1792862280 180.1 592228 snn_ep1 10000
+1792862290 190.1 592228 snn_ep1 10000
+1792862300 200.1 592228 snn_ep1 10000
+1792862310 210.1 592228 snn_ep1 10000
+1792862320 220.1 592228 snn_ep1 10000
+1792862330 230.1 592228 snn_ep1 10000
+1792862340 240.1 592228 snn_ep1 10000
+1792862350 250.1 592228 snn_ep1 10000
+1792862360 260.1 592228 snn_ep1 10000
+1792862370 270.1 592228 snn_ep1 10000
+1792862380 280.1 592228 snn_ep1 10000
+1792862390 290.1 592232 snn_ep1 10000
+1792862400 300.1 592232 snn_ep1 10000
+1792862410 310.1 592232 snn_ep1 20000
+1792862420 320.1 592232 snn_ep1 20000
+1792862430 330.1 592232 snn_ep1 20000
+1792862440 340.1 592232 snn_ep1 20000
+1792862450 350.1 592232 snn_ep1 20000
+1792862460 360.1 592232 snn_ep1 20000
+1792862470 370.1 592232 snn_ep1 20000
+1792862480 380.1 592232 snn_ep1 20000
+1792862490 390.1 592232 snn_ep1 20000
+1792862500 400.1 592232 snn_ep1 20000
+1792862510 410.1 592232 snn_ep1 20000
+1792862520 420.1 592232 snn_ep1 20000
+1792862530 430.1 592232 snn_ep1 20000
+1792862540 440.2 592232 snn_ep1 20000
+1792862550 450.2 592232 snn_ep1 30000
+1792862560 460.2 592232 snn_ep1 30000
+1792862570 470.2 592232 snn_ep1 30000
+1792862580 480.2 592232 snn_ep1 30000
+1792862590 490.2 592232 snn_ep1 30000
+1792862600 500.2 592232 snn_ep1 30000
+1792862610 510.2 592232 snn_ep1 30000
+1792862620 520.2 592232 snn_ep1 30000
+1792862630 530.2 592232 snn_ep1 30000
+1792862640 540.2 592232 snn_ep1 30000
+1792862650 550.2 592232 snn_ep1 30000
+1792862660 560.2 592232 snn_ep1 30000
+1792862670 570.2 592232 snn_ep1 30000
+1792862680 580.2 592232 snn_ep1 40000
+1792862690 590.2 592232 snn_ep1 40000
+1792862700 600.2 592232 snn_ep1 40000
+1792862710 610.2 592232 snn_ep1 40000
+1792862720 620.2 592232 snn_ep1 40000
+1792862730 630.2 592232 snn_ep1 40000
+1792862740 640.2 592232 snn_ep1 40000
+1792862750 650.2 592232 snn_ep1 40000
+1792862760 660.2 592232 snn_ep1 40000
+1792862770 670.2 592232 snn_ep1 40000
+1792862780 680.2 592232 snn_ep1 40000
+1792862790 690.2 592232 snn_ep1 40000
+1792862800 700.2 592232 snn_ep1 40000
+1792862810 710.2 592232 snn_ep1 40000
+1792862820 720.2 592232 snn_ep1 40000
+1792862830 730.2 592232 snn_ep1 50000
+1792862840 740.2 592232 snn_ep1 50000
+1792862850 750.2 592232 snn_ep1 50000
+1792862860 760.2 592232 snn_ep1 50000
+1792862870 770.2 592232 snn_ep1 50000
+1792862880 780.2 592232 snn_ep1 50000
+1792862890 790.2 592232 snn_ep1 50000
+1792862900 800.2 592232 snn_ep1 50000
+1792862910 810.2 592232 snn_ep1 50000
+1792862920 820.2 592232 snn_ep1 50000
+1792862930 830.2 592232 snn_ep1 50000
+1792862940 840.2 592232 snn_ep1 50000
+1792862950 850.2 592232 snn_ep1 60000
+1792862960 860.2 592232 snn_ep1 60000
+1792862970 870.2 592232 snn_ep1 60000
+1792862980 880.2 592232 snn_ep1 60000
+1792862990 890.2 592232 snn_ep1 60000
+1792863000 900.2 592232 snn_ep1 60000
+1792863010 910.2 592232 snn_ep1 60000
+1792863020 920.2 592232 snn_ep1 60000
+1792863030 930.2 592232 snn_ep1 60000
+1792863040 940.2 592232 snn_ep1 60000
+1792863050 950.2 592232 snn_ep1 60000
+1792863060 960.2 592232 snn_ep1 60000
+1792863070 970.2 592232 snn_ep1 60000
+1792863080 980.2 592236 snn_ep1 70000
+1792863090 990.2 592236 snn_ep1 70000
+1792863100 1000.2 592236 snn_ep1 70000
+1792863110 1010.2 592236 snn_ep1 70000
+1792863120 1020.2 592236 snn_ep1 70000
+1792863130 1030.2 592236 snn_ep1 70000
+1792863140 1040.2 592236 snn_ep1 70000
+1792863150 1050.2 592236 snn_ep1 70000
+1792863160 1060.2 592236 snn_ep1 70000
+1792863170 1070.2 592236 snn_ep1 70000
+1792863180 1080.2 592236 snn_ep1 70000
+1792863190 1090.2 592236 snn_ep1 70000
+1792863200 1100.2 592236 snn_ep1 80000
+1792863210 1110.2 592236 snn_ep1 80000
+1792863220 1120.2 592236 snn_ep1 80000
+1792863230 1130.2 592236 snn_ep1 80000
+1792863240 1140.2 592236 snn_ep1 80000
+1792863250 1150.2 592236 snn_ep1 80000
+1792863260 1160.2 592236 snn_ep1 80000
+1792863270 1170.2 592236 snn_ep1 80000
+1792863280 1180.2 592236 snn_ep1 80000
+1792863290 1190.2 592236 snn_ep1 80000
+1792863300 1200.2 592236 snn_ep1 80000
+1792863310 1210.2 592236 snn_ep1 80000
+1792863320 1220.2 592236 snn_ep1 90000
+1792863330 1230.2 592236 snn_ep1 90000
+1792863340 1240.2 592236 snn_ep1 90000
+1792863350 1250.2 592236 snn_ep1 90000
+1792863360 1260.2 592236 snn_ep1 90000
+1792863370 1270.2 592236 snn_ep1 90000
+1792863380 1280.2 592236 snn_ep1 90000
+1792863390 1290.2 592236 snn_ep1 90000
+1792863400 1300.2 592236 snn_ep1 90000
+1792863410 1310.2 592236 snn_ep1 90000
+1792863420 1320.2 592236 snn_ep1 90000
+1792863430 1330.2 592236 snn_ep1 90000
+1792863440 1340.2 592236 snn_ep1 90000
+1792863450 1350.2 592236 snn_ep1 100000
+1792863460 1360.2 592236 snn_ep1 100000
+1792863470 1370.2 592240 snn_ep1 100000
+1792863480 1380.2 592240 snn_ep1 100000
+1792863490 1390.2 592240 snn_ep1 100000
+1792863500 1400.2 592240 snn_ep1 100000
+1792863510 1410.2 592240 snn_ep1 100000
+1792863520 1420.2 592240 snn_ep1 100000
+1792863530 1430.2 592240 snn_ep1 100000
+1792863540 1440.2 592240 snn_ep1 100000
+1792863550 1450.2 592240 snn_ep1 100000
+1792863560 1460.2 592240 snn_ep1 100000
+1792863570 1470.2 592240 snn_ep1 110000
+1792863580 1480.2 592240 snn_ep1 110000
+1792863590 1490.2 592240 snn_ep1 110000
+1792863600 1500.2 592240 snn_ep1 110000
+1792863610 1510.2 592240 snn_ep1 110000
+1792863620 1520.2 592240 snn_ep1 110000
+1792863630 1530.2 592240 snn_ep1 110000
+1792863640 1540.2 592240 snn_ep1 110000
+1792863650 1550.3 592244 snn_ep1 110000
+1792863660 1560.3 592244 snn_ep1 110000
+1792863670 1570.3 592244 snn_ep1 110000
+1792863680 1580.3 592244 snn_ep1 110000
+1792863690 1590.3 592244 snn_ep1 110000
+1792863700 1600.3 592244 snn_ep1 120000
+1792863710 1610.3 592244 snn_ep1 120000
+1792863720 1620.3 592244 snn_ep1 120000
+1792863730 1630.3 592244 snn_ep1 120000
+1792863740 1640.3 592244 snn_ep1 120000
+1792863750 1650.3 592244 snn_ep1 120000
+1792863760 1660.3 592244 snn_ep1 120000
+1792863770 1670.3 592244 snn_ep1 120000
+1792863780 1680.3 592244 snn_ep1 120000
+1792863790 1690.3 592244 snn_ep1 120000
+1792863800 1700.3 592244 snn_ep1 120000
+1792863810 1710.3 592244 snn_ep1 120000
+1792863820 1720.3 592244 snn_ep1 130000
+1792863830 1730.3 592248 snn_ep1 130000
+1792863840 1740.3 592248 snn_ep1 130000
+1792863850 1750.3 592248 snn_ep1 130000
+1792863860 1760.3 592248 snn_ep1 130000
+1792863870 1770.3 592248 snn_ep1 130000
+1792863880 1780.3 592248 snn_ep1 130000
+1792863890 1790.3 592248 snn_ep1 130000
+1792863900 1800.3 592248 snn_ep1 130000
+1792863910 1810.3 592248 snn_ep1 130000
+1792863920 1820.3 592248 snn_ep1 130000
+1792863930 1830.3 592248 snn_ep1 130000
+1792863940 1840.3 592248 snn_ep1 140000
+1792863950 1850.3 592248 snn_ep1 140000
+1792863960 1860.3 592248 snn_ep1 140000
+1792863970 1870.3 592248 snn_ep1 140000
+1792863980 1880.3 592248 snn_ep1 140000
+1792863990 1890.3 592248 snn_ep1 140000
+1792864000 1900.3 592248 snn_ep1 140000
+1792864010 1910.3 592248 snn_ep1 140000
+1792864020 1920.3 592248 snn_ep1 140000
+1792864030 1930.3 592248 snn_ep1 140000
+1792864040 1940.3 592248 snn_ep1 140000
+1792864050 1950.3 592248 snn_ep1 140000
+1792864060 1960.3 592248 snn_ep1 150000
+1792864070 1970.3 592248 snn_ep1 150000
+1792864080 1980.3 592248 snn_ep1 150000
+1792864090 1990.3 592248 snn_ep1 150000
+1792864100 2000.3 592248 snn_ep1 150000
+1792864110 2010.3 592248 snn_ep1 150000
+1792864120 2020.3 592248 snn_ep1 150000
+1792864130 2030.3 592248 snn_ep1 150000
+1792864140 2040.3 592248 snn_ep1 150000
+1792864150 2050.3 592248 snn_ep1 150000
+1792864160 2060.3 592248 snn_ep1 150000
+1792864170 2070.3 592248 snn_ep1 150000
+1792864180 2080.3 592248 snn_ep1 150000
+1792864190 2090.3 592248 snn_ep1 160000
+1792864200 2100.3 592248 snn_ep1 160000
+1792864210 2110.3 592248 snn_ep1 160000
+1792864220 2120.3 592248 snn_ep1 160000
+1792864230 2130.3 592248 snn_ep1 160000
+1792864240 2140.3 592248 snn_ep1 160000
+1792864250 2150.3 592248 snn_ep1 160000
+1792864260 2160.3 592248 snn_ep1 160000
+1792864270 2170.3 592248 snn_ep1 160000
+1792864280 2180.3 592248 snn_ep1 160000
+1792864290 2190.3 592248 snn_ep1 160000
+1792864300 2200.3 592248 snn_ep1 160000
+1792864310 2210.3 592248 snn_ep1 170000
+1792864320 2220.3 592248 snn_ep1 170000
+1792864330 2230.3 592248 snn_ep1 170000
+1792864340 2240.3 592248 snn_ep1 170000
+1792864350 2250.3 592248 snn_ep1 170000
+1792864360 2260.3 592248 snn_ep1 170000
+1792864370 2270.3 592248 snn_ep1 170000
+1792864380 2280.3 592248 snn_ep1 170000
+1792864390 2290.3 592248 snn_ep1 170000
+1792864400 2300.3 592248 snn_ep1 170000
+1792864410 2310.3 592248 snn_ep1 170000
+1792864420 2320.3 592248 snn_ep1 180000
+1792864430 2330.3 592248 snn_ep1 180000
+1792864440 2340.3 592248 snn_ep1 180000
+1792864450 2350.3 592248 snn_ep1 180000
+1792864460 2360.3 592248 snn_ep1 180000
+1792864470 2370.3 592248 snn_ep1 180000
+1792864480 2380.3 592248 snn_ep1 180000
+1792864490 2390.3 592248 snn_ep1 180000
+1792864500 2400.3 592248 snn_ep1 180000
+1792864510 2410.3 592248 snn_ep1 180000
+1792864520 2420.3 592248 snn_ep1 180000
+1792864530 2430.3 592248 snn_ep1 180000
+1792864540 2440.3 592248 snn_ep1 190000
+1792864550 2450.3 592248 snn_ep1 190000
+1792864560 2460.3 592248 snn_ep1 190000
+1792864570 2470.3 592248 snn_ep1 190000
+1792864580 2480.3 592248 snn_ep1 190000
+1792864590 2490.3 592248 snn_ep1 190000
+1792864600 2500.3 592248 snn_ep1 190000
+1792864610 2510.3 592248 snn_ep1 190000
+1792864620 2520.3 592248 snn_ep1 190000
+1792864630 2530.3 592248 snn_ep1 190000
+1792864640 2540.3 592248 snn_ep1 200000
+1792864650 2550.3 592248 snn_ep1 200000
+1792864660 2560.3 592248 snn_ep1 200000
+1792864670 2570.3 592248 snn_ep1 200000
+1792864680 2580.3 592248 snn_ep1 200000
+1792864690 2590.3 592248 snn_ep1 200000
+1792864700 2600.3 592248 snn_ep1 200000
+1792864710 2610.3 592248 snn_ep1 200000
+1792864720 2620.3 592248 snn_ep1 200000
+1792864730 2630.3 592248 snn_ep1 200000
+1792864740 2640.3 592248 snn_ep1 200000
+1792864750 2650.3 592248 snn_ep1 210000
+1792864760 2660.3 592248 snn_ep1 210000
+1792864770 2670.3 592248 snn_ep1 210000
+1792864780 2680.3 592248 snn_ep1 210000
+1792864790 2690.3 592248 snn_ep1 210000
+1792864800 2700.3 592248 snn_ep1 210000
+1792864810 2710.3 592248 snn_ep1 210000
+1792864820 2720.3 592248 snn_ep1 210000
+1792864830 2730.3 592248 snn_ep1 210000
+1792864840 2740.3 592248 snn_ep1 210000
+1792864850 2750.3 592248 snn_ep1 210000
+1792864860 2760.3 592248 snn_ep1 210000
+1792864870 2770.3 592248 snn_ep1 220000
+1792864880 2780.3 592248 snn_ep1 220000
+1792864890 2790.3 592248 snn_ep1 220000
+1792864900 2800.3 592248 snn_ep1 220000
+1792864910 2810.3 592248 snn_ep1 220000
+1792864920 2820.3 592248 snn_ep1 220000
+1792864930 2830.3 592248 snn_ep1 220000
+1792864940 2840.3 592248 snn_ep1 220000
+1792864950 2850.3 592248 snn_ep1 220000
+1792864960 2860.3 592248 snn_ep1 220000
+1792864970 2870.3 592248 snn_ep1 220000
+1792864980 2880.3 592248 snn_ep1 220000
+1792864990 2890.3 592248 snn_ep1 220000
+1792865000 2900.3 592248 snn_ep1 230000
+1792865011 2910.4 592248 snn_ep1 230000
+1792865021 2920.4 592248 snn_ep1 230000
+1792865031 2930.4 592248 snn_ep1 230000
+1792865041 2940.4 592248 snn_ep1 230000
+1792865051 2950.4 592248 snn_ep1 230000
+1792865061 2960.4 592248 snn_ep1 230000
+1792865071 2970.4 592248 snn_ep1 230000
+1792865081 2980.4 592248 snn_ep1 230000
+1792865091 2990.4 592248 snn_ep1 230000
+1792865101 3000.4 592248 snn_ep1 230000
+1792865111 3010.4 592248 snn_ep1 230000
+1792865121 3020.4 592248 snn_ep1 240000
+1792865131 3030.4 592248 snn_ep1 240000
+1792865141 3040.4 592248 snn_ep1 240000
+1792865151 3050.4 592248 snn_ep1 240000
+1792865161 3060.4 592248 snn_ep1 240000
+1792865171 3070.4 592248 snn_ep1 240000
+1792865181 3080.4 592248 snn_ep1 240000
+1792865191 3090.4 592248 snn_ep1 240000
+1792865201 3100.4 592248 snn_ep1 240000
+1792865211 3110.4 592248 snn_ep1 240000
+1792865221 3120.4 592248 snn_ep1 240000
+1792865231 3130.4 592248 snn_ep1 240000
+1792865241 3140.4 592248 snn_ep1 250000
+1792865251 3150.4 592248 snn_ep1 250000
+1792865261 3160.4 592248 snn_ep1 250000
+1792865271 3170.4 592248 snn_ep1 250000
+1792865281 3180.4 592248 snn_ep1 250000
+1792865291 3190.4 592248 snn_ep1 250000
+1792865301 3200.4 592248 snn_ep1 250000
+1792865311 3210.4 592248 snn_ep1 250000
+1792865321 3220.4 592248 snn_ep1 250000
+1792865331 3230.4 592248 snn_ep1 250000
+1792865341 3240.4 592248 snn_ep1 250000
+1792865351 3250.4 592248 snn_ep1 250000
+1792865361 3260.4 592248 snn_ep1 250000
+1792865371 3270.4 592248 snn_ep1 260000
+1792865381 3280.4 592248 snn_ep1 260000
+1792865391 3290.4 592248 snn_ep1 260000
+1792865401 3300.4 592248 snn_ep1 260000
+1792865411 3310.4 592248 snn_ep1 260000
+1792865421 3320.4 592248 snn_ep1 260000
+1792865431 3330.4 592248 snn_ep1 260000
+1792865441 3340.4 592248 snn_ep1 260000
+1792865451 3350.4 592248 snn_ep1 260000
+1792865461 3360.4 592248 snn_ep1 260000
+1792865471 3370.4 592248 snn_ep1 260000
+1792865481 3380.4 592248 snn_ep1 260000
+1792865491 3390.4 592248 snn_ep1 270000
+1792865501 3400.4 592248 snn_ep1 270000
+1792865511 3410.4 592248 snn_ep1 270000
+1792865521 3420.4 592248 snn_ep1 270000
+1792865531 3430.4 592248 snn_ep1 270000
+1792865541 3440.4 592248 snn_ep1 270000
+1792865551 3450.4 592248 snn_ep1 270000
+1792865561 3460.4 592248 snn_ep1 270000
+1792865571 3470.4 592248 snn_ep1 270000
+1792865581 3480.4 592248 snn_ep1 270000
+1792865591 3490.4 592248 snn_ep1 270000
+1792865601 3500.4 592248 snn_ep1 270000
+1792865611 3510.4 592248 snn_ep1 280000
+1792865621 3520.4 592248 snn_ep1 280000
+1792865631 3530.4 592248 snn_ep1 280000
+1792865641 3540.4 592248 snn_ep1 280000
+1792865651 3550.4 592248 snn_ep1 280000
+1792865661 3560.4 592248 snn_ep1 280000
+1792865671 3570.4 592248 snn_ep1 280000
+1792865681 3580.4 592248 snn_ep1 280000
+1792865691 3590.4 592248 snn_ep1 280000
+1792865701 3600.4 592248 snn_ep1 280000
+1792865711 3610.4 592248 snn_ep1 280000
+1792865721 3620.4 592248 snn_ep1 290000
+1792865731 3630.4 592248 snn_ep1 290000
+1792865741 3640.4 592248 snn_ep1 290000
+1792865751 3650.4 592248 snn_ep1 290000
+1792865761 3660.4 592248 snn_ep1 290000
+1792865771 3670.4 592248 snn_ep1 290000
+1792865781 3680.4 592248 snn_ep1 290000
+1792865791 3690.4 592248 snn_ep1 290000
+1792865801 3700.4 592248 snn_ep1 290000
+1792865811 3710.4 592248 snn_ep1 290000
+1792865821 3720.4 592248 snn_ep1 290000
+1792865831 3730.4 592248 snn_ep1 290000
+1792865841 3740.4 592248 snn_ep1 300000
+1792865851 3750.4 592248 snn_ep1 300000
+1792865861 3760.4 592248 snn_ep1 300000
+1792865871 3770.4 592248 snn_ep1 300000
+1792865881 3780.4 592248 snn_ep1 300000
+1792865891 3790.4 592248 snn_ep1 300000
+1792865901 3800.4 592248 snn_ep1 300000
+1792865911 3810.4 592248 snn_ep1 300000
+1792865921 3820.4 592248 snn_ep1 300000
+1792865931 3830.4 592248 snn_ep1 300000
+1792865941 3840.4 592248 snn_ep1 300000
+1792865951 3850.4 592248 snn_ep1 300000
+1792865961 3860.4 592248 snn_ep1 310000
+1792865971 3870.4 592248 snn_ep1 310000
+1792865981 3880.4 592248 snn_ep1 310000
+1792865991 3890.4 592248 snn_ep1 310000
+1792866001 3900.4 592248 snn_ep1 310000
+1792866011 3910.4 592248 snn_ep1 310000
+1792866021 3920.4 592248 snn_ep1 310000
+1792866031 3930.4 592248 snn_ep1 310000
+1792866041 3940.4 592248 snn_ep1 310000
+1792866051 3950.4 592248 snn_ep1 310000
+1792866061 3960.4 592248 snn_ep1 310000
+1792866071 3970.4 592248 snn_ep1 310000
+1792866081 3980.4 592248 snn_ep1 320000
+1792866091 3990.4 592248 snn_ep1 320000
+1792866101 4000.4 592248 snn_ep1 320000
+1792866111 4010.4 592248 snn_ep1 320000
+1792866121 4020.4 592248 snn_ep1 320000
+1792866131 4030.4 592248 snn_ep1 320000
+1792866141 4040.4 592248 snn_ep1 320000
+1792866151 4050.4 592248 snn_ep1 320000
+1792866161 4060.4 592248 snn_ep1 320000
+1792866171 4070.4 592248 snn_ep1 320000
+1792866181 4080.4 592248 snn_ep1 320000
+1792866191 4090.4 592248 snn_ep1 320000
+1792866201 4100.4 592248 snn_ep1 330000
+1792866211 4110.4 592248 snn_ep1 330000
+1792866221 4120.4 592248 snn_ep1 330000
+1792866231 4130.4 592248 snn_ep1 330000
+1792866241 4140.4 592248 snn_ep1 330000
+1792866251 4150.4 592248 snn_ep1 330000
+1792866261 4160.4 592248 snn_ep1 330000
+1792866271 4170.4 592248 snn_ep1 330000
+1792866281 4180.4 592248 snn_ep1 330000
+1792866291 4190.4 592248 snn_ep1 330000
+1792866301 4200.4 592248 snn_ep1 330000
+1792866311 4210.4 592248 snn_ep1 330000
+1792866321 4220.4 592248 snn_ep1 340000
+1792866331 4230.5 592248 snn_ep1 340000
+1792866341 4240.5 592248 snn_ep1 340000
+1792866351 4250.5 592248 snn_ep1 340000
+1792866361 4260.5 592248 snn_ep1 340000
+1792866371 4270.5 592248 snn_ep1 340000
+1792866381 4280.5 592248 snn_ep1 340000
+1792866391 4290.5 592248 snn_ep1 340000
+1792866401 4300.5 592252 snn_ep1 340000
+1792866411 4310.5 592252 snn_ep1 340000
+1792866421 4320.5 592252 snn_ep1 340000
+1792866431 4330.5 592252 snn_ep1 340000
+1792866441 4340.5 592252 snn_ep1 350000
+1792866451 4350.5 592252 snn_ep1 350000
+1792866461 4360.5 592252 snn_ep1 350000
+1792866471 4370.5 592252 snn_ep1 350000
+1792866481 4380.5 592252 snn_ep1 350000
+1792866491 4390.5 592252 snn_ep1 350000
+1792866501 4400.5 592252 snn_ep1 350000
+1792866511 4410.5 592252 snn_ep1 350000
+1792866521 4420.5 592252 snn_ep1 350000
+1792866531 4430.5 592252 snn_ep1 350000
+1792866541 4440.5 592252 snn_ep1 350000
+1792866551 4450.5 592252 snn_ep1 360000
+1792866561 4460.5 592252 snn_ep1 360000
+1792866571 4470.5 592252 snn_ep1 360000
+1792866581 4480.5 592252 snn_ep1 360000
+1792866591 4490.5 592252 snn_ep1 360000
+1792866601 4500.5 592252 snn_ep1 360000
+1792866611 4510.5 592252 snn_ep1 360000
+1792866621 4520.5 592252 snn_ep1 360000
+1792866631 4530.5 592252 snn_ep1 360000
+1792866641 4540.5 592252 snn_ep1 360000
+1792866651 4550.5 592252 snn_ep1 360000
+1792866661 4560.5 592252 snn_ep1 360000
+1792866671 4570.5 592252 snn_ep1 370000
+1792866681 4580.5 592252 snn_ep1 370000
+1792866691 4590.5 592252 snn_ep1 370000
+1792866701 4600.5 592252 snn_ep1 370000
+1792866711 4610.5 592252 snn_ep1 370000
+1792866721 4620.5 592252 snn_ep1 370000
+1792866731 4630.5 592252 snn_ep1 370000
+1792866741 4640.5 592252 snn_ep1 370000
+1792866751 4650.5 592252 snn_ep1 370000
+1792866761 4660.5 592252 snn_ep1 370000
+1792866771 4670.5 592252 snn_ep1 370000
+1792866781 4680.5 592252 snn_ep1 370000
+1792866791 4690.5 592252 snn_ep1 380000
+1792866801 4700.5 592252 snn_ep1 380000
+1792866811 4710.5 592252 snn_ep1 380000
+1792866821 4720.5 592252 snn_ep1 380000
+1792866831 4730.5 592252 snn_ep1 380000
+1792866841 4740.5 592252 snn_ep1 380000
+1792866851 4750.5 592252 snn_ep1 380000
+1792866861 4760.5 592252 snn_ep1 380000
+1792866871 4770.5 592252 snn_ep1 380000
+1792866881 4780.5 592252 snn_ep1 380000
+1792866891 4790.5 592252 snn_ep1 380000
+1792866901 4800.5 592252 snn_ep1 380000
+1792866911 4810.5 592252 snn_ep1 390000
+1792866921 4820.5 592252 snn_ep1 390000
+1792866931 4830.5 592252 snn_ep1 390000
+1792866941 4840.5 592252 snn_ep1 390000
+1792866951 4850.5 592252 snn_ep1 390000
+1792866961 4860.5 592252 snn_ep1 390000
+1792866971 4870.5 592252 snn_ep1 390000
+1792866981 4880.5 592252 snn_ep1 390000
+1792866991 4890.5 592252 snn_ep1 390000
+1792867001 4900.5 592252 snn_ep1 390000
+1792867011 4910.5 592252 snn_ep1 390000
+1792867021 4920.5 592252 snn_ep1 390000
+1792867031 4930.5 592252 snn_ep1 400000
+1792867041 4940.5 592252 snn_ep1 400000
+1792867051 4950.5 592252 snn_ep1 400000
+1792867061 4960.5 592252 snn_ep1 400000
+1792867071 4970.5 592252 snn_ep1 400000
+1792867081 4980.5 592252 snn_ep1 400000
+1792867091 4990.5 592252 snn_ep1 400000
+1792867101 5000.5 592252 snn_ep1 400000
+1792867111 5010.5 592252 snn_ep1 400000
+1792867121 5020.5 592252 snn_ep1 400000
+1792867131 5030.5 592252 snn_ep1 400000
+1792867141 5040.5 592252 snn_ep1 410000
+1792867151 5050.5 592252 snn_ep1 410000
+1792867161 5060.5 592252 snn_ep1 410000
+1792867171 5070.5 592252 snn_ep1 410000
+1792867181 5080.5 592252 snn_ep1 410000
+1792867191 5090.5 592252 snn_ep1 410000
+1792867201 5100.5 592252 snn_ep1 410000
+1792867211 5110.5 592252 snn_ep1 410000
+1792867221 5120.5 592252 snn_ep1 410000
+1792867231 5130.5 592252 snn_ep1 410000
+1792867241 5140.5 592252 snn_ep1 410000
+1792867251 5150.5 592252 snn_ep1 410000
+1792867261 5160.5 592252 snn_ep1 420000
+1792867271 5170.5 592252 snn_ep1 420000
+1792867281 5180.5 592252 snn_ep1 420000
+1792867291 5190.5 592252 snn_ep1 420000
+1792867301 5200.5 592252 snn_ep1 420000
+1792867311 5210.5 592252 snn_ep1 420000
+1792867321 5220.5 592252 snn_ep1 420000
+1792867331 5230.5 592252 snn_ep1 420000
+1792867341 5240.5 592252 snn_ep1 420000
+1792867351 5250.5 592252 snn_ep1 420000
+1792867361 5260.5 592252 snn_ep1 420000
+1792867371 5270.5 592252 snn_ep1 420000
+1792867381 5280.5 592252 snn_ep1 430000
+1792867391 5290.5 592252 snn_ep1 430000
+1792867401 5300.5 592252 snn_ep1 430000
+1792867411 5310.5 592252 snn_ep1 430000
+1792867421 5320.5 592252 snn_ep1 430000
+1792867431 5330.5 592252 snn_ep1 430000
+1792867441 5340.5 592252 snn_ep1 430000
+1792867451 5350.5 592252 snn_ep1 430000
+1792867461 5360.5 592252 snn_ep1 430000
+1792867471 5370.5 592252 snn_ep1 430000
+1792867481 5380.5 592252 snn_ep1 430000
+1792867491 5390.5 592252 snn_ep1 430000
+1792867501 5400.5 592252 snn_ep1 440000
+1792867511 5410.5 592252 snn_ep1 440000
+1792867521 5420.5 592252 snn_ep1 440000
+1792867531 5430.5 592252 snn_ep1 440000
+1792867541 5440.5 592252 snn_ep1 440000
+1792867551 5450.5 592252 snn_ep1 440000
+1792867561 5460.5 592252 snn_ep1 440000
+1792867571 5470.5 592252 snn_ep1 440000
+1792867581 5480.5 592252 snn_ep1 440000
+1792867591 5490.6 592252 snn_ep1 440000
+1792867601 5500.6 592252 snn_ep1 440000
+1792867611 5510.6 592252 snn_ep1 440000
+1792867621 5520.6 592252 snn_ep1 450000
+1792867631 5530.6 592252 snn_ep1 450000
+1792867641 5540.6 592252 snn_ep1 450000
+1792867651 5550.6 592252 snn_ep1 450000
+1792867661 5560.6 592252 snn_ep1 450000
+1792867671 5570.6 592252 snn_ep1 450000
+1792867681 5580.6 592252 snn_ep1 450000
+1792867691 5590.6 592252 snn_ep1 450000
+1792867701 5600.6 592252 snn_ep1 450000
+1792867711 5610.6 592252 snn_ep1 450000
+1792867721 5620.6 592252 snn_ep1 450000
+1792867731 5630.6 592252 snn_ep1 460000
+1792867741 5640.6 592252 snn_ep1 460000
+1792867751 5650.6 592252 snn_ep1 460000
+1792867761 5660.6 592252 snn_ep1 460000
+1792867771 5670.6 592252 snn_ep1 460000
+1792867781 5680.6 592252 snn_ep1 460000
+1792867791 5690.6 592252 snn_ep1 460000
+1792867801 5700.6 592252 snn_ep1 460000
+1792867811 5710.6 592252 snn_ep1 460000
+1792867821 5720.6 592252 snn_ep1 460000
+1792867831 5730.6 592252 snn_ep1 460000
+1792867841 5740.6 592252 snn_ep1 460000
+1792867851 5750.6 592252 snn_ep1 470000
+1792867861 5760.6 592252 snn_ep1 470000
+1792867871 5770.6 592252 snn_ep1 470000
+1792867881 5780.6 592252 snn_ep1 470000
+1792867891 5790.6 592252 snn_ep1 470000
+1792867901 5800.6 592252 snn_ep1 470000
+1792867911 5810.6 592252 snn_ep1 470000
+1792867921 5820.6 592252 snn_ep1 470000
+1792867931 5830.6 592252 snn_ep1 470000
+1792867941 5840.6 592252 snn_ep1 470000
+1792867951 5850.6 592252 snn_ep1 470000
+1792867961 5860.6 592252 snn_ep1 480000
+1792867971 5870.6 592252 snn_ep1 480000
+1792867981 5880.6 592252 snn_ep1 480000
+1792867991 5890.6 592252 snn_ep1 480000
+1792868001 5900.6 592252 snn_ep1 480000
+1792868011 5910.6 592252 snn_ep1 480000
+1792868021 5920.6 592252 snn_ep1 480000
+1792868031 5930.6 592252 snn_ep1 480000
+1792868041 5940.6 592252 snn_ep1 480000
+1792868051 5950.6 592252 snn_ep1 480000
+1792868061 5960.6 592252 snn_ep1 480000
+1792868071 5970.6 592252 snn_ep1 490000
+1792868081 5980.6 592252 snn_ep1 490000
+1792868091 5990.6 592252 snn_ep1 490000
+1792868101 6000.6 592252 snn_ep1 490000
+1792868111 6010.6 592252 snn_ep1 490000
+1792868121 6020.6 592252 snn_ep1 490000
+1792868131 6030.6 592252 snn_ep1 490000
+1792868141 6040.6 592252 snn_ep1 490000
+1792868151 6050.6 592252 snn_ep1 490000
+1792868161 6060.6 592252 snn_ep1 490000
+1792868171 6070.6 592252 snn_ep1 490000
+1792868181 6080.6 592252 snn_ep1 500000
+1792868191 6090.6 592252 snn_ep1 500000
+1792868201 6100.6 592252 snn_ep1 500000
+1792868211 6110.6 592252 snn_ep1 500000
+1792868221 6120.6 592252 snn_ep1 500000
+1792868231 6130.6 592252 snn_ep1 500000
+1792868241 6140.6 592252 snn_ep1 500000
+1792868251 6150.6 592252 snn_ep1 500000
+1792868261 6160.6 592252 snn_ep1 500000
+1792868271 6170.6 592252 snn_ep1 500000
+1792868281 6180.6 592252 snn_ep1 500000
+1792868291 6190.6 592252 snn_ep1 500000
+1792868301 6200.6 592252 snn_ep1 510000
+1792868311 6210.6 592252 snn_ep1 510000
+1792868321 6220.6 592252 snn_ep1 510000
+1792868331 6230.6 592252 snn_ep1 510000
+1792868341 6240.6 592252 snn_ep1 510000
+1792868351 6250.6 592252 snn_ep1 510000
+1792868361 6260.6 592252 snn_ep1 510000
+1792868371 6270.6 592252 snn_ep1 510000
+1792868381 6280.6 592252 snn_ep1 510000
+1792868391 6290.6 592252 snn_ep1 510000
+1792868401 6300.6 592252 snn_ep1 510000
+1792868411 6310.6 592252 snn_ep1 520000
+1792868421 6320.6 592252 snn_ep1 520000
+1792868431 6330.6 592252 snn_ep1 520000
+1792868441 6340.6 592252 snn_ep1 520000
+1792868451 6350.6 592252 snn_ep1 520000
+1792868461 6360.6 592252 snn_ep1 520000
+1792868471 6370.6 592252 snn_ep1 520000
+1792868481 6380.6 592252 snn_ep1 520000
+1792868491 6390.6 592252 snn_ep1 520000
+1792868501 6400.6 592252 snn_ep1 520000
+1792868511 6410.6 592252 snn_ep1 520000
+1792868521 6420.6 592252 snn_ep1 530000
+1792868531 6430.6 592252 snn_ep1 530000
+1792868541 6440.6 592252 snn_ep1 530000
+1792868551 6450.6 592252 snn_ep1 530000
+1792868561 6460.6 592252 snn_ep1 530000
+1792868571 6470.6 592252 snn_ep1 530000
+1792868581 6480.6 592252 snn_ep1 530000
+1792868591 6490.6 592252 snn_ep1 530000
+1792868601 6500.6 592252 snn_ep1 530000
+1792868611 6510.6 592252 snn_ep1 530000
+1792868621 6520.6 592252 snn_ep1 530000
+1792868631 6530.6 592252 snn_ep1 540000
+1792868641 6540.6 592252 snn_ep1 540000
+1792868651 6550.6 592252 snn_ep1 540000
+1792868661 6560.6 592252 snn_ep1 540000
+1792868671 6570.6 592252 snn_ep1 540000
+1792868681 6580.6 592252 snn_ep1 540000
+1792868691 6590.6 592252 snn_ep1 540000
+1792868701 6600.6 592252 snn_ep1 540000
+1792868711 6610.6 592252 snn_ep1 540000
+1792868721 6620.6 592252 snn_ep1 540000
+1792868731 6630.6 592252 snn_ep1 540000
+1792868741 6640.6 592252 snn_ep1 540000
+1792868751 6650.6 592252 snn_ep1 550000
+1792868761 6660.6 592252 snn_ep1 550000
+1792868771 6670.6 592252 snn_ep1 550000
+1792868781 6680.6 592252 snn_ep1 550000
+1792868791 6690.6 592252 snn_ep1 550000
+1792868801 6700.6 592252 snn_ep1 550000
+1792868811 6710.6 592252 snn_ep1 550000
+1792868821 6720.6 592252 snn_ep1 550000
+1792868831 6730.6 592252 snn_ep1 550000
+1792868841 6740.6 592252 snn_ep1 550000
+1792868851 6750.6 592252 snn_ep1 550000
+1792868861 6760.6 592252 snn_ep1 560000
+1792868871 6770.6 592252 snn_ep1 560000
+1792868881 6780.6 592252 snn_ep1 560000
+1792868891 6790.6 592252 snn_ep1 560000
+1792868901 6800.6 592252 snn_ep1 560000
+1792868911 6810.6 592252 snn_ep1 560000
+1792868921 6820.6 592252 snn_ep1 560000
+1792868931 6830.6 592252 snn_ep1 560000
+1792868941 6840.6 592252 snn_ep1 560000
+1792868951 6850.6 592252 snn_ep1 560000
+1792868961 6860.6 592252 snn_ep1 560000
+1792868971 6870.6 592252 snn_ep1 560000
+1792868981 6880.6 592252 snn_ep1 570000
+1792868991 6890.6 592252 snn_ep1 570000
+1792869001 6900.6 592252 snn_ep1 570000
+1792869011 6910.6 592252 snn_ep1 570000
+1792869021 6920.6 592252 snn_ep1 570000
+1792869031 6930.6 592252 snn_ep1 570000
+1792869041 6940.6 592252 snn_ep1 570000
+1792869051 6950.6 592252 snn_ep1 570000
+1792869061 6960.6 592252 snn_ep1 570000
+1792869071 6970.6 592252 snn_ep1 570000
+1792869081 6980.6 592252 snn_ep1 570000
+1792869091 6990.6 592252 snn_ep1 570000
+1792869101 7000.6 592256 snn_ep1 580000
+1792869111 7010.6 592256 snn_ep1 580000
+1792869121 7020.6 592256 snn_ep1 580000
+1792869131 7030.6 592256 snn_ep1 580000
+1792869141 7040.6 592256 snn_ep1 580000
+1792869151 7050.6 592256 snn_ep1 580000
+1792869161 7060.6 592256 snn_ep1 580000
+1792869171 7070.6 592256 snn_ep1 580000
+1792869181 7080.6 592256 snn_ep1 580000
+1792869191 7090.6 592256 snn_ep1 580000
+1792869201 7100.6 592256 snn_ep1 580000
+1792869211 7110.6 592256 snn_ep1 580000
+1792869221 7120.6 592256 snn_ep1 590000
+1792869231 7130.6 592256 snn_ep1 590000
+1792869241 7140.6 592256 snn_ep1 590000
+1792869251 7150.6 592256 snn_ep1 590000
+1792869261 7160.6 592256 snn_ep1 590000
+1792869271 7170.6 592256 snn_ep1 590000
+1792869281 7180.6 592256 snn_ep1 590000
+1792869291 7190.6 592256 snn_ep1 590000
+1792869301 7200.6 592256 snn_ep1 590000
+1792869311 7210.6 592256 snn_ep1 590000
+1792869321 7220.6 592256 snn_ep1 590000
+1792869331 7230.6 592256 snn_ep1 590000
+1792869341 7240.6 592220 snn_ep2 600000
+1792869351 7250.6 592220 snn_ep2 600000
+1792869361 7260.6 592220 snn_ep2 600000
+1792869371 7270.6 592220 snn_ep2 600000
+1792869381 7280.6 592220 snn_ep2 600000
+1792869391 7290.6 592220 snn_ep2 600000
+1792869401 7300.6 592220 snn_ep2 600000
+1792869411 7310.6 592220 snn_ep2 600000
+1792869421 7320.6 592220 snn_ep2 600000
+1792869431 7330.6 592220 snn_ep2 600000
+1792869441 7340.6 592220 snn_ep2 600000
+1792869451 7350.6 592220 snn_ep2 600000
+1792869461 7360.6 592220 snn_ep2 10000
+1792869471 7370.6 592220 snn_ep2 10000
+1792869481 7380.6 592220 snn_ep2 10000
+1792869491 7390.6 592220 snn_ep2 10000
+1792869501 7400.6 592220 snn_ep2 10000
+1792869511 7410.6 592220 snn_ep2 10000
+1792869521 7420.6 592220 snn_ep2 10000
+1792869531 7430.7 592220 snn_ep2 10000
+1792869541 7440.7 592220 snn_ep2 10000
+1792869551 7450.7 592220 snn_ep2 10000
+1792869561 7460.7 592220 snn_ep2 10000
+1792869571 7470.7 592220 snn_ep2 10000
+1792869581 7480.7 592220 snn_ep2 20000
+1792869591 7490.7 592220 snn_ep2 20000
+1792869601 7500.7 592220 snn_ep2 20000
+1792869611 7510.7 592220 snn_ep2 20000
+1792869621 7520.7 592220 snn_ep2 20000
+1792869631 7530.7 592220 snn_ep2 20000
+1792869641 7540.7 592220 snn_ep2 20000
+1792869651 7550.7 592220 snn_ep2 20000
+1792869661 7560.7 592220 snn_ep2 20000
+1792869671 7570.7 592220 snn_ep2 20000
+1792869681 7580.7 592220 snn_ep2 20000
+1792869691 7590.7 592220 snn_ep2 20000
+1792869701 7600.7 592220 snn_ep2 20000
+1792869711 7610.7 592220 snn_ep2 30000
+1792869721 7620.7 592220 snn_ep2 30000
+1792869731 7630.7 592220 snn_ep2 30000
+1792869741 7640.7 592220 snn_ep2 30000
+1792869751 7650.7 592220 snn_ep2 30000
+1792869761 7660.7 592220 snn_ep2 30000
+1792869771 7670.7 592220 snn_ep2 30000
+1792869781 7680.7 592220 snn_ep2 30000
+1792869791 7690.7 592220 snn_ep2 30000
+1792869801 7700.7 592220 snn_ep2 30000
+1792869811 7710.7 592220 snn_ep2 30000
+1792869821 7720.7 592220 snn_ep2 30000
+1792869831 7730.7 592220 snn_ep2 40000
+1792869844 7743.7 592220 snn_ep2 40000
+1792869854 7753.7 592220 snn_ep2 40000
+1792869864 7763.7 592220 snn_ep2 40000
+1792869874 7773.7 592220 snn_ep2 40000
+1792869884 7783.7 592220 snn_ep2 40000
+1792869894 7793.7 592220 snn_ep2 40000
+1792869904 7803.7 592220 snn_ep2 40000
+1792869914 7813.7 592220 snn_ep2 40000
+1792869924 7823.7 592220 snn_ep2 40000
+1792869934 7833.7 592220 snn_ep2 40000
+1792869944 7843.7 592220 snn_ep2 40000
+1792869954 7853.7 592220 snn_ep2 50000
+1792869964 7863.7 592220 snn_ep2 50000
+1792869974 7873.7 592220 snn_ep2 50000
+1792869984 7883.7 592220 snn_ep2 50000
+1792869994 7893.7 592220 snn_ep2 50000
+1792870004 7903.7 592220 snn_ep2 50000
+1792870014 7913.7 592220 snn_ep2 50000
+1792870024 7923.7 592220 snn_ep2 50000
+1792870034 7933.7 592220 snn_ep2 50000
+1792870044 7943.7 592220 snn_ep2 50000
+1792870054 7953.7 592220 snn_ep2 50000
+1792870064 7963.7 592220 snn_ep2 50000
+1792870074 7973.7 592220 snn_ep2 60000
+1792870084 7983.7 592220 snn_ep2 60000
+1792870094 7993.7 592220 snn_ep2 60000
+1792870104 8003.7 592220 snn_ep2 60000
+1792870114 8013.7 592220 snn_ep2 60000
+1792870124 8023.7 592220 snn_ep2 60000
+1792870134 8033.7 592220 snn_ep2 60000
+1792870144 8043.7 592220 snn_ep2 60000
+1792870154 8053.7 592220 snn_ep2 60000
+1792870164 8063.7 592220 snn_ep2 60000
+1792870174 8073.7 592220 snn_ep2 60000
+1792870184 8083.7 592220 snn_ep2 60000
+1792870194 8093.7 592220 snn_ep2 70000
+1792870204 8103.7 592220 snn_ep2 70000
+1792870214 8113.7 592220 snn_ep2 70000
+1792870224 8123.7 592220 snn_ep2 70000
+1792870234 8133.7 592220 snn_ep2 70000
+1792870244 8143.7 592220 snn_ep2 70000
+1792870254 8153.7 592220 snn_ep2 70000
+1792870264 8163.7 592220 snn_ep2 70000
+1792870274 8173.7 592220 snn_ep2 70000
+1792870284 8183.7 592220 snn_ep2 70000
+1792870294 8193.7 592220 snn_ep2 70000
+1792870304 8203.7 592220 snn_ep2 80000
+1792870314 8213.7 592220 snn_ep2 80000
+1792870324 8223.7 592220 snn_ep2 80000
+1792870334 8233.7 592220 snn_ep2 80000
+1792870344 8243.7 592220 snn_ep2 80000
+1792870354 8253.7 592220 snn_ep2 80000
+1792870364 8263.7 592220 snn_ep2 80000
+1792870374 8273.7 592220 snn_ep2 80000
+1792870384 8283.7 592220 snn_ep2 80000
+1792870394 8293.7 592220 snn_ep2 80000
+1792870404 8303.7 592220 snn_ep2 80000
+1792870414 8313.7 592220 snn_ep2 80000
+1792870424 8323.7 592220 snn_ep2 90000
+1792870434 8333.7 592220 snn_ep2 90000
+1792870444 8343.7 592220 snn_ep2 90000
+1792870454 8353.7 592220 snn_ep2 90000
+1792870464 8363.7 592220 snn_ep2 90000
+1792870474 8373.7 592220 snn_ep2 90000
+1792870484 8383.7 592220 snn_ep2 90000
+1792870494 8393.7 592220 snn_ep2 90000
+1792870504 8403.7 592220 snn_ep2 90000
+1792870514 8413.7 592220 snn_ep2 90000
+1792870524 8423.7 592220 snn_ep2 90000
+1792870534 8433.7 592220 snn_ep2 100000
+1792870544 8443.7 592220 snn_ep2 100000
+1792870554 8453.7 592220 snn_ep2 100000
+1792870564 8463.7 592220 snn_ep2 100000
+1792870574 8473.7 592220 snn_ep2 100000
+1792870584 8483.7 592220 snn_ep2 100000
+1792870594 8493.7 592220 snn_ep2 100000
+1792870604 8503.7 592220 snn_ep2 100000
+1792870614 8513.7 592220 snn_ep2 100000
+1792870624 8523.7 592220 snn_ep2 100000
+1792870634 8533.7 592220 snn_ep2 100000
+1792870644 8543.7 592220 snn_ep2 100000
+1792870654 8553.7 592220 snn_ep2 110000
+1792870664 8563.7 592220 snn_ep2 110000
+1792870674 8573.7 592220 snn_ep2 110000
+1792870684 8583.7 592220 snn_ep2 110000
+1792870694 8593.7 592220 snn_ep2 110000
+1792870704 8603.7 592220 snn_ep2 110000
+1792870714 8613.7 592220 snn_ep2 110000
+1792870724 8623.7 592220 snn_ep2 110000
+1792870734 8633.7 592220 snn_ep2 110000
+1792870744 8643.7 592220 snn_ep2 110000
+1792870754 8653.7 592220 snn_ep2 110000
+1792870764 8663.7 592220 snn_ep2 110000
+1792870774 8673.7 592220 snn_ep2 120000
+1792870784 8683.7 592220 snn_ep2 120000
+1792870794 8693.7 592220 snn_ep2 120000
+1792870804 8703.7 592220 snn_ep2 120000
+1792870814 8713.7 592220 snn_ep2 120000
+1792870824 8723.7 592220 snn_ep2 120000
+1792870834 8733.7 592220 snn_ep2 120000
+1792870844 8743.7 592220 snn_ep2 120000
+1792870854 8753.7 592220 snn_ep2 120000
+1792870864 8763.7 592220 snn_ep2 120000
+1792870874 8773.7 592220 snn_ep2 120000
+1792870884 8783.7 592220 snn_ep2 130000
+1792870894 8793.8 592220 snn_ep2 130000
+1792870904 8803.8 592220 snn_ep2 130000
+1792870914 8813.8 592220 snn_ep2 130000
+1792870924 8823.8 592220 snn_ep2 130000
+1792870934 8833.8 592220 snn_ep2 130000
+1792870944 8843.8 592220 snn_ep2 130000
+1792870954 8853.8 592220 snn_ep2 130000
+1792870964 8863.8 592220 snn_ep2 130000
+1792870974 8873.8 592220 snn_ep2 130000
+1792870984 8883.8 592220 snn_ep2 130000
+1792870994 8893.8 592220 snn_ep2 130000
+1792871004 8903.8 592220 snn_ep2 140000
+1792871014 8913.8 592220 snn_ep2 140000
+1792871024 8923.8 592220 snn_ep2 140000
+1792871034 8933.8 592220 snn_ep2 140000
+1792871044 8943.8 592220 snn_ep2 140000
+1792871054 8953.8 592220 snn_ep2 140000
+1792871064 8963.8 592220 snn_ep2 140000
+1792871074 8973.8 592220 snn_ep2 140000
+1792871084 8983.8 592220 snn_ep2 140000
+1792871094 8993.8 592220 snn_ep2 140000
+1792871104 9003.8 592220 snn_ep2 140000
+1792871114 9013.8 592220 snn_ep2 140000
+1792871124 9023.8 592220 snn_ep2 150000
+1792871134 9033.8 592220 snn_ep2 150000
+1792871144 9043.8 592220 snn_ep2 150000
+1792871154 9053.8 592220 snn_ep2 150000
+1792871164 9063.8 592220 snn_ep2 150000
+1792871174 9073.8 592220 snn_ep2 150000
+1792871184 9083.8 592220 snn_ep2 150000
+1792871194 9093.8 592220 snn_ep2 150000
+1792871204 9103.8 592220 snn_ep2 150000
+1792871214 9113.8 592220 snn_ep2 150000
+1792871224 9123.8 592220 snn_ep2 150000
+1792871234 9133.8 592220 snn_ep2 150000
+1792871244 9143.8 592220 snn_ep2 160000
+1792871254 9153.8 592220 snn_ep2 160000
+1792871264 9163.8 592220 snn_ep2 160000
+1792871274 9173.8 592220 snn_ep2 160000
+1792871284 9183.8 592220 snn_ep2 160000
+1792871294 9193.8 592220 snn_ep2 160000
+1792871304 9203.8 592220 snn_ep2 160000
+1792871314 9213.8 592220 snn_ep2 160000
+1792871324 9223.8 592220 snn_ep2 160000
+1792871334 9233.8 592220 snn_ep2 160000
+1792871344 9243.8 592220 snn_ep2 160000
+1792871354 9253.8 592220 snn_ep2 170000
+1792871364 9263.8 592220 snn_ep2 170000
+1792871374 9273.8 592220 snn_ep2 170000
+1792871384 9283.8 592220 snn_ep2 170000
+1792871394 9293.8 592220 snn_ep2 170000
+1792871404 9303.8 592220 snn_ep2 170000
+1792871414 9313.8 592220 snn_ep2 170000
+1792871424 9323.8 592220 snn_ep2 170000
+1792871434 9333.8 592220 snn_ep2 170000
+1792871444 9343.8 592220 snn_ep2 170000
+1792871454 9353.8 592220 snn_ep2 170000
+1792871464 9363.8 592220 snn_ep2 170000
+1792871474 9373.8 592220 snn_ep2 180000
+1792871484 9383.8 592220 snn_ep2 180000
+1792871494 9393.8 592220 snn_ep2 180000
+1792871504 9403.8 592220 snn_ep2 180000
+1792871514 9413.8 592220 snn_ep2 180000
+1792871524 9423.8 592220 snn_ep2 180000
+1792871534 9433.8 592220 snn_ep2 180000
+1792871544 9443.8 592220 snn_ep2 180000
+1792871554 9453.8 592220 snn_ep2 180000
+1792871564 9463.8 592220 snn_ep2 180000
+1792871574 9473.8 592220 snn_ep2 180000
+1792871584 9483.8 592220 snn_ep2 180000
+1792871594 9493.8 592220 snn_ep2 190000
+1792871604 9503.8 592220 snn_ep2 190000
+1792871614 9513.8 592220 snn_ep2 190000
+1792871624 9523.8 592220 snn_ep2 190000
+1792871634 9533.8 592220 snn_ep2 190000
+1792871644 9543.8 592220 snn_ep2 190000
+1792871654 9553.8 592220 snn_ep2 190000
+1792871664 9563.8 592220 snn_ep2 190000
+1792871674 9573.8 592220 snn_ep2 190000
+1792871684 9583.8 592220 snn_ep2 190000
+1792871694 9593.8 592220 snn_ep2 190000
+1792871704 9603.8 592220 snn_ep2 190000
+1792871714 9613.8 592220 snn_ep2 200000
+1792871724 9623.8 592220 snn_ep2 200000
+1792871734 9633.8 592220 snn_ep2 200000
+1792871744 9643.8 592220 snn_ep2 200000
+1792871754 9653.8 592220 snn_ep2 200000
+1792871764 9663.8 592220 snn_ep2 200000
+1792871774 9673.8 592220 snn_ep2 200000
+1792871784 9683.8 592220 snn_ep2 200000
+1792871794 9693.8 592220 snn_ep2 200000
+1792871804 9703.8 592220 snn_ep2 200000
+1792871814 9713.8 592220 snn_ep2 200000
+1792871824 9723.8 592220 snn_ep2 200000
+1792871834 9733.8 592220 snn_ep2 210000
+1792871844 9743.8 592220 snn_ep2 210000
+1792871854 9753.8 592220 snn_ep2 210000
+1792871864 9763.8 592220 snn_ep2 210000
+1792871874 9773.8 592220 snn_ep2 210000
+1792871884 9783.8 592220 snn_ep2 210000
+1792871894 9793.8 592220 snn_ep2 210000
+1792871904 9803.8 592220 snn_ep2 210000
+1792871914 9813.8 592220 snn_ep2 210000
+1792871924 9823.8 592220 snn_ep2 210000
+1792871934 9833.8 592220 snn_ep2 210000
+1792871944 9843.8 592220 snn_ep2 220000
+1792871954 9853.8 592220 snn_ep2 220000
+1792871964 9863.8 592220 snn_ep2 220000
+1792871974 9873.8 592220 snn_ep2 220000
+1792871984 9883.8 592220 snn_ep2 220000
+1792871994 9893.8 592220 snn_ep2 220000
+1792872004 9903.8 592220 snn_ep2 220000
+1792872014 9913.8 592220 snn_ep2 220000
+1792872024 9923.8 592220 snn_ep2 220000
+1792872034 9933.8 592220 snn_ep2 220000
+1792872044 9943.8 592220 snn_ep2 220000
+1792872054 9953.8 592220 snn_ep2 220000
+1792872064 9963.8 592220 snn_ep2 230000
+1792872074 9973.8 592220 snn_ep2 230000
+1792872084 9983.8 592220 snn_ep2 230000
+1792872094 9993.8 592220 snn_ep2 230000
+1792872104 10003.8 592220 snn_ep2 230000
+1792872114 10013.8 592220 snn_ep2 230000
+1792872124 10023.8 592220 snn_ep2 230000
+1792872134 10033.8 592220 snn_ep2 230000
+1792872144 10043.8 592220 snn_ep2 230000
+1792872154 10053.8 592220 snn_ep2 230000
+1792872164 10063.8 592220 snn_ep2 230000
+1792872174 10073.8 592220 snn_ep2 240000
+1792872184 10083.8 592220 snn_ep2 240000
+1792872194 10093.8 592220 snn_ep2 240000
+1792872204 10103.8 592220 snn_ep2 240000
+1792872214 10113.8 592220 snn_ep2 240000
+1792872224 10123.8 592220 snn_ep2 240000
+1792872234 10133.8 592220 snn_ep2 240000
+1792872244 10143.8 592220 snn_ep2 240000
+1792872254 10153.8 592220 snn_ep2 240000
+1792872264 10163.8 592220 snn_ep2 240000
+1792872274 10173.8 592220 snn_ep2 240000
+1792872284 10183.8 592220 snn_ep2 250000
+1792872294 10193.8 592220 snn_ep2 250000
+1792872304 10203.8 592220 snn_ep2 250000
+1792872314 10213.8 592220 snn_ep2 250000
+1792872324 10223.8 592220 snn_ep2 250000
+1792872334 10233.8 592220 snn_ep2 250000
+1792872344 10243.8 592220 snn_ep2 250000
+1792872354 10253.8 592220 snn_ep2 250000
+1792872364 10263.8 592220 snn_ep2 250000
+1792872374 10273.8 592220 snn_ep2 250000
+1792872384 10283.8 592220 snn_ep2 250000
+1792872394 10293.8 592220 snn_ep2 260000
+1792872404 10303.8 592220 snn_ep2 260000
+1792872414 10313.8 592220 snn_ep2 260000
+1792872424 10323.8 592220 snn_ep2 260000
+1792872434 10333.8 592220 snn_ep2 260000
+1792872444 10343.8 592220 snn_ep2 260000
+1792872454 10353.8 592220 snn_ep2 260000
+1792872464 10363.8 592220 snn_ep2 260000
+1792872474 10373.8 592220 snn_ep2 260000
+1792872484 10383.8 592216 snn_ep2 260000
+1792872494 10393.8 592216 snn_ep2 260000
+1792872504 10403.8 592216 snn_ep2 270000
+1792872514 10413.8 592216 snn_ep2 270000
+1792872524 10423.8 592216 snn_ep2 270000
+1792872534 10433.8 592216 snn_ep2 270000
+1792872544 10443.8 592216 snn_ep2 270000
+1792872554 10453.8 592216 snn_ep2 270000
+1792872564 10463.8 592216 snn_ep2 270000
+1792872574 10473.8 592216 snn_ep2 270000
+1792872584 10483.8 592216 snn_ep2 270000
+1792872594 10493.8 592216 snn_ep2 270000
+1792872604 10503.8 592216 snn_ep2 270000
+1792872614 10513.8 592216 snn_ep2 270000
+1792872624 10523.8 592216 snn_ep2 280000
+1792872634 10533.8 592216 snn_ep2 280000
+1792872644 10543.8 592216 snn_ep2 280000
+1792872654 10553.8 592216 snn_ep2 280000
+1792872664 10563.8 592216 snn_ep2 280000
+1792872674 10573.8 592216 snn_ep2 280000
+1792872684 10583.8 592216 snn_ep2 280000
+1792872694 10593.8 592216 snn_ep2 280000
+1792872704 10603.8 592216 snn_ep2 280000
+1792872714 10613.8 592216 snn_ep2 280000
+1792872724 10623.8 592216 snn_ep2 280000
+1792872734 10633.8 592216 snn_ep2 280000
+1792872744 10643.8 592216 snn_ep2 290000
+1792872754 10653.9 592216 snn_ep2 290000
+1792872764 10663.9 592216 snn_ep2 290000
+1792872774 10673.9 592216 snn_ep2 290000
+1792872784 10683.9 592216 snn_ep2 290000
+1792872794 10693.9 592216 snn_ep2 290000
+1792872804 10703.9 592216 snn_ep2 290000
+1792872814 10713.9 592216 snn_ep2 290000
+1792872824 10723.9 592216 snn_ep2 290000
+1792872834 10733.9 592216 snn_ep2 290000
+1792872844 10743.9 592216 snn_ep2 290000
+1792872854 10753.9 592216 snn_ep2 290000
+1792872864 10763.9 592216 snn_ep2 300000
+1792872874 10773.9 592216 snn_ep2 300000
+1792872884 10783.9 592216 snn_ep2 300000
+1792872894 10793.9 592216 snn_ep2 300000
+1792872904 10803.9 592216 snn_ep2 300000
+1792872914 10813.9 592216 snn_ep2 300000
+1792872924 10823.9 592216 snn_ep2 300000
+1792872934 10833.9 592216 snn_ep2 300000
+1792872944 10843.9 592216 snn_ep2 300000
+1792872954 10853.9 592216 snn_ep2 300000
+1792872964 10863.9 592216 snn_ep2 300000
+1792872974 10873.9 592216 snn_ep2 310000
+1792872984 10883.9 592216 snn_ep2 310000
+1792872994 10893.9 592216 snn_ep2 310000
+1792873004 10903.9 592216 snn_ep2 310000
+1792873014 10913.9 592216 snn_ep2 310000
+1792873024 10923.9 592216 snn_ep2 310000
+1792873034 10933.9 592216 snn_ep2 310000
+1792873044 10943.9 592216 snn_ep2 310000
+1792873054 10953.9 592216 snn_ep2 310000
+1792873064 10963.9 592216 snn_ep2 310000
+1792873074 10973.9 592216 snn_ep2 310000
+1792873084 10983.9 592216 snn_ep2 310000
+1792873094 10993.9 592216 snn_ep2 320000
+1792873104 11003.9 592216 snn_ep2 320000
+1792873114 11013.9 592216 snn_ep2 320000
+1792873124 11023.9 592216 snn_ep2 320000
+1792873134 11033.9 592208 snn_ep2 320000
+1792873144 11043.9 592208 snn_ep2 320000
+1792873154 11053.9 592208 snn_ep2 320000
+1792873164 11063.9 592208 snn_ep2 320000
+1792873174 11073.9 592208 snn_ep2 320000
+1792873184 11083.9 592208 snn_ep2 320000
+1792873194 11093.9 592208 snn_ep2 320000
+1792873204 11103.9 592208 snn_ep2 330000
+1792873214 11113.9 592208 snn_ep2 330000
+1792873224 11123.9 592208 snn_ep2 330000
+1792873234 11133.9 592208 snn_ep2 330000
+1792873244 11143.9 592208 snn_ep2 330000
+1792873254 11153.9 592208 snn_ep2 330000
+1792873264 11163.9 592208 snn_ep2 330000
+1792873274 11173.9 592208 snn_ep2 330000
+1792873284 11183.9 592208 snn_ep2 330000
+1792873294 11193.9 592208 snn_ep2 330000
+1792873304 11203.9 592208 snn_ep2 330000
+1792873314 11213.9 592208 snn_ep2 330000
+1792873324 11223.9 592208 snn_ep2 340000
+1792873334 11233.9 592208 snn_ep2 340000
+1792873344 11243.9 592208 snn_ep2 340000
+1792873354 11253.9 592208 snn_ep2 340000
+1792873364 11263.9 592208 snn_ep2 340000
+1792873374 11273.9 592208 snn_ep2 340000
+1792873384 11283.9 592208 snn_ep2 340000
+1792873394 11293.9 592208 snn_ep2 340000
+1792873404 11303.9 592208 snn_ep2 340000
+1792873414 11313.9 592208 snn_ep2 340000
+1792873424 11323.9 592208 snn_ep2 340000
+1792873434 11333.9 592208 snn_ep2 340000
+1792873444 11343.9 592208 snn_ep2 340000
+1792873454 11353.9 592172 snn_ep2 350000
+1792873464 11363.9 592172 snn_ep2 350000
+1792873474 11373.9 592172 snn_ep2 350000
+1792873484 11383.9 592172 snn_ep2 350000
+1792873494 11393.9 592172 snn_ep2 350000
+1792873504 11403.9 592172 snn_ep2 350000
+1792873514 11413.9 592172 snn_ep2 350000
+1792873524 11423.9 592172 snn_ep2 350000
+1792873534 11433.9 592172 snn_ep2 350000
+1792873544 11443.9 592172 snn_ep2 350000
+1792873554 11453.9 592172 snn_ep2 350000
+1792873564 11463.9 592172 snn_ep2 350000
+1792873574 11473.9 592172 snn_ep2 360000
+1792873584 11483.9 592172 snn_ep2 360000
+1792873594 11493.9 592172 snn_ep2 360000
+1792873604 11503.9 591544 snn_ep2 360000
+1792873614 11513.9 591544 snn_ep2 360000
+1792873624 11523.9 591544 snn_ep2 360000
+1792873634 11533.9 591544 snn_ep2 360000
+1792873644 11543.9 591544 snn_ep2 360000
+1792873654 11553.9 591544 snn_ep2 360000
+1792873664 11563.9 591544 snn_ep2 360000
+1792873674 11573.9 591544 snn_ep2 360000
+1792873684 11583.9 591544 snn_ep2 360000
+1792873694 11593.9 591544 snn_ep2 370000
+1792873704 11603.9 591544 snn_ep2 370000
+1792873714 11613.9 591544 snn_ep2 370000
+1792873724 11623.9 591544 snn_ep2 370000
+1792873734 11633.9 591544 snn_ep2 370000
+1792873744 11643.9 591544 snn_ep2 370000
+1792873754 11653.9 591544 snn_ep2 370000
+1792873764 11663.9 591544 snn_ep2 370000
+1792873774 11673.9 591544 snn_ep2 370000
+1792873784 11683.9 591544 snn_ep2 370000
+1792873794 11693.9 591544 snn_ep2 370000
+1792873804 11703.9 591544 snn_ep2 370000
+1792873814 11713.9 591544 snn_ep2 380000
+1792873824 11723.9 591544 snn_ep2 380000
+1792873834 11733.9 591544 snn_ep2 380000
+1792873844 11743.9 591544 snn_ep2 380000
+1792873854 11753.9 591544 snn_ep2 380000
+1792873864 11763.9 591544 snn_ep2 380000
+1792873874 11773.9 591544 snn_ep2 380000
+1792873884 11783.9 591544 snn_ep2 380000
+1792873894 11793.9 591544 snn_ep2 380000
+1792873904 11803.9 591544 snn_ep2 380000
+1792873914 11813.9 591544 snn_ep2 380000
+1792873924 11823.9 591544 snn_ep2 380000
+1792873934 11833.9 591544 snn_ep2 390000
+1792873944 11843.9 591544 snn_ep2 390000
+1792873954 11853.9 591544 snn_ep2 390000
+1792873964 11863.9 591544 snn_ep2 390000
+1792873974 11873.9 591544 snn_ep2 390000
+1792873984 11883.9 591544 snn_ep2 390000
+1792873994 11893.9 591544 snn_ep2 390000
+1792874004 11903.9 591544 snn_ep2 390000
+1792874014 11913.9 591544 snn_ep2 390000
+1792874024 11923.9 591544 snn_ep2 390000
+1792874034 11933.9 591544 snn_ep2 390000
+1792874044 11943.9 591544 snn_ep2 390000
+1792874054 11953.9 591544 snn_ep2 400000
+1792874064 11963.9 591544 snn_ep2 400000
+1792874074 11973.9 591544 snn_ep2 400000
+1792874084 11983.9 591544 snn_ep2 400000
+1792874094 11993.9 591544 snn_ep2 400000
+1792874104 12003.9 591544 snn_ep2 400000
+1792874114 12013.9 591544 snn_ep2 400000
+1792874124 12023.9 591544 snn_ep2 400000
+1792874134 12033.9 591544 snn_ep2 400000
+1792874144 12043.9 591544 snn_ep2 400000
+1792874154 12054.0 591544 snn_ep2 400000
+1792874164 12064.0 591528 snn_ep2 400000
+1792874203 12102.4 591528 snn_ep2 400000
+1792874213 12112.4 591528 snn_ep2 410000
+1792874223 12122.4 591528 snn_ep2 410000
+1792874233 12132.4 591528 snn_ep2 410000
+1792874243 12142.4 591528 snn_ep2 410000
+1792874253 12152.4 591528 snn_ep2 410000
+1792874263 12162.4 591528 snn_ep2 410000
+1792874273 12172.4 591528 snn_ep2 410000
+1792874283 12182.4 591528 snn_ep2 410000
+1792874293 12192.4 591528 snn_ep2 410000
+1792874303 12202.4 591528 snn_ep2 410000
+1792874313 12212.4 591528 snn_ep2 410000
+1792874323 12222.4 591528 snn_ep2 420000
+1792874333 12232.4 591528 snn_ep2 420000
+1792874343 12242.4 591528 snn_ep2 420000
+1792874353 12252.4 591528 snn_ep2 420000
+1792874363 12262.4 591528 snn_ep2 420000
+1792874373 12272.4 591528 snn_ep2 420000
+1792874383 12282.4 591528 snn_ep2 420000
+1792874393 12292.4 591528 snn_ep2 420000
+1792874403 12302.4 591528 snn_ep2 420000
+1792874413 12312.4 591528 snn_ep2 420000
+1792874423 12322.4 591528 snn_ep2 420000
+1792874433 12332.4 591528 snn_ep2 420000
+1792874443 12342.4 591528 snn_ep2 420000
+1792874453 12352.4 591528 snn_ep2 430000
+1792874463 12362.4 591528 snn_ep2 430000
+1792874473 12372.4 591528 snn_ep2 430000
+1792874483 12382.4 591528 snn_ep2 430000
+1792874493 12392.4 591528 snn_ep2 430000
+1792874503 12402.4 591528 snn_ep2 430000
+1792874513 12412.4 591528 snn_ep2 430000
+1792874523 12422.4 591528 snn_ep2 430000
+1792874533 12432.4 591528 snn_ep2 430000
+1792874543 12442.4 591528 snn_ep2 430000
+1792874553 12452.4 591528 snn_ep2 430000
+1792874563 12462.4 591528 snn_ep2 430000
+1792874573 12472.4 591528 snn_ep2 440000
+1792874583 12482.4 591528 snn_ep2 440000
+1792874593 12492.4 591528 snn_ep2 440000
+1792874603 12502.4 591528 snn_ep2 440000
+1792874613 12512.5 591528 snn_ep2 440000
+1792874623 12522.5 591528 snn_ep2 440000
+1792874633 12532.5 591528 snn_ep2 440000
+1792874643 12542.5 591528 snn_ep2 440000
+1792874653 12552.5 591528 snn_ep2 440000
+1792874663 12562.5 591528 snn_ep2 440000
+1792874673 12572.5 591528 snn_ep2 440000
+1792874683 12582.5 591528 snn_ep2 440000
+1792874693 12592.5 591528 snn_ep2 450000
+1792874703 12602.5 591528 snn_ep2 450000
+1792874713 12612.5 591528 snn_ep2 450000
+1792874723 12622.5 591528 snn_ep2 450000
+1792874733 12632.5 591528 snn_ep2 450000
+1792874743 12642.5 591528 snn_ep2 450000
+1792874753 12652.5 591528 snn_ep2 450000
+1792874763 12662.5 591528 snn_ep2 450000
+1792874773 12672.5 591528 snn_ep2 450000
+1792874783 12682.5 591528 snn_ep2 450000
+1792874793 12692.5 591528 snn_ep2 450000
+1792874803 12702.5 591528 snn_ep2 450000
+1792874813 12712.5 591528 snn_ep2 450000
+1792874823 12722.5 591528 snn_ep2 460000
+1792874833 12732.5 591528 snn_ep2 460000
+1792874843 12742.5 591528 snn_ep2 460000
+1792874853 12752.5 591524 snn_ep2 460000
+1792874863 12762.5 591524 snn_ep2 460000
+1792874873 12772.5 591448 snn_ep2 460000
+1792874883 12782.5 591448 snn_ep2 460000
+1792874893 12792.5 591444 snn_ep2 460000
+1792874903 12802.5 591444 snn_ep2 460000
+1792874913 12812.5 591444 snn_ep2 460000
+1792874923 12822.5 591444 snn_ep2 460000
+1792874933 12832.5 591444 snn_ep2 460000
+1792874943 12842.5 591444 snn_ep2 470000
+1792874953 12852.5 591444 snn_ep2 470000
+1792874963 12862.5 591444 snn_ep2 470000
+1792874973 12872.5 591444 snn_ep2 470000
+1792874983 12882.5 591444 snn_ep2 470000
+1792874993 12892.5 591444 snn_ep2 470000
+1792875003 12902.5 591444 snn_ep2 470000
+1792875013 12912.5 591444 snn_ep2 470000
+1792875023 12922.5 591444 snn_ep2 470000
+1792875033 12932.5 591444 snn_ep2 470000
+1792875043 12942.5 591444 snn_ep2 470000
+1792875053 12952.5 591444 snn_ep2 470000
+1792875063 12962.5 591444 snn_ep2 470000
+1792875073 12972.5 591444 snn_ep2 480000
+1792875083 12982.5 591444 snn_ep2 480000
+1792875093 12992.5 591444 snn_ep2 480000
+1792875103 13002.5 591444 snn_ep2 480000
+1792875113 13012.5 591444 snn_ep2 480000
+1792875123 13022.5 591444 snn_ep2 480000
+1792875133 13032.5 591444 snn_ep2 480000
+1792875143 13042.5 591444 snn_ep2 480000
+1792875153 13052.5 591444 snn_ep2 480000
+1792875163 13062.5 591444 snn_ep2 480000
+1792875173 13072.5 591444 snn_ep2 480000
+1792875183 13082.5 591444 snn_ep2 480000
+1792875193 13092.5 591444 snn_ep2 490000
+1792875203 13102.5 591444 snn_ep2 490000
+1792875213 13112.5 591444 snn_ep2 490000
+1792875223 13122.5 591444 snn_ep2 490000
+1792875233 13132.5 591444 snn_ep2 490000
+1792875243 13142.5 591444 snn_ep2 490000
+1792875253 13152.5 591444 snn_ep2 490000
+1792875263 13162.5 591444 snn_ep2 490000
+1792875273 13172.5 591444 snn_ep2 490000
+1792875283 13182.5 591444 snn_ep2 490000
+1792875293 13192.5 591444 snn_ep2 490000
+1792875303 13202.5 591444 snn_ep2 490000
+1792875313 13212.5 591444 snn_ep2 500000
+1792875323 13222.5 591444 snn_ep2 500000
+1792875333 13232.5 591444 snn_ep2 500000
+1792875343 13242.5 591444 snn_ep2 500000
+1792875353 13252.5 591444 snn_ep2 500000
+1792875363 13262.5 591444 snn_ep2 500000
+1792875373 13272.5 591444 snn_ep2 500000
+1792875383 13282.5 591444 snn_ep2 500000
+1792875393 13292.5 591444 snn_ep2 500000
+1792875403 13302.5 591444 snn_ep2 500000
+1792875413 13312.5 591444 snn_ep2 500000
+1792875423 13322.5 591444 snn_ep2 500000
+1792875433 13332.5 591444 snn_ep2 510000
+1792875443 13342.5 591444 snn_ep2 510000
+1792875453 13352.5 591444 snn_ep2 510000
+1792875463 13362.5 591444 snn_ep2 510000
+1792875473 13372.5 591444 snn_ep2 510000
+1792875483 13382.5 591444 snn_ep2 510000
+1792875493 13392.5 591444 snn_ep2 510000
+1792875503 13402.5 591444 snn_ep2 510000
+1792875513 13412.5 591444 snn_ep2 510000
+1792875523 13422.5 591444 snn_ep2 510000
+1792875533 13432.5 591444 snn_ep2 510000
+1792875543 13442.5 591444 snn_ep2 510000
+1792875553 13452.5 591444 snn_ep2 520000
+1792875563 13462.5 591444 snn_ep2 520000
+1792875573 13472.5 591444 snn_ep2 520000
+1792875583 13482.5 591444 snn_ep2 520000
+1792875593 13492.5 591444 snn_ep2 520000
+1792875603 13502.5 591444 snn_ep2 520000
+1792875613 13512.5 591444 snn_ep2 520000
+1792875623 13522.5 591444 snn_ep2 520000
+1792875633 13532.5 591444 snn_ep2 520000
+1792875643 13542.5 591444 snn_ep2 520000
+1792875653 13552.5 591444 snn_ep2 520000
+1792875663 13562.5 591444 snn_ep2 520000
+1792875673 13572.5 591444 snn_ep2 530000
+1792875683 13582.5 591444 snn_ep2 530000
+1792875693 13592.5 591444 snn_ep2 530000
+1792875703 13602.5 591444 snn_ep2 530000
+1792875713 13612.5 591444 snn_ep2 530000
+1792875723 13622.5 591444 snn_ep2 530000
+1792875733 13632.5 591444 snn_ep2 530000
+1792875743 13642.5 591444 snn_ep2 530000
+1792875753 13652.5 591444 snn_ep2 530000
+1792875763 13662.5 591444 snn_ep2 530000
+1792875773 13672.5 591444 snn_ep2 530000
+1792875783 13682.5 591444 snn_ep2 540000
+1792875793 13692.5 591444 snn_ep2 540000
+1792875803 13702.5 591444 snn_ep2 540000
+1792875813 13712.5 591444 snn_ep2 540000
+1792875823 13722.5 591444 snn_ep2 540000
+1792875833 13732.5 591444 snn_ep2 540000
+1792875843 13742.5 591444 snn_ep2 540000
+1792875853 13752.5 591444 snn_ep2 540000
+1792875863 13762.5 591444 snn_ep2 540000
+1792875873 13772.5 591444 snn_ep2 540000
+1792875883 13782.5 591444 snn_ep2 540000
+1792875893 13792.5 591444 snn_ep2 540000
+1792875903 13802.5 591444 snn_ep2 550000
+1792875913 13812.5 591444 snn_ep2 550000
+1792875923 13822.5 591444 snn_ep2 550000
+1792875933 13832.5 591444 snn_ep2 550000
+1792875943 13842.5 591444 snn_ep2 550000
+1792875953 13852.5 591444 snn_ep2 550000
+1792875963 13862.5 591444 snn_ep2 550000
+1792875973 13872.5 591444 snn_ep2 550000
+1792875983 13882.5 591444 snn_ep2 550000
+1792875993 13892.5 591444 snn_ep2 550000
+1792876003 13902.5 591444 snn_ep2 550000
+1792876013 13912.5 591444 snn_ep2 550000
+1792876023 13922.5 591444 snn_ep2 560000
+1792876033 13932.5 591444 snn_ep2 560000
+1792876043 13942.5 591444 snn_ep2 560000
+1792876053 13952.5 591444 snn_ep2 560000
+1792876063 13962.5 591444 snn_ep2 560000
+1792876073 13972.5 591444 snn_ep2 560000
+1792876083 13982.5 591444 snn_ep2 560000
+1792876093 13992.5 591444 snn_ep2 560000
+1792876103 14002.5 591444 snn_ep2 560000
+1792876113 14012.5 591444 snn_ep2 560000
+1792876123 14022.5 591444 snn_ep2 560000
+1792876133 14032.5 591444 snn_ep2 570000
+1792876143 14042.5 591444 snn_ep2 570000
+1792876153 14052.5 591444 snn_ep2 570000
+1792876163 14062.5 591444 snn_ep2 570000
+1792876173 14072.5 591444 snn_ep2 570000
+1792876183 14082.5 591444 snn_ep2 570000
+1792876193 14092.5 591444 snn_ep2 570000
+1792876203 14102.5 591444 snn_ep2 570000
+1792876213 14112.5 591444 snn_ep2 570000
+1792876223 14122.6 591444 snn_ep2 570000
+1792876233 14132.6 591444 snn_ep2 570000
+1792876243 14142.6 591444 snn_ep2 570000
+1792876253 14152.6 591444 snn_ep2 580000
+1792876263 14162.6 591444 snn_ep2 580000
+1792876273 14172.6 591444 snn_ep2 580000
+1792876283 14182.6 591444 snn_ep2 580000
+1792876293 14192.6 591444 snn_ep2 580000
+1792876303 14202.6 591444 snn_ep2 580000
+1792876313 14212.6 591444 snn_ep2 580000
+1792876323 14222.6 591444 snn_ep2 580000
+1792876333 14232.6 591444 snn_ep2 580000
+1792876343 14242.6 591444 snn_ep2 580000
+1792876353 14252.6 591444 snn_ep2 580000
+1792876363 14262.6 591444 snn_ep2 580000
+1792876373 14272.6 591444 snn_ep2 590000
+1792876383 14282.6 591444 snn_ep2 590000
+1792876393 14292.6 591444 snn_ep2 590000
+1792876403 14302.6 591444 snn_ep2 590000
+1792876413 14312.6 591444 snn_ep2 590000
+1792876423 14322.6 591444 snn_ep2 590000
+1792876433 14332.6 591444 snn_ep2 590000
+1792876443 14342.6 591444 snn_ep2 590000
+1792876453 14352.6 591444 snn_ep2 590000
+1792876463 14362.6 591444 snn_ep2 590000
+1792876473 14372.6 591444 snn_ep2 590000
+1792876483 14382.6 591444 snn_ep2 590000
+1792876493 14392.6 804560 am_write 600000
+1792876503 14402.6 886536 am_write 600000
+1792876513 14412.6 821148 calibrate_save 600000
+1792876523 14422.6 821148 calibrate_save 600000
+1792876533 14432.6 821148 calibrate_save 600000
+1792876543 14442.6 849452 calibrate_save 600000
+1792876553 14452.6 862784 calibrate_save 600000
+1792876563 14462.6 845848 calibrate_save 600000
+1792876573 14472.7 1221636 calibrate_save 600000
+1792876583 14482.7 861580 eval_seen 600000
+1792876593 14492.7 861580 eval_seen 600000
+1792876603 14502.7 861580 eval_seen 600000
+1792876613 14512.7 861580 eval_seen 600000
+1792876623 14522.7 861860 eval_fc2 600000
+1792876633 14532.7 861860 eval_fc2 600000
+1792876643 14542.7 861860 eval_fc2 600000
+1792876653 14552.7 861860 eval_fc2 600000
+1792876663 14562.7 861860 eval_fc2 600000
+1792876673 14572.7 862124 eval_fresh_en 600000
+1792876683 14582.7 862124 eval_fresh_en 600000
+1792876693 14592.7 862124 eval_fresh_en 600000
+1792876703 14602.7 862124 eval_fresh_en 600000
+1792876713 14612.7 862124 eval_fresh_en 600000
+1792876723 14622.7 868792 eval_fresh_fr 600000
+1792876733 14632.7 868792 eval_fresh_fr 600000
+1792876743 14642.7 868792 eval_fresh_fr 600000
+1792876753 14652.7 868792 eval_fresh_fr 600000
+1792876763 14662.7 869844 eval_test20k 600000
+1792876773 14672.7 869844 eval_test20k 600000
+1792876783 14682.7 869844 eval_test20k 600000
+1792876793 14692.7 869844 eval_test20k 600000
+1792876803 14702.7 926752 eval_test_v3 600000
+1792876813 14712.7 960080 eval_test_v3 600000
+1792876823 14722.7 960084 eval_test_v3 600000
+1792876833 14732.7 960084 eval_test_v3 600000
+1792876843 14742.7 960084 eval_test_v3 600000
+1792876853 14752.7 879456 eval_queries 600000
+1792876863 14762.7 879456 eval_queries 600000
+1792876873 14772.7 879456 eval_queries 600000
+1792876883 14782.7 879456 eval_queries 600000
diff --git a/results/hashing/m8_v1b/sample/recount64_v1b_sample.json b/results/hashing/m8_v1b/sample/recount64_v1b_sample.json
new file mode 100644
index 0000000000000000000000000000000000000000..cd5433c2c5c835e0fe9f2d03230bc7ad25b00236
--- /dev/null
+++ b/results/hashing/m8_v1b/sample/recount64_v1b_sample.json
@@ -0,0 +1,221 @@
+{
+ "train": "/workspace/spira_shared/hashing_gen/m8_v1b/sample/v1b_sample.bin",
+ "bytes": 35128951,
+ "sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "positions_checked": 35128888,
+ "hash": "poly mod 2^64, M=0x9E3779B97F4A7C15, byte+0x3F (independent of builder FNV and Checker splitmix64); all hits byte-confirmed",
+ "windows_n": 15,
+ "window_unique_64gram_hashes": 6356115,
+ "intra_window_hash_collisions": 0,
+ "whitespace_tokens": 4794234,
+ "whitespace_def": "maximal runs of bytes not in {9,10,11,12,13,32} (== bytes.split())",
+ "segments": null,
+ "whitespace_tokens_by_segment": {
+ "whole": 4794234
+ },
+ "confirmed_positions_straddling_segment_boundaries": 0,
+ "windows": {
+ "m7_fresh_en": {
+ "window_file": "/workspace/spira_shared/spira_m7/windows/fresh_en.bin",
+ "window_bytes": 119763,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "n_64grams": 119700,
+ "hash_candidates_window_positions": 0,
+ "hash_candidates_train_positions": 0,
+ "confirmed_window_positions": 0,
+ "confirmed_train_positions": 0,
+ "confirmed_train_offsets_first10": []
+ },
+ "m7_fresh_fr": {
+ "window_file": "/workspace/spira_shared/spira_m7/windows/fresh_fr.bin",
+ "window_bytes": 1088688,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "n_64grams": 1088625,
+ "hash_candidates_window_positions": 0,
+ "hash_candidates_train_positions": 0,
+ "confirmed_window_positions": 0,
+ "confirmed_train_positions": 0,
+ "confirmed_train_offsets_first10": []
+ },
+ "m7_neither_code": {
+ "window_file": "/workspace/spira_shared/spira_m7/windows/neither_code.bin",
+ "window_bytes": 546036,
+ "window_sha256": "f1d728dc1a3db2e57aee703d25745f601ff6154dc31c519ea8a4fd921ff0f954",
+ "n_64grams": 545973,
+ "hash_candidates_window_positions": 0,
+ "hash_candidates_train_positions": 0,
+ "confirmed_window_positions": 0,
+ "confirmed_train_positions": 0,
+ "confirmed_train_offsets_first10": []
+ },
+ "m7_test20k": {
+ "window_file": "/workspace/spira_shared/spira_m7/windows/test20k.bin",
+ "window_bytes": 319940,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "n_64grams": 319877,
+ "hash_candidates_window_positions": 0,
+ "hash_candidates_train_positions": 0,
+ "confirmed_window_positions": 0,
+ "confirmed_train_positions": 0,
+ "confirmed_train_offsets_first10": []
+ },
+ "m7_queries": {
+ "window_file": "/workspace/spira_shared/spira_m7/windows/queries.bin",
+ "window_bytes": 27800,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "n_64grams": 27737,
+ "hash_candidates_window_positions": 0,
+ "hash_candidates_train_positions": 0,
+ "confirmed_window_positions": 0,
+ "confirmed_train_positions": 0,
+ "confirmed_train_offsets_first10": []
+ },
+ "m7_freshcode": {
+ "window_file": "/workspace/spira_shared/spira_m7/windows/freshcode.bin",
+ "window_bytes": 200000,
+ "window_sha256": "589dbc35997e0cadd2ac8e283fdb0f305ea8c923d021159668104be7dbfcef98",
+ "n_64grams": 199937,
+ "hash_candidates_window_positions": 143787,
+ "hash_candidates_train_positions": 55462,
+ "confirmed_window_positions": 143787,
+ "confirmed_train_positions": 55462,
+ "confirmed_train_offsets_first10": [
+ 10596340,
+ 10596341,
+ 10596342,
+ 10596343,
+ 10596344,
+ 10596345,
+ 10596346,
+ 10596347,
+ 10596348,
+ 10596349
+ ]
+ },
+ "fc2": {
+ "window_file": "/workspace/spira_shared/broad/freshcode_v2.bin",
+ "window_bytes": 199792,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "n_64grams": 199729,
+ "hash_candidates_window_positions": 0,
+ "hash_candidates_train_positions": 0,
+ "confirmed_window_positions": 0,
+ "confirmed_train_positions": 0,
+ "confirmed_train_offsets_first10": []
+ },
+ "corpus_v3_test": {
+ "window_file": "/workspace/spira_shared/corpus_v3/test.bin",
+ "window_bytes": 3486653,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "n_64grams": 3486590,
+ "hash_candidates_window_positions": 0,
+ "hash_candidates_train_positions": 0,
+ "confirmed_window_positions": 0,
+ "confirmed_train_positions": 0,
+ "confirmed_train_offsets_first10": []
+ },
+ "corpus_v3_oneshot": {
+ "window_file": "/workspace/spira_shared/corpus_v3/oneshot.bin",
+ "window_bytes": 119763,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "n_64grams": 119700,
+ "hash_candidates_window_positions": 0,
+ "hash_candidates_train_positions": 0,
+ "confirmed_window_positions": 0,
+ "confirmed_train_positions": 0,
+ "confirmed_train_offsets_first10": []
+ },
+ "broad_local_v1_test": {
+ "window_file": "/workspace/spira_shared/broad/broad_local_v1/test.bin",
+ "window_bytes": 894718,
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
+ "n_64grams": 894655,
+ "hash_candidates_window_positions": 21086,
+ "hash_candidates_train_positions": 37414,
+ "confirmed_window_positions": 21086,
+ "confirmed_train_positions": 37414,
+ "confirmed_train_offsets_first10": [
+ 10596341,
+ 10596342,
+ 10596343,
+ 10596344,
+ 10596345,
+ 10596346,
+ 10596347,
+ 10596348,
+ 10596349,
+ 10596350
+ ]
+ },
+ "broad_local_v1_oneshot": {
+ "window_file": "/workspace/spira_shared/broad/broad_local_v1/oneshot.bin",
+ "window_bytes": 119763,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "n_64grams": 119700,
+ "hash_candidates_window_positions": 0,
+ "hash_candidates_train_positions": 0,
+ "confirmed_window_positions": 0,
+ "confirmed_train_positions": 0,
+ "confirmed_train_offsets_first10": []
+ },
+ "broad_gutenberg_v1_test": {
+ "window_file": "/workspace/spira_shared/broad/broad_gutenberg_v1/test.bin",
+ "window_bytes": 894718,
+ "window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
+ "n_64grams": 894655,
+ "hash_candidates_window_positions": 21086,
+ "hash_candidates_train_positions": 37414,
+ "confirmed_window_positions": 21086,
+ "confirmed_train_positions": 37414,
+ "confirmed_train_offsets_first10": [
+ 10596341,
+ 10596342,
+ 10596343,
+ 10596344,
+ 10596345,
+ 10596346,
+ 10596347,
+ 10596348,
+ 10596349,
+ 10596350
+ ]
+ },
+ "broad_gutenberg_v1_oneshot": {
+ "window_file": "/workspace/spira_shared/broad/broad_gutenberg_v1/oneshot.bin",
+ "window_bytes": 119763,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "n_64grams": 119700,
+ "hash_candidates_window_positions": 0,
+ "hash_candidates_train_positions": 0,
+ "confirmed_window_positions": 0,
+ "confirmed_train_positions": 0,
+ "confirmed_train_offsets_first10": []
+ },
+ "old_local_v1_test": {
+ "window_file": "/workspace/spira_shared/broad/old_local_v1/test.bin",
+ "window_bytes": 319940,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "n_64grams": 319877,
+ "hash_candidates_window_positions": 0,
+ "hash_candidates_train_positions": 0,
+ "confirmed_window_positions": 0,
+ "confirmed_train_positions": 0,
+ "confirmed_train_offsets_first10": []
+ },
+ "old_local_v1_oneshot": {
+ "window_file": "/workspace/spira_shared/broad/old_local_v1/oneshot.bin",
+ "window_bytes": 119763,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "n_64grams": 119700,
+ "hash_candidates_window_positions": 0,
+ "hash_candidates_train_positions": 0,
+ "confirmed_window_positions": 0,
+ "confirmed_train_positions": 0,
+ "confirmed_train_offsets_first10": []
+ }
+ },
+ "total_confirmed_train_positions_any_window": 56227,
+ "valid_zero_overlap_all_windows": false,
+ "peak_rss_MB": 856,
+ "elapsed_s": 12.8
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/sample/v1b_sample_docs.json b/results/hashing/m8_v1b/sample/v1b_sample_docs.json
new file mode 100644
index 0000000000000000000000000000000000000000..fa3fef19e1972d7938373dde44ecd018038b0632
--- /dev/null
+++ b/results/hashing/m8_v1b/sample/v1b_sample_docs.json
@@ -0,0 +1 @@
+[["github/Scala", "sbt/sbt", "Scala", 519813093, 519813114, 0, 21], ["github/PHP", "laravel/framework", "PHP", 467036728, 467036913, 36, 221], ["github/Rust", "serde-rs/serde", "Rust", 346483888, 346484169, 236, 517], ["github/Ruby", "rails/rails", "Ruby", 458744914, 458745084, 532, 702], ["github/C#", "dotnet/aspnetcore", "C#", 440959854, 440960143, 717, 1006], ["tinystories/en", "TinyStories-valid", "en", 17441718, 17442471, 1021, 1774], ["github/C++", "protocolbuffers/protobuf", "C++", 403962897, 403964104, 1789, 2996], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487756559, 487757339, 3011, 3791], ["github/Python", "scikit-learn/scikit-learn", "Python", 292900377, 292902052, 3806, 5481], ["github/C#", "dotnet/aspnetcore", "C#", 446257209, 446258062, 5496, 6349], ["github/JavaScript", "webpack/webpack", "JavaScript", 303342658, 303344703, 6364, 8409], ["tinystories/en", "TinyStories-valid", "en", 10051775, 10052535, 8424, 9184], ["github/TypeScript", "microsoft/vscode", "TypeScript", 319352728, 319355147, 9199, 11618], ["github/Go", "gohugoio/hugo", "Go", 369262910, 369264884, 11633, 13607], ["github/PHP", "symfony/symfony", "PHP", 475902429, 475904741, 13622, 15934], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490592543, 490593134, 15949, 16540], ["github/Python", "psf/requests", "Python", 281670735, 281670964, 16555, 16784], ["github/Java", "google/guava", "Java", 415304910, 415310634, 16799, 22523], ["tinystories/en", "TinyStories-valid", "en", 16875555, 16876431, 22538, 23414], ["github/C++", "nlohmann/json", "C++", 385604965, 385608284, 23429, 26748], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 450672277, 450673746, 26763, 28232], ["github/Scala", "sbt/sbt", "Scala", 520357096, 520363012, 28247, 34163], ["tinystories/en", "TinyStories-valid", "en", 8118698, 8119590, 34178, 35070], ["github/C", "curl/curl", "C", 373102788, 373106673, 35085, 38970], ["github/PHP", "laravel/framework", "PHP", 464017162, 464018154, 38985, 39977], ["tinystories/en", "TinyStories-valid", "en", 6633423, 6634085, 39992, 40654], ["github/C#", "dotnet/aspnetcore", "C#", 443617012, 443617771, 40669, 41428], ["github/PHP", "guzzle/guzzle", "PHP", 479817849, 479818720, 41443, 42314], ["github/Java", "spring-projects/spring-framework", "Java", 417900859, 417902462, 42329, 43932], ["tinystories/en", "TinyStories-valid", "en", 10993860, 10994734, 43947, 44821], ["github/Python", "django/django", "Python", 287056139, 287060739, 44836, 49436], ["github/Go", "prometheus/prometheus", "Go", 359730101, 359734599, 49451, 53949], ["tinystories/en", "TinyStories-valid", "en", 5353994, 5354870, 53964, 54840], ["github/Java", "spring-projects/spring-framework", "Java", 419124075, 419125767, 54855, 56547], ["github/TypeScript", "angular/angular", "TypeScript", 325669324, 325676114, 56562, 63352], ["github/Scala", "scala/scala", "Scala", 505685030, 505685700, 63367, 64037], ["github/PHP", "symfony/symfony", "PHP", 473820686, 473823326, 64052, 66692], ["tinystories/en", "TinyStories-valid", "en", 1165314, 1165856, 66707, 67249], ["github/Rust", "alacritty/alacritty", "Rust", 355399195, 355410302, 67264, 78371], ["github/Java", "spring-projects/spring-framework", "Java", 423433553, 423434452, 78386, 79285], ["tinystories/en", "TinyStories-valid", "en", 4303330, 4304186, 79300, 80156], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 450675792, 450679753, 80171, 84132], ["github/Ruby", "jekyll/jekyll", "Ruby", 461407953, 461414698, 84147, 90892], ["github/C++", "opencv/opencv", "C++", 394560245, 394568947, 90907, 99609], ["github/PHP", "laravel/framework", "PHP", 468059803, 468060176, 99624, 99997], ["tinystories/en", "TinyStories-valid", "en", 1950384, 1951235, 100012, 100863], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316627527, 316638178, 100878, 111529], ["tinystories/en", "TinyStories-valid", "en", 15656578, 15657368, 111544, 112334], ["github/PHP", "symfony/symfony", "PHP", 477527391, 477529216, 112349, 114174], ["tinystories/en", "TinyStories-valid", "en", 16324134, 16324439, 114189, 114494], ["github/Go", "gohugoio/hugo", "Go", 369465625, 369467962, 114509, 116846], ["tinystories/en", "TinyStories-valid", "en", 14201807, 14202877, 116861, 117931], ["github/PHP", "laravel/framework", "PHP", 463979777, 463979992, 117946, 118161], ["github/PHP", "laravel/framework", "PHP", 467967113, 467967492, 118176, 118555], ["github/TypeScript", "angular/angular", "TypeScript", 325097122, 325099689, 118570, 121137], ["tinystories/en", "TinyStories-valid", "en", 17404187, 17404767, 121152, 121732], ["github/C", "curl/curl", "C", 376134360, 376140852, 121747, 128239], ["stdlib/python", "python3.13 stdlib", "Python", 20018114, 20025009, 128254, 135149], ["github/PHP", "symfony/symfony", "PHP", 472473757, 472476008, 135151, 137402], ["github/Go", "gohugoio/hugo", "Go", 372549110, 372550875, 137417, 139182], ["tinystories/en", "TinyStories-valid", "en", 8839491, 8841243, 139197, 140949], ["tinystories/en", "TinyStories-valid", "en", 6499505, 6500213, 140964, 141672], ["github/PHP", "symfony/symfony", "PHP", 478068817, 478069734, 141687, 142604], ["github/Go", "prometheus/prometheus", "Go", 361175888, 361176811, 142619, 143542], ["tinystories/en", "TinyStories-valid", "en", 3752389, 3753191, 143557, 144359], ["github/Ruby", "rails/rails", "Ruby", 457067118, 457067301, 144374, 144557], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 317484372, 317486104, 144572, 146304], ["github/Rust", "rust-lang/cargo", "Rust", 349141283, 349145819, 146319, 150855], ["tinystories/en", "TinyStories-valid", "en", 14018034, 14018729, 150870, 151565], ["github/Ruby", "sinatra/sinatra", "Ruby", 462285580, 462286215, 151580, 152215], ["github/C#", "dotnet/aspnetcore", "C#", 439402441, 439411241, 152230, 161030], ["tinystories/en", "TinyStories-valid", "en", 7187511, 7188135, 161045, 161669], ["github/Java", "apache/commons-lang", "Java", 431302767, 431328377, 161684, 187294], ["tinystories/en", "TinyStories-valid", "en", 17302704, 17303358, 187309, 187963], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 484734489, 484756703, 187978, 210192], ["tinystories/en", "TinyStories-valid", "en", 395227, 396108, 210207, 211088], ["github/Scala", "scala/scala", "Scala", 504435429, 504458009, 211103, 233683], ["github/Ruby", "rails/rails", "Ruby", 456377213, 456379052, 233698, 235537], ["tinystories/en", "TinyStories-valid", "en", 6272579, 6273307, 235552, 236280], ["github/Rust", "rust-lang/cargo", "Rust", 347352193, 347353846, 236295, 237948], ["tinystories/en", "TinyStories-valid", "en", 5671741, 5672587, 237963, 238809], ["github/Rust", "rust-lang/cargo", "Rust", 347696280, 347696475, 238824, 239019], ["github/JavaScript", "webpack/webpack", "JavaScript", 308255146, 308261970, 239034, 245858], ["github/Rust", "serde-rs/serde", "Rust", 346857299, 346857439, 245873, 246013], ["tinystories/en", "TinyStories-valid", "en", 8936559, 8937414, 246028, 246883], ["github/C", "libuv/libuv", "C", 382305222, 382310465, 246898, 252141], ["tinystories/en", "TinyStories-valid", "en", 6736896, 6737607, 252156, 252867], ["github/Go", "gohugoio/hugo", "Go", 367133754, 367144651, 252882, 263779], ["tinystories/en", "TinyStories-valid", "en", 11483302, 11483943, 263794, 264435], ["github/PHP", "symfony/symfony", "PHP", 476924687, 476938303, 264450, 278066], ["github/Ruby", "rails/rails", "Ruby", 459667316, 459669255, 278081, 280020], ["tinystories/en", "TinyStories-valid", "en", 14022305, 14023135, 280035, 280865], ["github/C++", "protocolbuffers/protobuf", "C++", 404157383, 404183756, 280880, 307253], ["tinystories/en", "TinyStories-valid", "en", 18375417, 18376027, 307268, 307878], ["tinystories/en", "TinyStories-valid", "en", 16693065, 16694097, 307893, 308925], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 309807469, 309808990, 308940, 310461], ["tinystories/en", "TinyStories-valid", "en", 1167968, 1168702, 310476, 311210], ["github/Ruby", "rails/rails", "Ruby", 456301668, 456303178, 311225, 312735], ["tinystories/en", "TinyStories-valid", "en", 16018122, 16018823, 312750, 313451], ["github/Java", "spring-projects/spring-framework", "Java", 417644005, 417645253, 313466, 314714], ["github/C#", "dotnet/aspnetcore", "C#", 443260070, 443266372, 314729, 321031], ["tinystories/en", "TinyStories-valid", "en", 1186213, 1186996, 321046, 321829], ["tinystories/en", "TinyStories-valid", "en", 7081313, 7082109, 321844, 322640], ["github/JavaScript", "webpack/webpack", "JavaScript", 305002371, 305006289, 322655, 326573], ["github/Ruby", "rails/rails", "Ruby", 454931450, 454932158, 326588, 327296], ["tinystories/en", "TinyStories-valid", "en", 5348256, 5349398, 327311, 328453], ["github/C", "libuv/libuv", "C", 383576258, 383580778, 328468, 332988], ["github/Scala", "sbt/sbt", "Scala", 519857580, 519857667, 333003, 333090], ["github/TypeScript", "vuejs/core", "TypeScript", 321680472, 321714319, 333105, 366952], ["tinystories/en", "TinyStories-valid", "en", 1212081, 1212862, 366967, 367748], ["github/Java", "spring-projects/spring-framework", "Java", 422441949, 422451673, 367763, 377487], ["github/PHP", "laravel/framework", "PHP", 463237328, 463238805, 377502, 378979], ["tinystories/en", "TinyStories-valid", "en", 12378169, 12378781, 378994, 379606], ["tinystories/en", "TinyStories-valid", "en", 3797331, 3798106, 379621, 380396], ["github/Scala", "sbt/sbt", "Scala", 517043038, 517047565, 380411, 384938], ["github/JavaScript", "expressjs/express", "JavaScript", 300105648, 300108460, 384953, 387765], ["github/Swift", "Alamofire/Alamofire", "Swift", 496517104, 496525864, 387780, 396540], ["github/Go", "gohugoio/hugo", "Go", 367704246, 367709356, 396555, 401665], ["tinystories/en", "TinyStories-valid", "en", 17327545, 17328216, 401680, 402351], ["tinystories/en", "TinyStories-valid", "en", 11457499, 11458211, 402366, 403078], ["github/Python", "scikit-learn/scikit-learn", "Python", 298634481, 298679528, 403093, 448140], ["tinystories/en", "TinyStories-valid", "en", 6521334, 6522112, 448155, 448933], ["github/Java", "spring-projects/spring-framework", "Java", 423697436, 423697902, 448948, 449414], ["github/C", "curl/curl", "C", 373901303, 373902762, 449429, 450888], ["github/Scala", "sbt/sbt", "Scala", 517634255, 517634945, 450903, 451593], ["tinystories/en", "TinyStories-valid", "en", 4802900, 4803600, 451608, 452308], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315769051, 315772403, 452323, 455675], ["github/C++", "opencv/opencv", "C++", 397951717, 397953834, 455690, 457807], ["tinystories/en", "TinyStories-valid", "en", 8143509, 8144235, 457822, 458548], ["github/Scala", "playframework/playframework", "Scala", 511682393, 511684769, 458563, 460939], ["github/Java", "spring-projects/spring-framework", "Java", 420919332, 420925285, 460954, 466907], ["tinystories/en", "TinyStories-valid", "en", 4028463, 4029366, 466922, 467825], ["github/Go", "prometheus/prometheus", "Go", 359095624, 359098006, 467840, 470222], ["github/Ruby", "rails/rails", "Ruby", 454119669, 454127077, 470237, 477645], ["tinystories/en", "TinyStories-valid", "en", 9140711, 9141188, 477660, 478137], ["github/Scala", "scala/scala", "Scala", 505674110, 505674778, 478152, 478820], ["tinystories/en", "TinyStories-valid", "en", 18945686, 18946554, 478835, 479703], ["tinystories/en", "TinyStories-valid", "en", 956778, 957171, 479718, 480111], ["github/JavaScript", "webpack/webpack", "JavaScript", 300508135, 300510585, 480126, 482576], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494634285, 494642045, 482591, 490351], ["github/Java", "spring-projects/spring-framework", "Java", 417974622, 417975792, 490366, 491536], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515747286, 515751673, 491551, 495938], ["tinystories/en", "TinyStories-valid", "en", 11358902, 11359409, 495953, 496460], ["github/PHP", "guzzle/guzzle", "PHP", 479687339, 479701572, 496475, 510708], ["tinystories/en", "TinyStories-valid", "en", 15473278, 15474269, 510723, 511714], ["github/Java", "apache/commons-lang", "Java", 430984980, 430986766, 511729, 513515], ["tinystories/en", "TinyStories-valid", "en", 16876446, 16877115, 513530, 514199], ["tinystories/en", "TinyStories-valid", "en", 1919172, 1919666, 514214, 514708], ["github/Java", "spring-projects/spring-framework", "Java", 425235063, 425237410, 514723, 517070], ["github/Scala", "scala/scala", "Scala", 500678536, 500687142, 517085, 525691], ["tinystories/en", "TinyStories-valid", "en", 6503365, 6504209, 525706, 526550], ["github/Java", "spring-projects/spring-framework", "Java", 417865919, 417867050, 526565, 527696], ["tinystories/en", "TinyStories-valid", "en", 9886200, 9887003, 527711, 528514], ["stdlib/python", "python3.13 stdlib", "Python", 24811996, 24822976, 528529, 539509], ["github/Go", "prometheus/prometheus", "Go", 365048666, 365055997, 539511, 546842], ["tinystories/en", "TinyStories-valid", "en", 9807502, 9808295, 546857, 547650], ["github/C#", "dotnet/aspnetcore", "C#", 440987991, 441007702, 547665, 567376], ["github/C++", "protocolbuffers/protobuf", "C++", 403411670, 403430842, 567391, 586563], ["tinystories/en", "TinyStories-valid", "en", 4516378, 4517265, 586578, 587465], ["github/Java", "google/guava", "Java", 413639669, 413644538, 587480, 592349], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486661533, 486662999, 592364, 593830], ["github/Ruby", "rails/rails", "Ruby", 457141775, 457142172, 593845, 594242], ["tinystories/en", "TinyStories-valid", "en", 11766326, 11767075, 594257, 595006], ["github/Rust", "alacritty/alacritty", "Rust", 355827412, 355873645, 595021, 641254], ["tinystories/en", "TinyStories-valid", "en", 3117209, 3118309, 641269, 642369], ["github/Ruby", "rails/rails", "Ruby", 453525489, 453526606, 642384, 643501], ["tinystories/en", "TinyStories-valid", "en", 9106239, 9107078, 643516, 644355], ["github/PHP", "laravel/framework", "PHP", 466165696, 466166385, 644370, 645059], ["github/Ruby", "rails/rails", "Ruby", 453396520, 453396641, 645074, 645195], ["tinystories/en", "TinyStories-valid", "en", 2479578, 2480240, 645210, 645872], ["github/TypeScript", "nestjs/nest", "TypeScript", 332956289, 332958327, 645887, 647925], ["tinystories/en", "TinyStories-valid", "en", 7991506, 7992339, 647940, 648773], ["books/en", "PG #422", "en", 199401664, 200290403, 648788, 1537527], ["github/Ruby", "rails/rails", "Ruby", 453434454, 453435739, 1537529, 1538814], ["github/Scala", "playframework/playframework", "Scala", 512878219, 512885987, 1538829, 1546597], ["tinystories/en", "TinyStories-valid", "en", 15141510, 15142340, 1546612, 1547442], ["github/TypeScript", "angular/angular", "TypeScript", 324190904, 324192707, 1547457, 1549260], ["tinystories/en", "TinyStories-valid", "en", 6823391, 6824046, 1549275, 1549930], ["github/PHP", "laravel/framework", "PHP", 467346720, 467352939, 1549945, 1556164], ["tinystories/en", "TinyStories-valid", "en", 7732406, 7733045, 1556179, 1556818], ["github/Ruby", "rails/rails", "Ruby", 460367869, 460368502, 1556833, 1557466], ["github/TypeScript", "nestjs/nest", "TypeScript", 332442319, 332442865, 1557481, 1558027], ["github/TypeScript", "nestjs/nest", "TypeScript", 332444886, 332445375, 1558042, 1558531], ["tinystories/en", "TinyStories-valid", "en", 3291649, 3292535, 1558546, 1559432], ["github/TypeScript", "nestjs/nest", "TypeScript", 333241719, 333241935, 1559447, 1559663], ["tinystories/en", "TinyStories-valid", "en", 93722, 94498, 1559678, 1560454], ["github/C", "curl/curl", "C", 376285633, 376308165, 1560469, 1583001], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486715653, 486726520, 1583016, 1593883], ["github/TypeScript", "angular/angular", "TypeScript", 326079131, 326081167, 1593898, 1595934], ["tinystories/en", "TinyStories-valid", "en", 588465, 589043, 1595949, 1596527], ["tinystories/en", "TinyStories-valid", "en", 11525476, 11526174, 1596542, 1597240], ["github/Ruby", "rails/rails", "Ruby", 456333734, 456336498, 1597255, 1600019], ["github/PHP", "laravel/framework", "PHP", 467225818, 467226395, 1600034, 1600611], ["github/TypeScript", "angular/angular", "TypeScript", 330662531, 330663270, 1600626, 1601365], ["github/Go", "gohugoio/hugo", "Go", 369922080, 369934172, 1601380, 1613472], ["tinystories/en", "TinyStories-valid", "en", 18147181, 18147710, 1613487, 1614016], ["tinystories/en", "TinyStories-valid", "en", 11017789, 11018396, 1614031, 1614638], ["github/TypeScript", "nestjs/nest", "TypeScript", 337506173, 337507791, 1614653, 1616271], ["tinystories/en", "TinyStories-valid", "en", 18455839, 18456651, 1616286, 1617098], ["tinystories/en", "TinyStories-valid", "en", 13580835, 13581687, 1617113, 1617965], ["github/C++", "opencv/opencv", "C++", 394453087, 394465628, 1617980, 1630521], ["tinystories/en", "TinyStories-valid", "en", 1915153, 1915858, 1630536, 1631241], ["github/Java", "google/guava", "Java", 415104045, 415138259, 1631256, 1665470], ["books/fr", "PG #6966", "fr", 236896679, 237296823, 1665485, 2065629], ["tinystories/en", "TinyStories-valid", "en", 13060002, 13060558, 2065631, 2066187], ["tinystories/en", "TinyStories-valid", "en", 18928317, 18929118, 2066202, 2067003], ["tinystories/en", "TinyStories-valid", "en", 9812058, 9813313, 2067018, 2068273], ["github/Ruby", "rails/rails", "Ruby", 453025931, 453028756, 2068288, 2071113], ["github/PHP", "symfony/symfony", "PHP", 476058361, 476068846, 2071128, 2081613], ["github/Python", "scikit-learn/scikit-learn", "Python", 295988003, 295993737, 2081628, 2087362], ["github/Kotlin", "ktorio/ktor", "Kotlin", 488396437, 488397417, 2087377, 2088357], ["tinystories/en", "TinyStories-valid", "en", 5295090, 5296288, 2088372, 2089570], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491822198, 491822385, 2089585, 2089772], ["github/C#", "dotnet/aspnetcore", "C#", 445592776, 445600213, 2089787, 2097224], ["tinystories/en", "TinyStories-valid", "en", 7648653, 7649278, 2097239, 2097864], ["github/C++", "protocolbuffers/protobuf", "C++", 404102394, 404103307, 2097879, 2098792], ["tinystories/en", "TinyStories-valid", "en", 6912233, 6912984, 2098807, 2099558], ["github/Go", "gohugoio/hugo", "Go", 371038353, 371040207, 2099573, 2101427], ["github/TypeScript", "angular/angular", "TypeScript", 328361603, 328375199, 2101442, 2115038], ["tinystories/en", "TinyStories-valid", "en", 4473879, 4474774, 2115053, 2115948], ["github/C++", "protocolbuffers/protobuf", "C++", 408845201, 408848222, 2115963, 2118984], ["tinystories/en", "TinyStories-valid", "en", 19130317, 19131333, 2118999, 2120015], ["github/Python", "encode/httpx", "Python", 299470864, 299472803, 2120030, 2121969], ["tinystories/en", "TinyStories-valid", "en", 12331177, 12331835, 2121984, 2122642], ["tinystories/en", "TinyStories-valid", "en", 5355632, 5355958, 2122657, 2122983], ["github/Ruby", "rails/rails", "Ruby", 453136215, 453139383, 2122998, 2126166], ["github/Python", "django/django", "Python", 286464501, 286464775, 2126181, 2126455], ["github/C++", "protocolbuffers/protobuf", "C++", 401990951, 401992552, 2126470, 2128071], ["tinystories/en", "TinyStories-valid", "en", 3234371, 3235231, 2128086, 2128946], ["tinystories/en", "TinyStories-valid", "en", 8124198, 8125072, 2128961, 2129835], ["tinystories/en", "TinyStories-valid", "en", 11963185, 11963685, 2129850, 2130350], ["tinystories/en", "TinyStories-valid", "en", 11964267, 11964810, 2130365, 2130908], ["github/Ruby", "rails/rails", "Ruby", 453496389, 453496553, 2130923, 2131087], ["github/Scala", "sbt/sbt", "Scala", 519053841, 519088394, 2131102, 2165655], ["tinystories/en", "TinyStories-valid", "en", 522806, 523683, 2165670, 2166547], ["github/C#", "dotnet/aspnetcore", "C#", 440788215, 440792660, 2166562, 2171007], ["github/PHP", "laravel/framework", "PHP", 466385790, 466392939, 2171022, 2178171], ["github/Ruby", "rails/rails", "Ruby", 457059793, 457060269, 2178186, 2178662], ["github/JavaScript", "webpack/webpack", "JavaScript", 301051319, 301108295, 2178677, 2235653], ["tinystories/en", "TinyStories-valid", "en", 2888496, 2889012, 2235668, 2236184], ["github/TypeScript", "nestjs/nest", "TypeScript", 337640846, 337642132, 2236199, 2237485], ["tinystories/en", "TinyStories-valid", "en", 862312, 863014, 2237500, 2238202], ["github/Java", "apache/commons-lang", "Java", 433098740, 433102382, 2238217, 2241859], ["github/TypeScript", "nestjs/nest", "TypeScript", 333620358, 333620391, 2241874, 2241907], ["github/C++", "opencv/opencv", "C++", 394325676, 394335962, 2241922, 2252208], ["github/Rust", "tokio-rs/tokio", "Rust", 340567964, 340569170, 2252223, 2253429], ["github/TypeScript", "nestjs/nest", "TypeScript", 332776054, 332776614, 2253444, 2254004], ["github/Ruby", "rails/rails", "Ruby", 458921161, 458922156, 2254019, 2255014], ["tinystories/en", "TinyStories-valid", "en", 1665398, 1666106, 2255029, 2255737], ["github/TypeScript", "angular/angular", "TypeScript", 325084083, 325085026, 2255752, 2256695], ["tinystories/en", "TinyStories-valid", "en", 4133463, 4134123, 2256710, 2257370], ["github/Rust", "serde-rs/serde", "Rust", 346837272, 346838521, 2257385, 2258634], ["github/Java", "spring-projects/spring-framework", "Java", 420660194, 420662338, 2258649, 2260793], ["tinystories/en", "TinyStories-valid", "en", 8280149, 8280828, 2260808, 2261487], ["github/Rust", "tokio-rs/tokio", "Rust", 344962283, 344962895, 2261502, 2262114], ["tinystories/en", "TinyStories-valid", "en", 12411290, 12412239, 2262129, 2263078], ["github/Java", "google/guava", "Java", 416947800, 416949606, 2263093, 2264899], ["github/Python", "django/django", "Python", 289911414, 289926532, 2264914, 2280032], ["tinystories/en", "TinyStories-valid", "en", 9555076, 9555921, 2280047, 2280892], ["stdlib/python", "python3.13 stdlib", "Python", 29286242, 29295138, 2280907, 2289803], ["github/Ruby", "rails/rails", "Ruby", 454348114, 454350909, 2289805, 2292600], ["github/C#", "dotnet/aspnetcore", "C#", 440699672, 440704220, 2292615, 2297163], ["tinystories/en", "TinyStories-valid", "en", 19005484, 19006145, 2297178, 2297839], ["tinystories/en", "TinyStories-valid", "en", 9727619, 9728472, 2297854, 2298707], ["github/Java", "apache/commons-lang", "Java", 436062321, 436067394, 2298722, 2303795], ["github/C++", "google/leveldb", "C++", 392131230, 392134294, 2303810, 2306874], ["tinystories/en", "TinyStories-valid", "en", 6816252, 6816948, 2306889, 2307585], ["github/Go", "gohugoio/hugo", "Go", 372144757, 372166188, 2307600, 2329031], ["github/C", "curl/curl", "C", 378590951, 378601044, 2329046, 2339139], ["github/Rust", "serde-rs/serde", "Rust", 346229192, 346236350, 2339154, 2346312], ["tinystories/en", "TinyStories-valid", "en", 5901559, 5902650, 2346327, 2347418], ["github/C++", "protocolbuffers/protobuf", "C++", 401769060, 401770259, 2347433, 2348632], ["github/Java", "google/guava", "Java", 411963201, 411964723, 2348647, 2350169], ["tinystories/en", "TinyStories-valid", "en", 5349413, 5350157, 2350184, 2350928], ["github/C#", "dotnet/aspnetcore", "C#", 444990158, 444991857, 2350943, 2352642], ["tinystories/en", "TinyStories-valid", "en", 2402731, 2403458, 2352657, 2353384], ["github/Java", "spring-projects/spring-framework", "Java", 418277261, 418278128, 2353399, 2354266], ["github/Ruby", "rails/rails", "Ruby", 459767075, 459768797, 2354281, 2356003], ["github/C++", "protocolbuffers/protobuf", "C++", 402953304, 402955668, 2356018, 2358382], ["tinystories/en", "TinyStories-valid", "en", 13068185, 13068918, 2358397, 2359130], ["github/Java", "spring-projects/spring-framework", "Java", 420504559, 420505820, 2359145, 2360406], ["tinystories/en", "TinyStories-valid", "en", 4792777, 4793440, 2360421, 2361084], ["github/C++", "opencv/opencv", "C++", 397968506, 397970354, 2361099, 2362947], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449658201, 449660150, 2362962, 2364911], ["tinystories/en", "TinyStories-valid", "en", 6402599, 6403599, 2364926, 2365926], ["github/Ruby", "sinatra/sinatra", "Ruby", 462766939, 462768757, 2365941, 2367759], ["tinystories/en", "TinyStories-valid", "en", 16707954, 16710046, 2367774, 2369866], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 450131632, 450133174, 2369881, 2371423], ["github/Python", "django/django", "Python", 284110129, 284113297, 2371438, 2374606], ["tinystories/en", "TinyStories-valid", "en", 14661626, 14662259, 2374621, 2375254], ["github/C++", "protocolbuffers/protobuf", "C++", 402366636, 402373138, 2375269, 2381771], ["tinystories/en", "TinyStories-valid", "en", 5084152, 5084875, 2381786, 2382509], ["github/Scala", "sbt/sbt", "Scala", 519803302, 519803522, 2382524, 2382744], ["tinystories/en", "TinyStories-valid", "en", 4942042, 4942799, 2382759, 2383516], ["github/Ruby", "rails/rails", "Ruby", 455004461, 455005788, 2383531, 2384858], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 446980194, 446983306, 2384873, 2387985], ["tinystories/en", "TinyStories-valid", "en", 17737252, 17738863, 2388000, 2389611], ["github/PHP", "guzzle/guzzle", "PHP", 481158914, 481186498, 2389626, 2417210], ["github/C", "curl/curl", "C", 379340392, 379343755, 2417225, 2420588], ["github/C++", "protocolbuffers/protobuf", "C++", 408593865, 408596346, 2420603, 2423084], ["tinystories/en", "TinyStories-valid", "en", 3025336, 3026234, 2423099, 2423997], ["github/Ruby", "rails/rails", "Ruby", 457622717, 457624041, 2424012, 2425336], ["tinystories/en", "TinyStories-valid", "en", 1970273, 1970749, 2425351, 2425827], ["github/Java", "google/guava", "Java", 412737419, 412764481, 2425842, 2452904], ["tinystories/en", "TinyStories-valid", "en", 2681242, 2681978, 2452919, 2453655], ["github/Swift", "vapor/vapor", "Swift", 498426962, 498435181, 2453670, 2461889], ["github/Rust", "tokio-rs/tokio", "Rust", 343945238, 343963097, 2461904, 2479763], ["tinystories/en", "TinyStories-valid", "en", 14308621, 14309794, 2479778, 2480951], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 447465867, 447469406, 2480966, 2484505], ["tinystories/en", "TinyStories-valid", "en", 1413385, 1413881, 2484520, 2485016], ["tinystories/en", "TinyStories-valid", "en", 12558692, 12559417, 2485031, 2485756], ["github/Scala", "playframework/playframework", "Scala", 510226035, 510241719, 2485771, 2501455], ["tinystories/en", "TinyStories-valid", "en", 7839192, 7839912, 2501470, 2502190], ["tinystories/en", "TinyStories-valid", "en", 1034890, 1035533, 2502205, 2502848], ["github/C#", "dotnet/aspnetcore", "C#", 439333695, 439335491, 2502863, 2504659], ["tinystories/en", "TinyStories-valid", "en", 4731185, 4732163, 2504674, 2505652], ["tinystories/en", "TinyStories-valid", "en", 10552711, 10553677, 2505667, 2506633], ["github/C++", "opencv/opencv", "C++", 394353283, 394368792, 2506648, 2522157], ["tinystories/en", "TinyStories-valid", "en", 12519973, 12520667, 2522172, 2522866], ["tinystories/en", "TinyStories-valid", "en", 7538571, 7539199, 2522881, 2523509], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515362800, 515365454, 2523524, 2526178], ["tinystories/en", "TinyStories-valid", "en", 16968566, 16969583, 2526193, 2527210], ["tinystories/en", "TinyStories-valid", "en", 19462318, 19462979, 2527225, 2527886], ["tinystories/en", "TinyStories-valid", "en", 4135253, 4135972, 2527901, 2528620], ["github/Java", "google/guava", "Java", 414818242, 414819777, 2528635, 2530170], ["tinystories/en", "TinyStories-valid", "en", 18944242, 18944764, 2530185, 2530707], ["github/Scala", "sbt/sbt", "Scala", 519884703, 519884728, 2530722, 2530747], ["github/Rust", "rust-lang/cargo", "Rust", 350721153, 350721478, 2530762, 2531087], ["tinystories/en", "TinyStories-valid", "en", 17932246, 17933018, 2531102, 2531874], ["github/Java", "spring-projects/spring-framework", "Java", 422967421, 422970255, 2531889, 2534723], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 317191573, 317193767, 2534738, 2536932], ["tinystories/en", "TinyStories-valid", "en", 222262, 223477, 2536947, 2538162], ["github/C", "curl/curl", "C", 374219160, 374234661, 2538177, 2553678], ["github/JavaScript", "webpack/webpack", "JavaScript", 308526572, 308526631, 2553693, 2553752], ["github/Python", "django/django", "Python", 289954723, 289986246, 2553767, 2585290], ["github/JavaScript", "axios/axios", "JavaScript", 308755544, 308755576, 2585305, 2585337], ["tinystories/en", "TinyStories-valid", "en", 5433375, 5433956, 2585352, 2585933], ["github/Java", "spring-projects/spring-framework", "Java", 423309650, 423312482, 2585948, 2588780], ["github/C++", "opencv/opencv", "C++", 392498345, 392501176, 2588795, 2591626], ["github/Scala", "playframework/playframework", "Scala", 507375371, 507381698, 2591641, 2597968], ["tinystories/en", "TinyStories-valid", "en", 12413583, 12414482, 2597983, 2598882], ["tinystories/en", "TinyStories-valid", "en", 17342824, 17343634, 2598897, 2599707], ["github/PHP", "laravel/framework", "PHP", 469126694, 469131600, 2599722, 2604628], ["github/Rust", "tokio-rs/tokio", "Rust", 340427434, 340435737, 2604643, 2612946], ["tinystories/en", "TinyStories-valid", "en", 15173924, 15175385, 2612961, 2614422], ["github/C++", "opencv/opencv", "C++", 392729583, 392734158, 2614437, 2619012], ["tinystories/en", "TinyStories-valid", "en", 9693356, 9694238, 2619027, 2619909], ["tinystories/en", "TinyStories-valid", "en", 7925607, 7926265, 2619924, 2620582], ["github/PHP", "guzzle/guzzle", "PHP", 481358776, 481359772, 2620597, 2621593], ["github/Scala", "sbt/sbt", "Scala", 520038345, 520041886, 2621608, 2625149], ["tinystories/en", "TinyStories-valid", "en", 3598855, 3599439, 2625164, 2625748], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315879253, 315891153, 2625763, 2637663], ["tinystories/en", "TinyStories-valid", "en", 14354321, 14355413, 2637678, 2638770], ["github/PHP", "symfony/symfony", "PHP", 474893989, 474895471, 2638785, 2640267], ["github/C++", "google/leveldb", "C++", 392122756, 392125869, 2640282, 2643395], ["tinystories/en", "TinyStories-valid", "en", 16073825, 16074425, 2643410, 2644010], ["github/C#", "dotnet/aspnetcore", "C#", 442621616, 442643775, 2644025, 2666184], ["tinystories/en", "TinyStories-valid", "en", 1266180, 1266821, 2666199, 2666840], ["github/Rust", "tokio-rs/tokio", "Rust", 340146654, 340149279, 2666855, 2669480], ["github/PHP", "symfony/symfony", "PHP", 472188229, 472190306, 2669495, 2671572], ["tinystories/en", "TinyStories-valid", "en", 18884535, 18885637, 2671587, 2672689], ["github/Scala", "scala/scala", "Scala", 506437602, 506441554, 2672704, 2676656], ["github/C++", "google/leveldb", "C++", 392072919, 392075940, 2676671, 2679692], ["tinystories/en", "TinyStories-valid", "en", 17576203, 17577562, 2679707, 2681066], ["github/C++", "nlohmann/json", "C++", 385508318, 385509259, 2681081, 2682022], ["tinystories/en", "TinyStories-valid", "en", 13264734, 13265815, 2682037, 2683118], ["github/C++", "opencv/opencv", "C++", 393739603, 393740834, 2683133, 2684364], ["github/Rust", "tokio-rs/tokio", "Rust", 343154185, 343159164, 2684379, 2689358], ["github/C++", "opencv/opencv", "C++", 398126130, 398126494, 2689373, 2689737], ["github/JavaScript", "webpack/webpack", "JavaScript", 300434786, 300434846, 2689752, 2689812], ["github/C++", "nlohmann/json", "C++", 385634380, 385634777, 2689827, 2690224], ["tinystories/en", "TinyStories-valid", "en", 6030103, 6032028, 2690239, 2692164], ["github/JavaScript", "axios/axios", "JavaScript", 309100019, 309100907, 2692179, 2693067], ["github/Scala", "playframework/playframework", "Scala", 512182181, 512188980, 2693082, 2699881], ["tinystories/en", "TinyStories-valid", "en", 15051000, 15051402, 2699896, 2700298], ["github/C++", "protocolbuffers/protobuf", "C++", 401751342, 401754213, 2700313, 2703184], ["github/Go", "gohugoio/hugo", "Go", 368345510, 368390488, 2703199, 2748177], ["github/C", "curl/curl", "C", 380081232, 380084961, 2748192, 2751921], ["github/Java", "spring-projects/spring-framework", "Java", 422584889, 422622872, 2751936, 2789919], ["tinystories/en", "TinyStories-valid", "en", 12987895, 12988512, 2789934, 2790551], ["github/JavaScript", "webpack/webpack", "JavaScript", 303070047, 303071765, 2790566, 2792284], ["tinystories/en", "TinyStories-valid", "en", 4723816, 4724610, 2792299, 2793093], ["github/C++", "nlohmann/json", "C++", 385460693, 385461071, 2793108, 2793486], ["github/JavaScript", "webpack/webpack", "JavaScript", 300538695, 300538775, 2793501, 2793581], ["github/PHP", "guzzle/guzzle", "PHP", 480156242, 480167729, 2793596, 2805083], ["tinystories/en", "TinyStories-valid", "en", 13982842, 13983535, 2805098, 2805791], ["tinystories/en", "TinyStories-valid", "en", 8308090, 8308989, 2805806, 2806705], ["github/JavaScript", "expressjs/express", "JavaScript", 299597574, 299600618, 2806720, 2809764], ["tinystories/en", "TinyStories-valid", "en", 4391251, 4391741, 2809779, 2810269], ["github/Python", "django/django", "Python", 289132801, 289134836, 2810284, 2812319], ["tinystories/en", "TinyStories-valid", "en", 2680445, 2681227, 2812334, 2813116], ["github/Scala", "playframework/playframework", "Scala", 512497352, 512500829, 2813131, 2816608], ["tinystories/en", "TinyStories-valid", "en", 7653898, 7654571, 2816623, 2817296], ["github/Python", "django/django", "Python", 290646662, 290647100, 2817311, 2817749], ["tinystories/en", "TinyStories-valid", "en", 6097144, 6098007, 2817764, 2818627], ["github/Python", "scikit-learn/scikit-learn", "Python", 295921421, 295922138, 2818642, 2819359], ["github/C", "libuv/libuv", "C", 381120472, 381124413, 2819374, 2823315], ["tinystories/en", "TinyStories-valid", "en", 881524, 882493, 2823330, 2824299], ["github/Python", "django/django", "Python", 283607817, 283608823, 2824314, 2825320], ["github/Scala", "scala/scala", "Scala", 500053581, 500054953, 2825335, 2826707], ["tinystories/en", "TinyStories-valid", "en", 6698763, 6699288, 2826722, 2827247], ["tinystories/en", "TinyStories-valid", "en", 9045797, 9046488, 2827262, 2827953], ["github/PHP", "symfony/symfony", "PHP", 471385891, 471387039, 2827968, 2829116], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 450083619, 450084938, 2829131, 2830450], ["github/Swift", "Alamofire/Alamofire", "Swift", 496975288, 496977388, 2830465, 2832565], ["tinystories/en", "TinyStories-valid", "en", 15140119, 15140804, 2832580, 2833265], ["github/PHP", "laravel/framework", "PHP", 463992432, 463993142, 2833280, 2833990], ["tinystories/en", "TinyStories-valid", "en", 3488326, 3488754, 2834005, 2834433], ["tinystories/en", "TinyStories-valid", "en", 10406701, 10407557, 2834448, 2835304], ["github/Scala", "sbt/sbt", "Scala", 516536958, 516542502, 2835319, 2840863], ["github/PHP", "laravel/framework", "PHP", 464776533, 464778178, 2840878, 2842523], ["tinystories/en", "TinyStories-valid", "en", 3766356, 3767361, 2842538, 2843543], ["github/PHP", "laravel/framework", "PHP", 463581325, 463582012, 2843558, 2844245], ["tinystories/en", "TinyStories-valid", "en", 5476417, 5477764, 2844260, 2845607], ["github/C#", "dotnet/aspnetcore", "C#", 441216603, 441221638, 2845622, 2850657], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315362072, 315377401, 2850672, 2866001], ["github/PHP", "symfony/symfony", "PHP", 471972114, 471973999, 2866016, 2867901], ["github/Rust", "rust-lang/cargo", "Rust", 348174618, 348197461, 2867916, 2890759], ["tinystories/en", "TinyStories-valid", "en", 10091146, 10091758, 2890774, 2891386], ["github/Scala", "playframework/playframework", "Scala", 511425172, 511426257, 2891401, 2892486], ["tinystories/en", "TinyStories-valid", "en", 1395990, 1396856, 2892501, 2893367], ["github/PHP", "laravel/framework", "PHP", 468473189, 468473485, 2893382, 2893678], ["github/Java", "spring-projects/spring-framework", "Java", 425007123, 425010201, 2893693, 2896771], ["github/Python", "django/django", "Python", 282919111, 282932113, 2896786, 2909788], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515110045, 515111450, 2909803, 2911208], ["tinystories/en", "TinyStories-valid", "en", 6786402, 6787182, 2911223, 2912003], ["github/C", "curl/curl", "C", 375333123, 375340469, 2912018, 2919364], ["books/en", "PG #154", "en", 108407914, 109107485, 2919379, 3618950], ["github/PHP", "symfony/symfony", "PHP", 471813542, 471815789, 3618952, 3621199], ["tinystories/en", "TinyStories-valid", "en", 2088708, 2089483, 3621214, 3621989], ["tinystories/en", "TinyStories-valid", "en", 74729, 75573, 3622004, 3622848], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 451838884, 451840584, 3622863, 3624563], ["tinystories/en", "TinyStories-valid", "en", 15499502, 15500919, 3624578, 3625995], ["github/Scala", "sbt/sbt", "Scala", 516802019, 516810761, 3626010, 3634752], ["tinystories/en", "TinyStories-valid", "en", 15261020, 15262460, 3634767, 3636207], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449847465, 449849053, 3636222, 3637810], ["github/Swift", "vapor/vapor", "Swift", 497434836, 497435967, 3637825, 3638956], ["tinystories/en", "TinyStories-valid", "en", 11087786, 11088651, 3638971, 3639836], ["github/Java", "spring-projects/spring-framework", "Java", 418221693, 418235787, 3639851, 3653945], ["tinystories/en", "TinyStories-valid", "en", 13261924, 13262850, 3653960, 3654886], ["github/C", "curl/curl", "C", 380024945, 380026642, 3654901, 3656598], ["tinystories/en", "TinyStories-valid", "en", 17161581, 17162193, 3656613, 3657225], ["github/C#", "dotnet/aspnetcore", "C#", 445726551, 445728952, 3657240, 3659641], ["github/JavaScript", "webpack/webpack", "JavaScript", 305324548, 305326734, 3659656, 3661842], ["tinystories/en", "TinyStories-valid", "en", 1429737, 1430535, 3661857, 3662655], ["github/Scala", "playframework/playframework", "Scala", 512799177, 512800154, 3662670, 3663647], ["tinystories/en", "TinyStories-valid", "en", 14256690, 14257310, 3663662, 3664282], ["github/Scala", "playframework/playframework", "Scala", 514212306, 514212707, 3664297, 3664698], ["github/C++", "nlohmann/json", "C++", 389048128, 389101970, 3664713, 3718555], ["tinystories/en", "TinyStories-valid", "en", 18806112, 18806977, 3718570, 3719435], ["github/C#", "dotnet/aspnetcore", "C#", 438689854, 438691064, 3719450, 3720660], ["github/JavaScript", "expressjs/express", "JavaScript", 299571689, 299573952, 3720675, 3722938], ["github/C", "curl/curl", "C", 372841060, 372843278, 3722953, 3725171], ["tinystories/en", "TinyStories-valid", "en", 3553968, 3554571, 3725186, 3725789], ["github/Python", "django/django", "Python", 287604544, 287610918, 3725804, 3732178], ["github/Java", "square/okhttp", "Java", 428150576, 428151696, 3732193, 3733313], ["tinystories/en", "TinyStories-valid", "en", 3152889, 3153643, 3733328, 3734082], ["github/Rust", "serde-rs/serde", "Rust", 346055662, 346056456, 3734097, 3734891], ["github/JavaScript", "webpack/webpack", "JavaScript", 300469212, 300469261, 3734906, 3734955], ["stdlib/python", "python3.13 stdlib", "Python", 30480404, 30513034, 3734970, 3767600], ["github/Java", "spring-projects/spring-framework", "Java", 417599031, 417599963, 3767602, 3768534], ["github/C#", "dotnet/aspnetcore", "C#", 444043326, 444045037, 3768549, 3770260], ["github/PHP", "laravel/framework", "PHP", 467776387, 467794478, 3770275, 3788366], ["tinystories/en", "TinyStories-valid", "en", 6073321, 6073988, 3788381, 3789048], ["tinystories/en", "TinyStories-valid", "en", 2192595, 2193254, 3789063, 3789722], ["github/Scala", "sbt/sbt", "Scala", 517094156, 517101402, 3789737, 3796983], ["tinystories/en", "TinyStories-valid", "en", 3731774, 3732603, 3796998, 3797827], ["github/Go", "prometheus/prometheus", "Go", 365445287, 365446045, 3797842, 3798600], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515578248, 515578452, 3798615, 3798819], ["github/Java", "google/guava", "Java", 412446509, 412451826, 3798834, 3804151], ["tinystories/en", "TinyStories-valid", "en", 14958035, 14958648, 3804166, 3804779], ["tinystories/en", "TinyStories-valid", "en", 2828091, 2828722, 3804794, 3805425], ["github/C#", "dotnet/aspnetcore", "C#", 438581471, 438585016, 3805440, 3808985], ["tinystories/en", "TinyStories-valid", "en", 10561673, 10562557, 3809000, 3809884], ["github/Scala", "scala/scala", "Scala", 505703486, 505704160, 3809899, 3810573], ["tinystories/en", "TinyStories-valid", "en", 13165916, 13166707, 3810588, 3811379], ["github/Java", "spring-projects/spring-framework", "Java", 425614997, 425617925, 3811394, 3814322], ["github/Python", "scikit-learn/scikit-learn", "Python", 290974971, 290980522, 3814337, 3819888], ["tinystories/en", "TinyStories-valid", "en", 9546964, 9547629, 3819903, 3820568], ["github/Java", "square/okhttp", "Java", 426212444, 426212990, 3820583, 3821129], ["tinystories/en", "TinyStories-valid", "en", 13405247, 13406629, 3821144, 3822526], ["github/C", "curl/curl", "C", 372638328, 372646599, 3822541, 3830812], ["github/Scala", "playframework/playframework", "Scala", 510213826, 510217627, 3830827, 3834628], ["github/C#", "dotnet/aspnetcore", "C#", 440941103, 440942854, 3834643, 3836394], ["github/Java", "spring-projects/spring-framework", "Java", 424076137, 424078296, 3836409, 3838568], ["github/Rust", "rust-lang/cargo", "Rust", 350922275, 350936367, 3838583, 3852675], ["tinystories/en", "TinyStories-valid", "en", 7449238, 7450084, 3852690, 3853536], ["github/Kotlin", "ktorio/ktor", "Kotlin", 488645506, 488780492, 3853551, 3988537], ["tinystories/en", "TinyStories-valid", "en", 17056578, 17057369, 3988552, 3989343], ["github/Java", "spring-projects/spring-framework", "Java", 420584932, 420586666, 3989358, 3991092], ["tinystories/en", "TinyStories-valid", "en", 15945172, 15945999, 3991107, 3991934], ["github/Ruby", "rails/rails", "Ruby", 453933027, 453994831, 3991949, 4053753], ["tinystories/en", "TinyStories-valid", "en", 13504263, 13505074, 4053768, 4054579], ["github/Java", "spring-projects/spring-framework", "Java", 421960495, 421963632, 4054594, 4057731], ["github/PHP", "symfony/symfony", "PHP", 473668899, 473669984, 4057746, 4058831], ["github/Scala", "sbt/sbt", "Scala", 520022316, 520026248, 4058846, 4062778], ["tinystories/en", "TinyStories-valid", "en", 8223761, 8224294, 4062793, 4063326], ["github/PHP", "laravel/framework", "PHP", 468478791, 468479156, 4063341, 4063706], ["tinystories/en", "TinyStories-valid", "en", 2989292, 2989946, 4063721, 4064375], ["github/Python", "scikit-learn/scikit-learn", "Python", 292863997, 292870280, 4064390, 4070673], ["github/Java", "apache/commons-lang", "Java", 431563673, 431564943, 4070688, 4071958], ["tinystories/en", "TinyStories-valid", "en", 11264877, 11265457, 4071973, 4072553], ["github/PHP", "laravel/framework", "PHP", 466471032, 466472698, 4072568, 4074234], ["github/Scala", "playframework/playframework", "Scala", 508221470, 508221680, 4074249, 4074459], ["github/Scala", "sbt/sbt", "Scala", 519870297, 519870809, 4074474, 4074986], ["github/Java", "apache/commons-lang", "Java", 432273923, 432275816, 4075001, 4076894], ["tinystories/en", "TinyStories-valid", "en", 6350417, 6351411, 4076909, 4077903], ["github/Scala", "playframework/playframework", "Scala", 514215231, 514216453, 4077918, 4079140], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515606180, 515607376, 4079155, 4080351], ["github/C", "madler/zlib", "C", 383652051, 383653005, 4080366, 4081320], ["tinystories/en", "TinyStories-valid", "en", 2959837, 2960942, 4081335, 4082440], ["tinystories/en", "TinyStories-valid", "en", 160348, 160817, 4082455, 4082924], ["github/Python", "django/django", "Python", 283779631, 283779845, 4082939, 4083153], ["github/Rust", "rust-lang/cargo", "Rust", 353078554, 353078607, 4083168, 4083221], ["github/Java", "spring-projects/spring-framework", "Java", 421688734, 421694020, 4083236, 4088522], ["github/Python", "django/django", "Python", 288901645, 288901799, 4088537, 4088691], ["tinystories/en", "TinyStories-valid", "en", 16837291, 16837944, 4088706, 4089359], ["tinystories/en", "TinyStories-valid", "en", 2556300, 2556928, 4089374, 4090002], ["github/Swift", "vapor/vapor", "Swift", 497229540, 497234983, 4090017, 4095460], ["tinystories/en", "TinyStories-valid", "en", 5711368, 5712093, 4095475, 4096200], ["tinystories/en", "TinyStories-valid", "en", 11341634, 11342331, 4096215, 4096912], ["github/Java", "google/guava", "Java", 411081109, 411085601, 4096927, 4101419], ["tinystories/en", "TinyStories-valid", "en", 15324137, 15326085, 4101434, 4103382], ["github/TypeScript", "angular/angular", "TypeScript", 331932887, 332116254, 4103397, 4286764], ["github/Scala", "playframework/playframework", "Scala", 511333863, 511345953, 4286779, 4298869], ["tinystories/en", "TinyStories-valid", "en", 18336888, 18337657, 4298884, 4299653], ["tinystories/en", "TinyStories-valid", "en", 4020988, 4021617, 4299668, 4300297], ["github/C#", "dotnet/aspnetcore", "C#", 439770515, 439790748, 4300312, 4320545], ["tinystories/en", "TinyStories-valid", "en", 1910002, 1910794, 4320560, 4321352], ["tinystories/en", "TinyStories-valid", "en", 5659133, 5659843, 4321367, 4322077], ["github/Rust", "tokio-rs/tokio", "Rust", 342528382, 342541989, 4322092, 4335699], ["github/C++", "nlohmann/json", "C++", 386341647, 386349837, 4335714, 4343904], ["tinystories/en", "TinyStories-valid", "en", 16359605, 16360273, 4343919, 4344587], ["github/Java", "google/guava", "Java", 414671469, 414683605, 4344602, 4356738], ["tinystories/en", "TinyStories-valid", "en", 5325573, 5327379, 4356753, 4358559], ["github/PHP", "symfony/symfony", "PHP", 474403705, 474425674, 4358574, 4380543], ["tinystories/en", "TinyStories-valid", "en", 13921887, 13922667, 4380558, 4381338], ["tinystories/en", "TinyStories-valid", "en", 70725, 71209, 4381353, 4381837], ["tinystories/en", "TinyStories-valid", "en", 10001509, 10002257, 4381852, 4382600], ["github/C", "curl/curl", "C", 376030595, 376047008, 4382615, 4399028], ["github/C++", "opencv/opencv", "C++", 398466936, 398470003, 4399043, 4402110], ["tinystories/en", "TinyStories-valid", "en", 17037844, 17038526, 4402125, 4402807], ["tinystories/en", "TinyStories-valid", "en", 248098, 249057, 4402822, 4403781], ["github/Java", "square/okhttp", "Java", 429869728, 429871198, 4403796, 4405266], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515642096, 515642750, 4405281, 4405935], ["tinystories/en", "TinyStories-valid", "en", 13276968, 13277608, 4405950, 4406590], ["tinystories/en", "TinyStories-valid", "en", 18824112, 18824872, 4406605, 4407365], ["github/Rust", "rust-lang/cargo", "Rust", 352842706, 352843452, 4407380, 4408126], ["github/Java", "spring-projects/spring-framework", "Java", 424290622, 424292610, 4408141, 4410129], ["tinystories/en", "TinyStories-valid", "en", 489578, 490498, 4410144, 4411064], ["github/Java", "spring-projects/spring-framework", "Java", 417664138, 417665394, 4411079, 4412335], ["tinystories/en", "TinyStories-valid", "en", 10480580, 10481615, 4412350, 4413385], ["github/Java", "spring-projects/spring-framework", "Java", 420328102, 420331188, 4413400, 4416486], ["github/C++", "opencv/opencv", "C++", 392395437, 392405371, 4416501, 4426435], ["tinystories/en", "TinyStories-valid", "en", 17788501, 17789752, 4426450, 4427701], ["tinystories/en", "TinyStories-valid", "en", 12296397, 12297114, 4427716, 4428433], ["tinystories/en", "TinyStories-valid", "en", 18980039, 18981080, 4428448, 4429489], ["github/Java", "spring-projects/spring-framework", "Java", 424969480, 424973639, 4429504, 4433663], ["tinystories/en", "TinyStories-valid", "en", 2315740, 2316246, 4433678, 4434184], ["tinystories/en", "TinyStories-valid", "en", 11663420, 11665109, 4434199, 4435888], ["github/C#", "dotnet/aspnetcore", "C#", 444897500, 444901307, 4435903, 4439710], ["github/Java", "spring-projects/spring-framework", "Java", 418078596, 418079567, 4439725, 4440696], ["github/Scala", "scala/scala", "Scala", 500962283, 500987939, 4440711, 4466367], ["github/Java", "google/guava", "Java", 416497917, 416498988, 4466382, 4467453], ["tinystories/en", "TinyStories-valid", "en", 12166600, 12167572, 4467468, 4468440], ["github/PHP", "symfony/symfony", "PHP", 472546496, 472551621, 4468455, 4473580], ["tinystories/en", "TinyStories-valid", "en", 11833220, 11834764, 4473595, 4475139], ["books/fr", "PG #7770", "fr", 240967123, 241459094, 4475154, 4967125], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 450182689, 450183969, 4967127, 4968407], ["tinystories/en", "TinyStories-valid", "en", 12732423, 12733390, 4968422, 4969389], ["github/C", "curl/curl", "C", 379228841, 379230248, 4969404, 4970811], ["tinystories/en", "TinyStories-valid", "en", 12502467, 12503132, 4970826, 4971491], ["github/Python", "scikit-learn/scikit-learn", "Python", 293238734, 293287931, 4971506, 5020703], ["tinystories/en", "TinyStories-valid", "en", 4425799, 4426412, 5020718, 5021331], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515431730, 515432689, 5021346, 5022305], ["tinystories/en", "TinyStories-valid", "en", 18523788, 18524485, 5022320, 5023017], ["github/C", "curl/curl", "C", 374542658, 374544366, 5023032, 5024740], ["github/Swift", "Alamofire/Alamofire", "Swift", 495972947, 495975386, 5024755, 5027194], ["tinystories/en", "TinyStories-valid", "en", 4210578, 4211437, 5027209, 5028068], ["github/Java", "google/guava", "Java", 410355259, 410373312, 5028083, 5046136], ["tinystories/en", "TinyStories-valid", "en", 17145427, 17146239, 5046151, 5046963], ["books/en", "PG #318", "en", 166240926, 166598224, 5046978, 5404276], ["tinystories/en", "TinyStories-valid", "en", 1573576, 1574384, 5404278, 5405086], ["github/C", "curl/curl", "C", 374133231, 374134590, 5405101, 5406460], ["tinystories/en", "TinyStories-valid", "en", 17320236, 17320920, 5406475, 5407159], ["github/PHP", "laravel/framework", "PHP", 467935141, 467944908, 5407174, 5416941], ["tinystories/en", "TinyStories-valid", "en", 6602723, 6603598, 5416956, 5417831], ["tinystories/en", "TinyStories-valid", "en", 9193129, 9193862, 5417846, 5418579], ["tinystories/en", "TinyStories-valid", "en", 17542312, 17543455, 5418594, 5419737], ["tinystories/en", "TinyStories-valid", "en", 12168584, 12169088, 5419752, 5420256], ["github/JavaScript", "webpack/webpack", "JavaScript", 301211898, 301305972, 5420271, 5514345], ["github/Scala", "sbt/sbt", "Scala", 516341108, 516342005, 5514360, 5515257], ["github/C", "curl/curl", "C", 379814545, 379819242, 5515272, 5519969], ["tinystories/en", "TinyStories-valid", "en", 5635218, 5635920, 5519984, 5520686], ["tinystories/en", "TinyStories-valid", "en", 6322134, 6322914, 5520701, 5521481], ["github/Java", "square/okhttp", "Java", 426105173, 426107298, 5521496, 5523621], ["tinystories/en", "TinyStories-valid", "en", 16767443, 16768310, 5523636, 5524503], ["tinystories/en", "TinyStories-valid", "en", 18179732, 18180413, 5524518, 5525199], ["github/Java", "google/guava", "Java", 414194424, 414199008, 5525214, 5529798], ["github/Go", "prometheus/prometheus", "Go", 359963047, 360048779, 5529813, 5615545], ["tinystories/en", "TinyStories-valid", "en", 5943929, 5946244, 5615560, 5617875], ["github/C", "libuv/libuv", "C", 381005492, 381006003, 5617890, 5618401], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449336495, 449357408, 5618416, 5639329], ["github/Scala", "scala/scala", "Scala", 502786712, 502795356, 5639344, 5647988], ["tinystories/en", "TinyStories-valid", "en", 8347168, 8347970, 5648003, 5648805], ["github/Java", "google/guava", "Java", 415275297, 415278166, 5648820, 5651689], ["github/PHP", "guzzle/guzzle", "PHP", 479914064, 479922407, 5651704, 5660047], ["tinystories/en", "TinyStories-valid", "en", 6067179, 6068091, 5660062, 5660974], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515430440, 515431143, 5660989, 5661692], ["github/Java", "spring-projects/spring-framework", "Java", 425050611, 425050902, 5661707, 5661998], ["tinystories/en", "TinyStories-valid", "en", 9651411, 9652026, 5662013, 5662628], ["github/C", "curl/curl", "C", 375808429, 375812242, 5662643, 5666456], ["github/Java", "google/guava", "Java", 411092346, 411094867, 5666471, 5668992], ["github/Rust", "rust-lang/cargo", "Rust", 349220692, 349272474, 5669007, 5720789], ["tinystories/en", "TinyStories-valid", "en", 2667637, 2668325, 5720804, 5721492], ["tinystories/en", "TinyStories-valid", "en", 5617127, 5617719, 5721507, 5722099], ["github/Scala", "playframework/playframework", "Scala", 512291782, 512292848, 5722114, 5723180], ["tinystories/en", "TinyStories-valid", "en", 1121024, 1122083, 5723195, 5724254], ["tinystories/en", "TinyStories-valid", "en", 19358693, 19359459, 5724269, 5725035], ["github/Java", "google/guava", "Java", 417188866, 417193923, 5725050, 5730107], ["github/PHP", "laravel/framework", "PHP", 466802656, 466802898, 5730122, 5730364], ["github/Scala", "sbt/sbt", "Scala", 519621413, 519624316, 5730379, 5733282], ["tinystories/en", "TinyStories-valid", "en", 12779232, 12779988, 5733297, 5734053], ["github/PHP", "symfony/symfony", "PHP", 473904525, 473905235, 5734068, 5734778], ["tinystories/en", "TinyStories-valid", "en", 10311715, 10312143, 5734793, 5735221], ["github/C", "curl/curl", "C", 379943923, 379946227, 5735236, 5737540], ["tinystories/en", "TinyStories-valid", "en", 8173615, 8174226, 5737555, 5738166], ["github/Java", "spring-projects/spring-framework", "Java", 417994734, 417995517, 5738181, 5738964], ["tinystories/en", "TinyStories-valid", "en", 5588319, 5588779, 5738979, 5739439], ["github/Scala", "playframework/playframework", "Scala", 508046757, 508048206, 5739454, 5740903], ["tinystories/en", "TinyStories-valid", "en", 4405392, 4405940, 5740918, 5741466], ["github/C++", "opencv/opencv", "C++", 398980845, 399045737, 5741481, 5806373], ["github/Java", "spring-projects/spring-framework", "Java", 419920201, 419922304, 5806388, 5808491], ["tinystories/en", "TinyStories-valid", "en", 9627660, 9628480, 5808506, 5809326], ["github/Scala", "scala/scala", "Scala", 504931274, 504932382, 5809341, 5810449], ["github/Java", "spring-projects/spring-framework", "Java", 423458682, 423458804, 5810464, 5810586], ["tinystories/en", "TinyStories-valid", "en", 11269223, 11269946, 5810601, 5811324], ["github/Java", "apache/commons-lang", "Java", 432114434, 432116391, 5811339, 5813296], ["github/C", "curl/curl", "C", 378360261, 378361921, 5813311, 5814971], ["tinystories/en", "TinyStories-valid", "en", 15114418, 15115109, 5814986, 5815677], ["github/Java", "apache/commons-lang", "Java", 436126660, 436127975, 5815692, 5817007], ["github/Scala", "sbt/sbt", "Scala", 519050595, 519053826, 5817022, 5820253], ["tinystories/en", "TinyStories-valid", "en", 7642308, 7643153, 5820268, 5821113], ["tinystories/en", "TinyStories-valid", "en", 3052108, 3052626, 5821128, 5821646], ["github/Java", "spring-projects/spring-framework", "Java", 424382303, 424384389, 5821661, 5823747], ["github/PHP", "laravel/framework", "PHP", 464895730, 464906608, 5823762, 5834640], ["tinystories/en", "TinyStories-valid", "en", 18769356, 18770272, 5834655, 5835571], ["github/Scala", "playframework/playframework", "Scala", 513146831, 513147373, 5835586, 5836128], ["github/Python", "django/django", "Python", 284963829, 284964039, 5836143, 5836353], ["github/Scala", "sbt/sbt", "Scala", 519882751, 519882796, 5836368, 5836413], ["github/Java", "spring-projects/spring-framework", "Java", 417827816, 417829463, 5836428, 5838075], ["tinystories/en", "TinyStories-valid", "en", 5261456, 5262606, 5838090, 5839240], ["github/C", "libuv/libuv", "C", 382285496, 382288772, 5839255, 5842531], ["github/Python", "scikit-learn/scikit-learn", "Python", 292518631, 292521120, 5842546, 5845035], ["tinystories/en", "TinyStories-valid", "en", 7490372, 7491139, 5845050, 5845817], ["github/Scala", "sbt/sbt", "Scala", 517872253, 517877446, 5845832, 5851025], ["tinystories/en", "TinyStories-valid", "en", 4559862, 4560872, 5851040, 5852050], ["github/Ruby", "rails/rails", "Ruby", 458743876, 458744068, 5852065, 5852257], ["github/C#", "dotnet/aspnetcore", "C#", 441380101, 441385102, 5852272, 5857273], ["tinystories/en", "TinyStories-valid", "en", 10573209, 10573562, 5857288, 5857641], ["tinystories/en", "TinyStories-valid", "en", 6932591, 6933438, 5857656, 5858503], ["tinystories/en", "TinyStories-valid", "en", 1619915, 1620719, 5858518, 5859322], ["github/Java", "apache/commons-lang", "Java", 434276731, 434289984, 5859337, 5872590], ["github/C", "curl/curl", "C", 376348741, 376351927, 5872605, 5875791], ["tinystories/en", "TinyStories-valid", "en", 19201321, 19202486, 5875806, 5876971], ["tinystories/en", "TinyStories-valid", "en", 11974661, 11975708, 5876986, 5878033], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449917967, 449919429, 5878048, 5879510], ["tinystories/en", "TinyStories-valid", "en", 12349294, 12349867, 5879525, 5880098], ["github/Ruby", "rails/rails", "Ruby", 455735409, 455739924, 5880113, 5884628], ["github/Scala", "sbt/sbt", "Scala", 519011360, 519017305, 5884643, 5890588], ["tinystories/en", "TinyStories-valid", "en", 9996635, 9997527, 5890603, 5891495], ["github/Python", "django/django", "Python", 289142313, 289152683, 5891510, 5901880], ["github/C#", "dotnet/aspnetcore", "C#", 439240342, 439240769, 5901895, 5902322], ["tinystories/en", "TinyStories-valid", "en", 16376477, 16377101, 5902337, 5902961], ["github/PHP", "symfony/symfony", "PHP", 477183619, 477193085, 5902976, 5912442], ["tinystories/en", "TinyStories-valid", "en", 10794663, 10795608, 5912457, 5913402], ["tinystories/en", "TinyStories-valid", "en", 3146728, 3147421, 5913417, 5914110], ["github/Scala", "playframework/playframework", "Scala", 510768824, 510769750, 5914125, 5915051], ["github/C", "curl/curl", "C", 378758447, 378762733, 5915066, 5919352], ["tinystories/en", "TinyStories-valid", "en", 1413896, 1414583, 5919367, 5920054], ["github/Scala", "playframework/playframework", "Scala", 511192183, 511192422, 5920069, 5920308], ["github/Scala", "playframework/playframework", "Scala", 509523127, 509523482, 5920323, 5920678], ["github/Scala", "sbt/sbt", "Scala", 519780436, 519780629, 5920693, 5920886], ["tinystories/en", "TinyStories-valid", "en", 5772448, 5773385, 5920901, 5921838], ["github/Scala", "playframework/playframework", "Scala", 511597907, 511598461, 5921853, 5922407], ["github/Ruby", "rails/rails", "Ruby", 453251439, 453252421, 5922422, 5923404], ["tinystories/en", "TinyStories-valid", "en", 2214516, 2215240, 5923419, 5924143], ["github/Scala", "sbt/sbt", "Scala", 519448047, 519449962, 5924158, 5926073], ["github/Java", "apache/commons-lang", "Java", 436008634, 436020487, 5926088, 5937941], ["tinystories/en", "TinyStories-valid", "en", 12363197, 12364032, 5937956, 5938791], ["github/Python", "django/django", "Python", 282451259, 282452570, 5938806, 5940117], ["tinystories/en", "TinyStories-valid", "en", 2665559, 2666303, 5940132, 5940876], ["tinystories/en", "TinyStories-valid", "en", 14979680, 14980394, 5940891, 5941605], ["github/Ruby", "rails/rails", "Ruby", 454666625, 454668485, 5941620, 5943480], ["tinystories/en", "TinyStories-valid", "en", 5416216, 5416954, 5943495, 5944233], ["github/C", "libuv/libuv", "C", 383215517, 383217973, 5944248, 5946704], ["tinystories/en", "TinyStories-valid", "en", 3403475, 3404812, 5946719, 5948056], ["github/Rust", "rust-lang/cargo", "Rust", 352985889, 352986917, 5948071, 5949099], ["tinystories/en", "TinyStories-valid", "en", 689018, 689783, 5949114, 5949879], ["github/Rust", "serde-rs/serde", "Rust", 346847044, 346847537, 5949894, 5950387], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515449909, 515452875, 5950402, 5953368], ["github/Rust", "serde-rs/serde", "Rust", 346847552, 346848021, 5953383, 5953852], ["tinystories/en", "TinyStories-valid", "en", 16277790, 16278845, 5953867, 5954922], ["github/Ruby", "rails/rails", "Ruby", 453786692, 453788645, 5954937, 5956890], ["stdlib/python", "python3.13 stdlib", "Python", 24447340, 24468969, 5956905, 5978534], ["tinystories/en", "TinyStories-valid", "en", 8019411, 8020192, 5978536, 5979317], ["github/PHP", "laravel/framework", "PHP", 469474780, 469486686, 5979332, 5991238], ["tinystories/en", "TinyStories-valid", "en", 9833715, 9834626, 5991253, 5992164], ["github/C#", "dotnet/aspnetcore", "C#", 445471005, 445491195, 5992179, 6012369], ["tinystories/en", "TinyStories-valid", "en", 3063460, 3063975, 6012384, 6012899], ["github/C++", "nlohmann/json", "C++", 387119076, 387119805, 6012914, 6013643], ["tinystories/en", "TinyStories-valid", "en", 3703559, 3704026, 6013658, 6014125], ["github/C++", "protocolbuffers/protobuf", "C++", 403387062, 403388002, 6014140, 6015080], ["tinystories/en", "TinyStories-valid", "en", 13451986, 13453433, 6015095, 6016542], ["github/C++", "nlohmann/json", "C++", 385612702, 385613578, 6016557, 6017433], ["github/C", "curl/curl", "C", 374162274, 374170276, 6017448, 6025450], ["github/Scala", "scala/scala", "Scala", 504635432, 504656867, 6025465, 6046900], ["github/Python", "django/django", "Python", 284820504, 284839248, 6046915, 6065659], ["tinystories/en", "TinyStories-valid", "en", 15511208, 15514492, 6065674, 6068958], ["github/Rust", "alacritty/alacritty", "Rust", 355329760, 355343259, 6068973, 6082472], ["tinystories/en", "TinyStories-valid", "en", 11596384, 11597544, 6082487, 6083647], ["github/Java", "spring-projects/spring-framework", "Java", 422748122, 422779676, 6083662, 6115216], ["github/PHP", "laravel/framework", "PHP", 467067735, 467070810, 6115231, 6118306], ["tinystories/en", "TinyStories-valid", "en", 14243474, 14244097, 6118321, 6118944], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491193294, 491193603, 6118959, 6119268], ["tinystories/en", "TinyStories-valid", "en", 4071608, 4072438, 6119283, 6120113], ["tinystories/en", "TinyStories-valid", "en", 14481364, 14482709, 6120128, 6121473], ["github/JavaScript", "webpack/webpack", "JavaScript", 300921178, 300921527, 6121488, 6121837], ["tinystories/en", "TinyStories-valid", "en", 17904581, 17906266, 6121852, 6123537], ["github/JavaScript", "axios/axios", "JavaScript", 309509008, 309509725, 6123552, 6124269], ["github/JavaScript", "webpack/webpack", "JavaScript", 300450065, 300450614, 6124284, 6124833], ["github/JavaScript", "webpack/webpack", "JavaScript", 307115064, 307115673, 6124848, 6125457], ["tinystories/en", "TinyStories-valid", "en", 15063096, 15064058, 6125472, 6126434], ["github/PHP", "laravel/framework", "PHP", 465177495, 465183808, 6126449, 6132762], ["github/Rust", "rust-lang/cargo", "Rust", 352967268, 352967632, 6132777, 6133141], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491167039, 491174319, 6133156, 6140436], ["tinystories/en", "TinyStories-valid", "en", 9664940, 9665856, 6140451, 6141367], ["github/Rust", "BurntSushi/ripgrep", "Rust", 338422837, 338424961, 6141382, 6143506], ["tinystories/en", "TinyStories-valid", "en", 540103, 540620, 6143521, 6144038], ["github/Scala", "playframework/playframework", "Scala", 514078175, 514080289, 6144053, 6146167], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449609655, 449611120, 6146182, 6147647], ["tinystories/en", "TinyStories-valid", "en", 11073730, 11074769, 6147662, 6148701], ["github/Python", "django/django", "Python", 288083663, 288085511, 6148716, 6150564], ["github/C#", "dotnet/aspnetcore", "C#", 445198628, 445199047, 6150579, 6150998], ["tinystories/en", "TinyStories-valid", "en", 17025358, 17026255, 6151013, 6151910], ["tinystories/en", "TinyStories-valid", "en", 8225071, 8225703, 6151925, 6152557], ["github/JavaScript", "webpack/webpack", "JavaScript", 308081001, 308089114, 6152572, 6160685], ["tinystories/en", "TinyStories-valid", "en", 8215898, 8216689, 6160700, 6161491], ["github/PHP", "laravel/framework", "PHP", 465822183, 465825587, 6161506, 6164910], ["github/Go", "gohugoio/hugo", "Go", 371011021, 371014371, 6164925, 6168275], ["tinystories/en", "TinyStories-valid", "en", 15567751, 15568570, 6168290, 6169109], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494784121, 494784616, 6169124, 6169619], ["tinystories/en", "TinyStories-valid", "en", 3504199, 3504991, 6169634, 6170426], ["github/PHP", "laravel/framework", "PHP", 463684940, 463685293, 6170441, 6170794], ["github/Python", "django/django", "Python", 290206293, 290213167, 6170809, 6177683], ["tinystories/en", "TinyStories-valid", "en", 11189847, 11190745, 6177698, 6178596], ["github/Scala", "playframework/playframework", "Scala", 510581874, 510591829, 6178611, 6188566], ["github/TypeScript", "nestjs/nest", "TypeScript", 336453074, 336453733, 6188581, 6189240], ["github/PHP", "laravel/framework", "PHP", 466671314, 466672435, 6189255, 6190376], ["tinystories/en", "TinyStories-valid", "en", 12038814, 12039426, 6190391, 6191003], ["github/Ruby", "rails/rails", "Ruby", 457433628, 457453969, 6191018, 6211359], ["github/Go", "gohugoio/hugo", "Go", 366805993, 366807417, 6211374, 6212798], ["tinystories/en", "TinyStories-valid", "en", 19045692, 19046398, 6212813, 6213519], ["github/Go", "gohugoio/hugo", "Go", 367047205, 367047231, 6213534, 6213560], ["tinystories/en", "TinyStories-valid", "en", 5156482, 5157300, 6213575, 6214393], ["github/Go", "prometheus/prometheus", "Go", 365448621, 365449622, 6214408, 6215409], ["tinystories/en", "TinyStories-valid", "en", 12566918, 12567860, 6215424, 6216366], ["github/Java", "google/guava", "Java", 413784085, 413799931, 6216381, 6232227], ["tinystories/en", "TinyStories-valid", "en", 19431084, 19431816, 6232242, 6232974], ["github/Go", "prometheus/prometheus", "Go", 365480530, 365481966, 6232989, 6234425], ["github/Python", "django/django", "Python", 282416865, 282417594, 6234440, 6235169], ["github/PHP", "laravel/framework", "PHP", 469572601, 469578702, 6235184, 6241285], ["github/JavaScript", "webpack/webpack", "JavaScript", 302966676, 302972810, 6241300, 6247434], ["tinystories/en", "TinyStories-valid", "en", 18188871, 18189685, 6247449, 6248263], ["tinystories/en", "TinyStories-valid", "en", 16201343, 16202083, 6248278, 6249018], ["github/Python", "scikit-learn/scikit-learn", "Python", 292268689, 292270759, 6249033, 6251103], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515091024, 515091405, 6251118, 6251499], ["tinystories/en", "TinyStories-valid", "en", 1064523, 1065222, 6251514, 6252213], ["github/Kotlin", "ktorio/ktor", "Kotlin", 495454179, 495466155, 6252228, 6264204], ["tinystories/en", "TinyStories-valid", "en", 8087873, 8088612, 6264219, 6264958], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 448922743, 448939726, 6264973, 6281956], ["tinystories/en", "TinyStories-valid", "en", 3896959, 3897313, 6281971, 6282325], ["tinystories/en", "TinyStories-valid", "en", 13319867, 13320627, 6282340, 6283100], ["github/Python", "django/django", "Python", 282470420, 282474350, 6283115, 6287045], ["tinystories/en", "TinyStories-valid", "en", 7683700, 7684321, 6287060, 6287681], ["github/PHP", "laravel/framework", "PHP", 469147941, 469151353, 6287696, 6291108], ["tinystories/en", "TinyStories-valid", "en", 9861978, 9862704, 6291123, 6291849], ["tinystories/en", "TinyStories-valid", "en", 7968017, 7968877, 6291864, 6292724], ["github/TypeScript", "vuejs/core", "TypeScript", 321900394, 321921340, 6292739, 6313685], ["tinystories/en", "TinyStories-valid", "en", 8041993, 8042766, 6313700, 6314473], ["github/PHP", "guzzle/guzzle", "PHP", 479797866, 479798384, 6314488, 6315006], ["github/Python", "django/django", "Python", 285017448, 285018719, 6315021, 6316292], ["github/Go", "gohugoio/hugo", "Go", 371026838, 371038338, 6316307, 6327807], ["tinystories/en", "TinyStories-valid", "en", 47987, 48753, 6327822, 6328588], ["github/Java", "square/okhttp", "Java", 430232870, 430241298, 6328603, 6337031], ["github/PHP", "laravel/framework", "PHP", 465847687, 465848563, 6337046, 6337922], ["github/C++", "opencv/opencv", "C++", 392595591, 392668143, 6337937, 6410489], ["tinystories/en", "TinyStories-valid", "en", 12157905, 12158394, 6410504, 6410993], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515157217, 515157716, 6411008, 6411507], ["github/PHP", "symfony/symfony", "PHP", 478299923, 478300623, 6411522, 6412222], ["tinystories/en", "TinyStories-valid", "en", 2053911, 2054719, 6412237, 6413045], ["github/PHP", "laravel/framework", "PHP", 467924391, 467924812, 6413060, 6413481], ["github/Python", "scikit-learn/scikit-learn", "Python", 291054753, 291057511, 6413496, 6416254], ["tinystories/en", "TinyStories-valid", "en", 10520421, 10521219, 6416269, 6417067], ["github/Swift", "Alamofire/Alamofire", "Swift", 496052458, 496073752, 6417082, 6438376], ["stdlib/python", "python3.13 stdlib", "Python", 26021897, 26022251, 6438391, 6438745], ["tinystories/en", "TinyStories-valid", "en", 13209378, 13210244, 6438747, 6439613], ["github/PHP", "laravel/framework", "PHP", 467667150, 467669638, 6439628, 6442116], ["github/Java", "spring-projects/spring-framework", "Java", 418149891, 418151411, 6442131, 6443651], ["tinystories/en", "TinyStories-valid", "en", 8845394, 8846235, 6443666, 6444507], ["github/Python", "scikit-learn/scikit-learn", "Python", 295808484, 295809840, 6444522, 6445878], ["tinystories/en", "TinyStories-valid", "en", 9163669, 9164353, 6445893, 6446577], ["tinystories/en", "TinyStories-valid", "en", 11304367, 11305039, 6446592, 6447264], ["github/PHP", "symfony/symfony", "PHP", 477968422, 477972064, 6447279, 6450921], ["tinystories/en", "TinyStories-valid", "en", 18004041, 18005764, 6450936, 6452659], ["github/Rust", "rust-lang/cargo", "Rust", 351008757, 351054715, 6452674, 6498632], ["tinystories/en", "TinyStories-valid", "en", 9999893, 10000550, 6498647, 6499304], ["github/Java", "square/okhttp", "Java", 427928220, 427940692, 6499319, 6511791], ["tinystories/en", "TinyStories-valid", "en", 12133763, 12134883, 6511806, 6512926], ["github/Go", "gohugoio/hugo", "Go", 367162970, 367166726, 6512941, 6516697], ["github/PHP", "laravel/framework", "PHP", 470718098, 470721062, 6516712, 6519676], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515372569, 515373144, 6519691, 6520266], ["tinystories/en", "TinyStories-valid", "en", 1330663, 1332070, 6520281, 6521688], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486986876, 486998077, 6521703, 6532904], ["tinystories/en", "TinyStories-valid", "en", 1675498, 1676315, 6532919, 6533736], ["github/TypeScript", "vuejs/core", "TypeScript", 320420159, 320424147, 6533751, 6537739], ["github/Go", "prometheus/prometheus", "Go", 361160426, 361161180, 6537754, 6538508], ["tinystories/en", "TinyStories-valid", "en", 6127013, 6127805, 6538523, 6539315], ["github/Scala", "scala/scala", "Scala", 500745114, 500786470, 6539330, 6580686], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 313816697, 313847917, 6580701, 6611921], ["github/Java", "square/okhttp", "Java", 426978467, 426978548, 6611936, 6612017], ["tinystories/en", "TinyStories-valid", "en", 7148567, 7149286, 6612032, 6612751], ["github/Python", "scikit-learn/scikit-learn", "Python", 292503565, 292518616, 6612766, 6627817], ["github/Go", "gohugoio/hugo", "Go", 370803068, 370804190, 6627832, 6628954], ["github/Java", "apache/commons-lang", "Java", 433055310, 433057309, 6628969, 6630968], ["github/TypeScript", "nestjs/nest", "TypeScript", 337928037, 337928382, 6630983, 6631328], ["tinystories/en", "TinyStories-valid", "en", 4403310, 4404337, 6631343, 6632370], ["github/TypeScript", "nestjs/nest", "TypeScript", 332772159, 332772703, 6632385, 6632929], ["github/Java", "spring-projects/spring-framework", "Java", 418357445, 418358457, 6632944, 6633956], ["tinystories/en", "TinyStories-valid", "en", 3584646, 3585197, 6633971, 6634522], ["github/TypeScript", "angular/angular", "TypeScript", 328291254, 328291967, 6634537, 6635250], ["github/Ruby", "jekyll/jekyll", "Ruby", 461972007, 461977524, 6635265, 6640782], ["github/Java", "square/okhttp", "Java", 426587035, 426587571, 6640797, 6641333], ["github/Go", "prometheus/prometheus", "Go", 365904808, 365907393, 6641348, 6643933], ["tinystories/en", "TinyStories-valid", "en", 1592620, 1593543, 6643948, 6644871], ["tinystories/en", "TinyStories-valid", "en", 7659404, 7659988, 6644886, 6645470], ["tinystories/en", "TinyStories-valid", "en", 5440378, 5441077, 6645485, 6646184], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515142319, 515142600, 6646199, 6646480], ["tinystories/en", "TinyStories-valid", "en", 4372763, 4373583, 6646495, 6647315], ["github/Go", "gohugoio/hugo", "Go", 372009914, 372011341, 6647330, 6648757], ["github/Java", "spring-projects/spring-framework", "Java", 420542447, 420551693, 6648772, 6658018], ["tinystories/en", "TinyStories-valid", "en", 15902377, 15903215, 6658033, 6658871], ["github/Go", "prometheus/prometheus", "Go", 361157398, 361158149, 6658886, 6659637], ["tinystories/en", "TinyStories-valid", "en", 1742392, 1742989, 6659652, 6660249], ["tinystories/en", "TinyStories-valid", "en", 7647307, 7647894, 6660264, 6660851], ["tinystories/en", "TinyStories-valid", "en", 15576690, 15577438, 6660866, 6661614], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487758417, 487762873, 6661629, 6666085], ["books/en", "PG #22", "en", 43773806, 45267808, 6666100, 8160102], ["github/TypeScript", "vuejs/core", "TypeScript", 323829247, 323841083, 8160104, 8171940], ["tinystories/en", "TinyStories-valid", "en", 14685043, 14685879, 8171955, 8172791], ["tinystories/en", "TinyStories-valid", "en", 12029413, 12030022, 8172806, 8173415], ["github/Java", "spring-projects/spring-framework", "Java", 422964715, 422967406, 8173430, 8176121], ["tinystories/en", "TinyStories-valid", "en", 12693307, 12694742, 8176136, 8177571], ["github/Java", "spring-projects/spring-framework", "Java", 420362334, 420362514, 8177586, 8177766], ["github/Java", "spring-projects/spring-framework", "Java", 417808176, 417809279, 8177781, 8178884], ["tinystories/en", "TinyStories-valid", "en", 3129709, 3130377, 8178899, 8179567], ["github/Java", "apache/commons-lang", "Java", 436240010, 436241776, 8179582, 8181348], ["tinystories/en", "TinyStories-valid", "en", 11268390, 11269208, 8181363, 8182181], ["github/Python", "django/django", "Python", 283295651, 283302951, 8182196, 8189496], ["tinystories/en", "TinyStories-valid", "en", 18831551, 18832353, 8189511, 8190313], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481460674, 481463914, 8190328, 8193568], ["github/Java", "spring-projects/spring-framework", "Java", 419592075, 419593360, 8193583, 8194868], ["tinystories/en", "TinyStories-valid", "en", 9887018, 9887882, 8194883, 8195747], ["github/Java", "apache/commons-lang", "Java", 436393254, 436395810, 8195762, 8198318], ["github/TypeScript", "vuejs/core", "TypeScript", 323391157, 323392481, 8198333, 8199657], ["github/Ruby", "jekyll/jekyll", "Ruby", 461664977, 461671886, 8199672, 8206581], ["github/Go", "gohugoio/hugo", "Go", 368817158, 368831373, 8206596, 8220811], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489379122, 489379471, 8220826, 8221175], ["tinystories/en", "TinyStories-valid", "en", 17747781, 17750186, 8221190, 8223595], ["github/TypeScript", "vuejs/core", "TypeScript", 319698063, 319698825, 8223610, 8224372], ["github/Java", "spring-projects/spring-framework", "Java", 425564475, 425565746, 8224387, 8225658], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486285084, 486285596, 8225673, 8226185], ["github/TypeScript", "nestjs/nest", "TypeScript", 337468473, 337468874, 8226200, 8226601], ["github/TypeScript", "nestjs/nest", "TypeScript", 337449798, 337450192, 8226616, 8227010], ["github/JavaScript", "webpack/webpack", "JavaScript", 300574329, 300574379, 8227025, 8227075], ["github/Java", "spring-projects/spring-framework", "Java", 423051281, 423052985, 8227090, 8228794], ["github/TypeScript", "nestjs/nest", "TypeScript", 337728135, 337728434, 8228809, 8229108], ["tinystories/en", "TinyStories-valid", "en", 3017609, 3018100, 8229123, 8229614], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492884034, 492885267, 8229629, 8230862], ["github/Python", "scikit-learn/scikit-learn", "Python", 291650109, 291652198, 8230877, 8232966], ["tinystories/en", "TinyStories-valid", "en", 18966849, 18967788, 8232981, 8233920], ["github/C++", "nlohmann/json", "C++", 385434194, 385435049, 8233935, 8234790], ["github/TypeScript", "nestjs/nest", "TypeScript", 334452253, 334454796, 8234805, 8237348], ["github/JavaScript", "expressjs/express", "JavaScript", 299938100, 299941636, 8237363, 8240899], ["tinystories/en", "TinyStories-valid", "en", 8939830, 8940526, 8240914, 8241610], ["github/Java", "google/guava", "Java", 414534012, 414538122, 8241625, 8245735], ["github/Python", "django/django", "Python", 282366296, 282367197, 8245750, 8246651], ["tinystories/en", "TinyStories-valid", "en", 7961484, 7962187, 8246666, 8247369], ["github/Scala", "sbt/sbt", "Scala", 519900726, 519900888, 8247384, 8247546], ["github/Python", "django/django", "Python", 286961879, 286962155, 8247561, 8247837], ["github/TypeScript", "nestjs/nest", "TypeScript", 332625899, 332626254, 8247852, 8248207], ["github/Python", "django/django", "Python", 283082459, 283083305, 8248222, 8249068], ["tinystories/en", "TinyStories-valid", "en", 12197726, 12198845, 8249083, 8250202], ["github/TypeScript", "nestjs/nest", "TypeScript", 332320796, 332321493, 8250217, 8250914], ["github/Scala", "playframework/playframework", "Scala", 514783974, 514786521, 8250929, 8253476], ["github/Python", "django/django", "Python", 287784487, 287784773, 8253491, 8253777], ["github/PHP", "symfony/symfony", "PHP", 472748450, 472790748, 8253792, 8296090], ["tinystories/en", "TinyStories-valid", "en", 1212877, 1213702, 8296105, 8296930], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 514952425, 514954155, 8296945, 8298675], ["github/Java", "apache/commons-lang", "Java", 436185888, 436189336, 8298690, 8302138], ["github/JavaScript", "webpack/webpack", "JavaScript", 306606148, 306608595, 8302153, 8304600], ["tinystories/en", "TinyStories-valid", "en", 1718279, 1718808, 8304615, 8305144], ["github/C++", "opencv/opencv", "C++", 395852670, 395862844, 8305159, 8315333], ["tinystories/en", "TinyStories-valid", "en", 16187625, 16188487, 8315348, 8316210], ["github/Python", "django/django", "Python", 285807345, 285811212, 8316225, 8320092], ["github/Java", "spring-projects/spring-framework", "Java", 423281077, 423283638, 8320107, 8322668], ["tinystories/en", "TinyStories-valid", "en", 6532005, 6532941, 8322683, 8323619], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315100730, 315101895, 8323634, 8324799], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490890944, 490899512, 8324814, 8333382], ["tinystories/en", "TinyStories-valid", "en", 19430214, 19431069, 8333397, 8334252], ["github/TypeScript", "angular/angular", "TypeScript", 325470290, 325478397, 8334267, 8342374], ["github/Java", "spring-projects/spring-framework", "Java", 417815229, 417816158, 8342389, 8343318], ["stdlib/python", "python3.13 stdlib", "Python", 24589269, 24609945, 8343333, 8364009], ["tinystories/en", "TinyStories-valid", "en", 4005488, 4006010, 8364011, 8364533], ["github/JavaScript", "webpack/webpack", "JavaScript", 303367505, 303369231, 8364548, 8366274], ["tinystories/en", "TinyStories-valid", "en", 13662053, 13662945, 8366289, 8367181], ["github/Java", "apache/commons-lang", "Java", 435465590, 435468322, 8367196, 8369928], ["github/JavaScript", "expressjs/express", "JavaScript", 299583990, 299584105, 8369943, 8370058], ["github/Go", "gohugoio/hugo", "Go", 369765136, 369769192, 8370073, 8374129], ["github/Rust", "alacritty/alacritty", "Rust", 355776578, 355789403, 8374144, 8386969], ["tinystories/en", "TinyStories-valid", "en", 6247845, 6248649, 8386984, 8387788], ["github/Java", "spring-projects/spring-framework", "Java", 418828651, 418830145, 8387803, 8389297], ["tinystories/en", "TinyStories-valid", "en", 16892292, 16892939, 8389312, 8389959], ["tinystories/en", "TinyStories-valid", "en", 8631032, 8631742, 8389974, 8390684], ["tinystories/en", "TinyStories-valid", "en", 16839629, 16840383, 8390699, 8391453], ["github/TypeScript", "nestjs/nest", "TypeScript", 337737088, 337738857, 8391468, 8393237], ["tinystories/en", "TinyStories-valid", "en", 10279806, 10280623, 8393252, 8394069], ["github/TypeScript", "nestjs/nest", "TypeScript", 332742874, 332743287, 8394084, 8394497], ["github/C", "curl/curl", "C", 376047023, 376132632, 8394512, 8480121], ["tinystories/en", "TinyStories-valid", "en", 3672353, 3673269, 8480136, 8481052], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481414441, 481416925, 8481067, 8483551], ["github/Java", "spring-projects/spring-framework", "Java", 420700002, 420709948, 8483566, 8493512], ["github/TypeScript", "angular/angular", "TypeScript", 324993901, 324995100, 8493527, 8494726], ["tinystories/en", "TinyStories-valid", "en", 6241821, 6242411, 8494741, 8495331], ["github/Ruby", "rails/rails", "Ruby", 460791456, 460801719, 8495346, 8505609], ["tinystories/en", "TinyStories-valid", "en", 6359846, 6360323, 8505624, 8506101], ["github/TypeScript", "nestjs/nest", "TypeScript", 332760733, 332761125, 8506116, 8506508], ["github/TypeScript", "nestjs/nest", "TypeScript", 334255795, 334256337, 8506523, 8507065], ["tinystories/en", "TinyStories-valid", "en", 17836927, 17837804, 8507080, 8507957], ["github/TypeScript", "nestjs/nest", "TypeScript", 337792529, 337793882, 8507972, 8509325], ["tinystories/en", "TinyStories-valid", "en", 14207374, 14208706, 8509340, 8510672], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 482640549, 482643489, 8510687, 8513627], ["tinystories/en", "TinyStories-valid", "en", 7347353, 7349542, 8513642, 8515831], ["tinystories/en", "TinyStories-valid", "en", 6434838, 6435715, 8515846, 8516723], ["tinystories/en", "TinyStories-valid", "en", 535558, 536511, 8516738, 8517691], ["tinystories/en", "TinyStories-valid", "en", 10516128, 10517266, 8517706, 8518844], ["github/TypeScript", "angular/angular", "TypeScript", 329112903, 329123429, 8518859, 8529385], ["tinystories/en", "TinyStories-valid", "en", 19299576, 19300417, 8529400, 8530241], ["tinystories/en", "TinyStories-valid", "en", 18057996, 18059101, 8530256, 8531361], ["github/Rust", "rust-lang/cargo", "Rust", 353516767, 353532837, 8531376, 8547446], ["tinystories/en", "TinyStories-valid", "en", 15926586, 15927412, 8547461, 8548287], ["tinystories/en", "TinyStories-valid", "en", 11154539, 11155525, 8548302, 8549288], ["github/Go", "prometheus/prometheus", "Go", 360341884, 360366550, 8549303, 8573969], ["github/PHP", "laravel/framework", "PHP", 470002879, 470003449, 8573984, 8574554], ["tinystories/en", "TinyStories-valid", "en", 18554017, 18554832, 8574569, 8575384], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515472441, 515473426, 8575399, 8576384], ["tinystories/en", "TinyStories-valid", "en", 8756751, 8758019, 8576399, 8577667], ["github/Java", "google/guava", "Java", 413484211, 413514936, 8577682, 8608407], ["github/PHP", "laravel/framework", "PHP", 470021605, 470023812, 8608422, 8610629], ["tinystories/en", "TinyStories-valid", "en", 9001125, 9001772, 8610644, 8611291], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 313029848, 313067215, 8611306, 8648673], ["github/TypeScript", "nestjs/nest", "TypeScript", 334704807, 334708203, 8648688, 8652084], ["github/Scala", "scala/scala", "Scala", 500104016, 500155726, 8652099, 8703809], ["tinystories/en", "TinyStories-valid", "en", 10066838, 10067794, 8703824, 8704780], ["github/PHP", "laravel/framework", "PHP", 464261640, 464263134, 8704795, 8706289], ["tinystories/en", "TinyStories-valid", "en", 13625475, 13626119, 8706304, 8706948], ["github/PHP", "symfony/symfony", "PHP", 474544077, 474544499, 8706963, 8707385], ["tinystories/en", "TinyStories-valid", "en", 1987702, 1988591, 8707400, 8708289], ["github/Ruby", "rails/rails", "Ruby", 453504956, 453511559, 8708304, 8714907], ["tinystories/en", "TinyStories-valid", "en", 4975512, 4976257, 8714922, 8715667], ["tinystories/en", "TinyStories-valid", "en", 1722415, 1723046, 8715682, 8716313], ["github/Rust", "serde-rs/serde", "Rust", 346863583, 346863712, 8716328, 8716457], ["tinystories/en", "TinyStories-valid", "en", 12951305, 12952583, 8716472, 8717750], ["github/Rust", "tokio-rs/tokio", "Rust", 342907931, 342909157, 8717765, 8718991], ["github/PHP", "symfony/symfony", "PHP", 476647618, 476654086, 8719006, 8725474], ["tinystories/en", "TinyStories-valid", "en", 3400712, 3401973, 8725489, 8726750], ["github/Python", "django/django", "Python", 286211072, 286262970, 8726765, 8778663], ["tinystories/en", "TinyStories-valid", "en", 15140819, 15141495, 8778678, 8779354], ["tinystories/en", "TinyStories-valid", "en", 14617843, 14618511, 8779369, 8780037], ["tinystories/en", "TinyStories-valid", "en", 18109126, 18110466, 8780052, 8781392], ["github/C#", "dotnet/aspnetcore", "C#", 441534753, 441630654, 8781407, 8877308], ["tinystories/en", "TinyStories-valid", "en", 4090058, 4090888, 8877323, 8878153], ["github/Java", "spring-projects/spring-framework", "Java", 418036569, 418037962, 8878168, 8879561], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515396409, 515396909, 8879576, 8880076], ["tinystories/en", "TinyStories-valid", "en", 9593905, 9594715, 8880091, 8880901], ["tinystories/en", "TinyStories-valid", "en", 9285117, 9285853, 8880916, 8881652], ["github/C++", "nlohmann/json", "C++", 386360645, 386438211, 8881667, 8959233], ["tinystories/en", "TinyStories-valid", "en", 11651451, 11652621, 8959248, 8960418], ["github/Rust", "tokio-rs/tokio", "Rust", 344381851, 344396028, 8960433, 8974610], ["tinystories/en", "TinyStories-valid", "en", 2863908, 2864656, 8974625, 8975373], ["github/Kotlin", "ktorio/ktor", "Kotlin", 493393181, 493428145, 8975388, 9010352], ["tinystories/en", "TinyStories-valid", "en", 13475043, 13475700, 9010367, 9011024], ["tinystories/en", "TinyStories-valid", "en", 12845170, 12845800, 9011039, 9011669], ["tinystories/en", "TinyStories-valid", "en", 272578, 273193, 9011684, 9012299], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515153739, 515153935, 9012314, 9012510], ["tinystories/en", "TinyStories-valid", "en", 6339740, 6340435, 9012525, 9013220], ["tinystories/en", "TinyStories-valid", "en", 10212924, 10213782, 9013235, 9014093], ["tinystories/en", "TinyStories-valid", "en", 19153444, 19154835, 9014108, 9015499], ["github/Ruby", "rails/rails", "Ruby", 457316088, 457326131, 9015514, 9025557], ["tinystories/en", "TinyStories-valid", "en", 826626, 827499, 9025572, 9026445], ["tinystories/en", "TinyStories-valid", "en", 9297828, 9298433, 9026460, 9027065], ["books/fr", "PG #7442", "fr", 239484942, 240143918, 9027080, 9686056], ["tinystories/en", "TinyStories-valid", "en", 3515521, 3516112, 9686058, 9686649], ["github/Rust", "tokio-rs/tokio", "Rust", 341199180, 341199239, 9686664, 9686723], ["tinystories/en", "TinyStories-valid", "en", 8427964, 8428506, 9686738, 9687280], ["github/PHP", "symfony/symfony", "PHP", 472226200, 472250121, 9687295, 9711216], ["tinystories/en", "TinyStories-valid", "en", 3984598, 3985079, 9711231, 9711712], ["github/Rust", "rust-lang/cargo", "Rust", 347891118, 347893098, 9711727, 9713707], ["tinystories/en", "TinyStories-valid", "en", 11779826, 11781268, 9713722, 9715164], ["github/Rust", "rust-lang/cargo", "Rust", 352848199, 352849154, 9715179, 9716134], ["tinystories/en", "TinyStories-valid", "en", 5738349, 5738999, 9716149, 9716799], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316746240, 316753835, 9716814, 9724409], ["github/Java", "google/guava", "Java", 413291808, 413331663, 9724424, 9764279], ["tinystories/en", "TinyStories-valid", "en", 5697525, 5698225, 9764294, 9764994], ["github/Rust", "tokio-rs/tokio", "Rust", 341022895, 341024205, 9765009, 9766319], ["github/Scala", "sbt/sbt", "Scala", 519894586, 519895194, 9766334, 9766942], ["tinystories/en", "TinyStories-valid", "en", 15651834, 15652536, 9766957, 9767659], ["github/Scala", "sbt/sbt", "Scala", 517566271, 517567503, 9767674, 9768906], ["github/Rust", "tokio-rs/tokio", "Rust", 343324940, 343325908, 9768921, 9769889], ["tinystories/en", "TinyStories-valid", "en", 18465729, 18466330, 9769904, 9770505], ["github/Rust", "rust-lang/cargo", "Rust", 353004457, 353005144, 9770520, 9771207], ["tinystories/en", "TinyStories-valid", "en", 11898140, 11899670, 9771222, 9772752], ["github/Scala", "sbt/sbt", "Scala", 519709238, 519713321, 9772767, 9776850], ["tinystories/en", "TinyStories-valid", "en", 3681546, 3682380, 9776865, 9777699], ["github/Rust", "tokio-rs/tokio", "Rust", 340337947, 340340306, 9777714, 9780073], ["github/TypeScript", "vuejs/core", "TypeScript", 320482779, 320537438, 9780088, 9834747], ["tinystories/en", "TinyStories-valid", "en", 11757727, 11758447, 9834762, 9835482], ["github/Swift", "vapor/vapor", "Swift", 497516900, 497520657, 9835497, 9839254], ["tinystories/en", "TinyStories-valid", "en", 19069242, 19070755, 9839269, 9840782], ["tinystories/en", "TinyStories-valid", "en", 14018744, 14019462, 9840797, 9841515], ["tinystories/en", "TinyStories-valid", "en", 2209786, 2210526, 9841530, 9842270], ["tinystories/en", "TinyStories-valid", "en", 3861069, 3861762, 9842285, 9842978], ["github/Scala", "playframework/playframework", "Scala", 512768640, 512775082, 9842993, 9849435], ["tinystories/en", "TinyStories-valid", "en", 9954476, 9955099, 9849450, 9850073], ["github/Rust", "serde-rs/serde", "Rust", 346039569, 346047845, 9850088, 9858364], ["tinystories/en", "TinyStories-valid", "en", 6500228, 6501142, 9858379, 9859293], ["tinystories/en", "TinyStories-valid", "en", 11510649, 11511433, 9859308, 9860092], ["github/JavaScript", "webpack/webpack", "JavaScript", 307422251, 307436883, 9860107, 9874739], ["github/Python", "django/django", "Python", 288023813, 288025580, 9874754, 9876521], ["tinystories/en", "TinyStories-valid", "en", 6646022, 6646663, 9876536, 9877177], ["tinystories/en", "TinyStories-valid", "en", 2194958, 2195684, 9877192, 9877918], ["github/Scala", "playframework/playframework", "Scala", 512292863, 512294288, 9877933, 9879358], ["github/Python", "scikit-learn/scikit-learn", "Python", 295965715, 295966214, 9879373, 9879872], ["github/Kotlin", "ktorio/ktor", "Kotlin", 495498671, 495499071, 9879887, 9880287], ["github/Python", "scikit-learn/scikit-learn", "Python", 290951315, 290951442, 9880302, 9880429], ["tinystories/en", "TinyStories-valid", "en", 2213750, 2214501, 9880444, 9881195], ["github/Java", "spring-projects/spring-framework", "Java", 423455172, 423456027, 9881210, 9882065], ["tinystories/en", "TinyStories-valid", "en", 15797148, 15798011, 9882080, 9882943], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481426140, 481427539, 9882958, 9884357], ["tinystories/en", "TinyStories-valid", "en", 4920371, 4921023, 9884372, 9885024], ["github/Python", "django/django", "Python", 282434466, 282438393, 9885039, 9888966], ["tinystories/en", "TinyStories-valid", "en", 4202660, 4203367, 9888981, 9889688], ["github/Go", "prometheus/prometheus", "Go", 357675447, 357720299, 9889703, 9934555], ["github/Ruby", "rails/rails", "Ruby", 456061343, 456071987, 9934570, 9945214], ["tinystories/en", "TinyStories-valid", "en", 3760564, 3761409, 9945229, 9946074], ["github/Rust", "tokio-rs/tokio", "Rust", 340810672, 340814966, 9946089, 9950383], ["tinystories/en", "TinyStories-valid", "en", 12103534, 12104373, 9950398, 9951237], ["github/PHP", "laravel/framework", "PHP", 463730611, 463743780, 9951252, 9964421], ["tinystories/en", "TinyStories-valid", "en", 11948298, 11949121, 9964436, 9965259], ["github/Python", "django/django", "Python", 282788038, 282789613, 9965274, 9966849], ["tinystories/en", "TinyStories-valid", "en", 3823666, 3824274, 9966864, 9967472], ["tinystories/en", "TinyStories-valid", "en", 17972212, 17973091, 9967487, 9968366], ["tinystories/en", "TinyStories-valid", "en", 13177806, 13178540, 9968381, 9969115], ["github/C++", "protocolbuffers/protobuf", "C++", 408302916, 408304475, 9969130, 9970689], ["tinystories/en", "TinyStories-valid", "en", 17452992, 17453800, 9970704, 9971512], ["github/Scala", "scala/scala", "Scala", 500540625, 500558035, 9971527, 9988937], ["tinystories/en", "TinyStories-valid", "en", 11619946, 11621332, 9988952, 9990338], ["github/Python", "django/django", "Python", 286088299, 286094325, 9990353, 9996379], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494515096, 494526231, 9996394, 10007529], ["tinystories/en", "TinyStories-valid", "en", 6095510, 6096070, 10007544, 10008104], ["tinystories/en", "TinyStories-valid", "en", 2467409, 2468121, 10008119, 10008831], ["tinystories/en", "TinyStories-valid", "en", 4153734, 4154443, 10008846, 10009555], ["github/PHP", "symfony/symfony", "PHP", 477681398, 477682579, 10009570, 10010751], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 314483769, 314494307, 10010766, 10021304], ["tinystories/en", "TinyStories-valid", "en", 858633, 859362, 10021319, 10022048], ["tinystories/en", "TinyStories-valid", "en", 5336342, 5336894, 10022063, 10022615], ["github/C++", "protocolbuffers/protobuf", "C++", 408023941, 408036152, 10022630, 10034841], ["tinystories/en", "TinyStories-valid", "en", 2523025, 2523840, 10034856, 10035671], ["tinystories/en", "TinyStories-valid", "en", 8349785, 8350428, 10035686, 10036329], ["github/C", "libuv/libuv", "C", 380995834, 380998053, 10036344, 10038563], ["tinystories/en", "TinyStories-valid", "en", 877457, 877986, 10038578, 10039107], ["tinystories/en", "TinyStories-valid", "en", 997015, 997717, 10039122, 10039824], ["github/Java", "spring-projects/spring-framework", "Java", 420255853, 420299743, 10039839, 10083729], ["github/Ruby", "jekyll/jekyll", "Ruby", 461778795, 461781696, 10083744, 10086645], ["tinystories/en", "TinyStories-valid", "en", 17398888, 17399920, 10086660, 10087692], ["github/JavaScript", "webpack/webpack", "JavaScript", 300513193, 300513479, 10087707, 10087993], ["github/PHP", "laravel/framework", "PHP", 466632881, 466643279, 10088008, 10098406], ["tinystories/en", "TinyStories-valid", "en", 19115933, 19117572, 10098421, 10100060], ["github/C++", "nlohmann/json", "C++", 385589852, 385591206, 10100075, 10101429], ["github/C", "libuv/libuv", "C", 381368334, 381371904, 10101444, 10105014], ["tinystories/en", "TinyStories-valid", "en", 1150013, 1150772, 10105029, 10105788], ["github/Kotlin", "ktorio/ktor", "Kotlin", 493883755, 493887904, 10105803, 10109952], ["github/Scala", "scala/scala", "Scala", 506039135, 506045648, 10109967, 10116480], ["tinystories/en", "TinyStories-valid", "en", 6562182, 6562983, 10116495, 10117296], ["books/en", "PG #323", "en", 167800884, 168121881, 10117311, 10438308], ["github/TypeScript", "angular/angular", "TypeScript", 324166244, 324170373, 10438310, 10442439], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 317554472, 317559222, 10442454, 10447204], ["tinystories/en", "TinyStories-valid", "en", 536526, 537109, 10447219, 10447802], ["tinystories/en", "TinyStories-valid", "en", 2321254, 2322075, 10447817, 10448638], ["github/Rust", "tokio-rs/tokio", "Rust", 341125129, 341154077, 10448653, 10477601], ["tinystories/en", "TinyStories-valid", "en", 13528625, 13529190, 10477616, 10478181], ["github/TypeScript", "angular/angular", "TypeScript", 325088622, 325088802, 10478196, 10478376], ["tinystories/en", "TinyStories-valid", "en", 2108103, 2108819, 10478391, 10479107], ["github/Scala", "sbt/sbt", "Scala", 519881345, 519881387, 10479122, 10479164], ["github/Ruby", "jekyll/jekyll", "Ruby", 461720984, 461725109, 10479179, 10483304], ["github/PHP", "laravel/framework", "PHP", 465153258, 465153801, 10483319, 10483862], ["tinystories/en", "TinyStories-valid", "en", 4580898, 4582247, 10483877, 10485226], ["github/TypeScript", "angular/angular", "TypeScript", 329280480, 329283985, 10485241, 10488746], ["github/Swift", "vapor/vapor", "Swift", 497574482, 497579994, 10488761, 10494273], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494483746, 494487311, 10494288, 10497853], ["tinystories/en", "TinyStories-valid", "en", 1046491, 1047203, 10497868, 10498580], ["github/Scala", "playframework/playframework", "Scala", 514348606, 514353993, 10498595, 10503982], ["tinystories/en", "TinyStories-valid", "en", 3687794, 3688685, 10503997, 10504888], ["github/C", "libuv/libuv", "C", 382468231, 382473308, 10504903, 10509980], ["github/PHP", "symfony/symfony", "PHP", 474607053, 474611051, 10509995, 10513993], ["github/TypeScript", "nestjs/nest", "TypeScript", 337110234, 337110935, 10514008, 10514709], ["tinystories/en", "TinyStories-valid", "en", 16122423, 16123201, 10514724, 10515502], ["tinystories/en", "TinyStories-valid", "en", 6652238, 6652726, 10515517, 10516005], ["github/Python", "scikit-learn/scikit-learn", "Python", 291715388, 291743284, 10516020, 10543916], ["tinystories/en", "TinyStories-valid", "en", 3502360, 3502980, 10543931, 10544551], ["github/Ruby", "rails/rails", "Ruby", 453177714, 453178005, 10544566, 10544857], ["github/TypeScript", "nestjs/nest", "TypeScript", 337020525, 337023731, 10544872, 10548078], ["github/C++", "nlohmann/json", "C++", 388645554, 388667806, 10548093, 10570345], ["tinystories/en", "TinyStories-valid", "en", 9056319, 9057025, 10570360, 10571066], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491916708, 491919593, 10571081, 10573966], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 310340414, 310352172, 10573981, 10585739], ["tinystories/en", "TinyStories-valid", "en", 10554375, 10555577, 10585754, 10586956], ["tinystories/en", "TinyStories-valid", "en", 563454, 564256, 10586971, 10587773], ["github/PHP", "symfony/symfony", "PHP", 474167025, 474171615, 10587788, 10592378], ["tinystories/en", "TinyStories-valid", "en", 10531469, 10532057, 10592393, 10592981], ["github/Ruby", "rails/rails", "Ruby", 461076656, 461079906, 10592996, 10596246], ["stdlib/python", "python3.13 stdlib", "Python", 27748778, 27783254, 10596261, 10630737], ["github/Go", "gohugoio/hugo", "Go", 366397654, 366401215, 10630739, 10634300], ["github/C", "libuv/libuv", "C", 383372535, 383375422, 10634315, 10637202], ["tinystories/en", "TinyStories-valid", "en", 11940860, 11941727, 10637217, 10638084], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 484210478, 484212050, 10638099, 10639671], ["github/Java", "google/guava", "Java", 411149194, 411151931, 10639686, 10642423], ["github/TypeScript", "nestjs/nest", "TypeScript", 335426705, 335431930, 10642438, 10647663], ["tinystories/en", "TinyStories-valid", "en", 14054894, 14055601, 10647678, 10648385], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485646458, 485646729, 10648400, 10648671], ["github/PHP", "symfony/symfony", "PHP", 476546990, 476547415, 10648686, 10649111], ["tinystories/en", "TinyStories-valid", "en", 10106377, 10107280, 10649126, 10650029], ["github/Scala", "sbt/sbt", "Scala", 516563310, 516576668, 10650044, 10663402], ["github/PHP", "laravel/framework", "PHP", 467471274, 467473087, 10663417, 10665230], ["github/Go", "gohugoio/hugo", "Go", 366532169, 366533041, 10665245, 10666117], ["tinystories/en", "TinyStories-valid", "en", 18888458, 18889599, 10666132, 10667273], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489268856, 489270824, 10667288, 10669256], ["github/TypeScript", "nestjs/nest", "TypeScript", 332765154, 332765179, 10669271, 10669296], ["github/TypeScript", "angular/angular", "TypeScript", 325121845, 325121920, 10669311, 10669386], ["github/C", "curl/curl", "C", 374123020, 374124724, 10669401, 10671105], ["tinystories/en", "TinyStories-valid", "en", 7801867, 7802668, 10671120, 10671921], ["github/PHP", "laravel/framework", "PHP", 464034605, 464035345, 10671936, 10672676], ["github/TypeScript", "angular/angular", "TypeScript", 326013284, 326014753, 10672691, 10674160], ["github/JavaScript", "webpack/webpack", "JavaScript", 305533113, 305534400, 10674175, 10675462], ["tinystories/en", "TinyStories-valid", "en", 911719, 912271, 10675477, 10676029], ["github/TypeScript", "nestjs/nest", "TypeScript", 337624314, 337624536, 10676044, 10676266], ["github/PHP", "symfony/symfony", "PHP", 475939219, 475940144, 10676281, 10677206], ["tinystories/en", "TinyStories-valid", "en", 18546137, 18547084, 10677221, 10678168], ["github/Go", "prometheus/prometheus", "Go", 363751388, 363754877, 10678183, 10681672], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489409245, 489410889, 10681687, 10683331], ["github/TypeScript", "angular/angular", "TypeScript", 324798063, 324799228, 10683346, 10684511], ["github/PHP", "symfony/symfony", "PHP", 476717470, 476718652, 10684526, 10685708], ["tinystories/en", "TinyStories-valid", "en", 15870194, 15870845, 10685723, 10686374], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 487426648, 487426723, 10686389, 10686464], ["github/Java", "spring-projects/spring-framework", "Java", 419563621, 419578648, 10686479, 10701506], ["github/JavaScript", "expressjs/express", "JavaScript", 299725465, 299728310, 10701521, 10704366], ["tinystories/en", "TinyStories-valid", "en", 2630548, 2631259, 10704381, 10705092], ["github/Ruby", "jekyll/jekyll", "Ruby", 461432222, 461436478, 10705107, 10709363], ["books/en", "PG #263", "en", 150784758, 150823592, 10709378, 10748212], ["tinystories/en", "TinyStories-valid", "en", 852893, 853859, 10748214, 10749180], ["github/PHP", "laravel/framework", "PHP", 466903613, 466905806, 10749195, 10751388], ["github/Go", "gohugoio/hugo", "Go", 372085590, 372086801, 10751403, 10752614], ["tinystories/en", "TinyStories-valid", "en", 19046967, 19047784, 10752629, 10753446], ["github/Rust", "alacritty/alacritty", "Rust", 355955856, 355962870, 10753461, 10760475], ["github/Scala", "scala/scala", "Scala", 498812086, 498812669, 10760490, 10761073], ["github/Scala", "sbt/sbt", "Scala", 519902156, 519902207, 10761088, 10761139], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 451397262, 451406922, 10761154, 10770814], ["tinystories/en", "TinyStories-valid", "en", 13388320, 13389638, 10770829, 10772147], ["github/Go", "gin-gonic/gin", "Go", 356450501, 356451969, 10772162, 10773630], ["github/TypeScript", "nestjs/nest", "TypeScript", 337313168, 337322232, 10773645, 10782709], ["github/PHP", "symfony/symfony", "PHP", 474028679, 474031794, 10782724, 10785839], ["github/JavaScript", "webpack/webpack", "JavaScript", 302401486, 302406153, 10785854, 10790521], ["tinystories/en", "TinyStories-valid", "en", 14204083, 14204751, 10790536, 10791204], ["github/Go", "prometheus/prometheus", "Go", 358383352, 358384342, 10791219, 10792209], ["tinystories/en", "TinyStories-valid", "en", 11534379, 11535034, 10792224, 10792879], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492175132, 492182861, 10792894, 10800623], ["tinystories/en", "TinyStories-valid", "en", 18490882, 18491593, 10800638, 10801349], ["github/Java", "spring-projects/spring-framework", "Java", 423377430, 423378973, 10801364, 10802907], ["github/C++", "opencv/opencv", "C++", 395634241, 395650554, 10802922, 10819235], ["github/Go", "prometheus/prometheus", "Go", 358078907, 358079964, 10819250, 10820307], ["tinystories/en", "TinyStories-valid", "en", 289780, 290474, 10820322, 10821016], ["github/Rust", "rust-lang/cargo", "Rust", 353006502, 353007192, 10821031, 10821721], ["tinystories/en", "TinyStories-valid", "en", 12312480, 12313036, 10821736, 10822292], ["github/Go", "gohugoio/hugo", "Go", 370659577, 370660798, 10822307, 10823528], ["github/Scala", "playframework/playframework", "Scala", 512095854, 512105584, 10823543, 10833273], ["tinystories/en", "TinyStories-valid", "en", 2190320, 2191120, 10833288, 10834088], ["github/Rust", "rust-lang/cargo", "Rust", 353189443, 353191166, 10834103, 10835826], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 310685985, 310688540, 10835841, 10838396], ["github/Python", "django/django", "Python", 283767738, 283774689, 10838411, 10845362], ["tinystories/en", "TinyStories-valid", "en", 9314054, 9315003, 10845377, 10846326], ["github/PHP", "symfony/symfony", "PHP", 474665571, 474671574, 10846341, 10852344], ["github/Java", "apache/commons-lang", "Java", 434951884, 434959495, 10852359, 10859970], ["github/TypeScript", "angular/angular", "TypeScript", 326672267, 326673184, 10859985, 10860902], ["tinystories/en", "TinyStories-valid", "en", 3691068, 3691827, 10860917, 10861676], ["github/TypeScript", "nestjs/nest", "TypeScript", 332745330, 332745491, 10861691, 10861852], ["github/TypeScript", "angular/angular", "TypeScript", 324986708, 324987261, 10861867, 10862420], ["tinystories/en", "TinyStories-valid", "en", 14779673, 14780932, 10862435, 10863694], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 314712462, 314714540, 10863709, 10865787], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487526646, 487527085, 10865802, 10866241], ["github/TypeScript", "nestjs/nest", "TypeScript", 335023386, 335024741, 10866256, 10867611], ["tinystories/en", "TinyStories-valid", "en", 12078265, 12079231, 10867626, 10868592], ["github/Java", "spring-projects/spring-framework", "Java", 417760436, 417761387, 10868607, 10869558], ["tinystories/en", "TinyStories-valid", "en", 7666734, 7667509, 10869573, 10870348], ["github/PHP", "symfony/symfony", "PHP", 476586354, 476587233, 10870363, 10871242], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316131397, 316133229, 10871257, 10873089], ["github/Scala", "playframework/playframework", "Scala", 513243998, 513245425, 10873104, 10874531], ["tinystories/en", "TinyStories-valid", "en", 3924919, 3925776, 10874546, 10875403], ["github/PHP", "laravel/framework", "PHP", 466056206, 466057489, 10875418, 10876701], ["tinystories/en", "TinyStories-valid", "en", 17214160, 17214735, 10876716, 10877291], ["github/TypeScript", "vuejs/core", "TypeScript", 323410157, 323415755, 10877306, 10882904], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487665737, 487670850, 10882919, 10888032], ["github/Java", "spring-projects/spring-framework", "Java", 425415603, 425421855, 10888047, 10894299], ["github/JavaScript", "webpack/webpack", "JavaScript", 302475284, 302477391, 10894314, 10896421], ["tinystories/en", "TinyStories-valid", "en", 9172410, 9173106, 10896436, 10897132], ["github/Scala", "scala/scala", "Scala", 505576838, 505579943, 10897147, 10900252], ["tinystories/en", "TinyStories-valid", "en", 11303438, 11304352, 10900267, 10901181], ["github/Python", "django/django", "Python", 287549335, 287555971, 10901196, 10907832], ["tinystories/en", "TinyStories-valid", "en", 10945278, 10946040, 10907847, 10908609], ["github/Scala", "sbt/sbt", "Scala", 519871552, 519871613, 10908624, 10908685], ["github/Java", "spring-projects/spring-framework", "Java", 418058580, 418059353, 10908700, 10909473], ["github/Ruby", "rails/rails", "Ruby", 460326898, 460338790, 10909488, 10921380], ["github/Scala", "playframework/playframework", "Scala", 512027129, 512028430, 10921395, 10922696], ["tinystories/en", "TinyStories-valid", "en", 6884840, 6885615, 10922711, 10923486], ["github/Java", "google/guava", "Java", 410163712, 410165757, 10923501, 10925546], ["github/PHP", "symfony/symfony", "PHP", 472566183, 472572931, 10925561, 10932309], ["tinystories/en", "TinyStories-valid", "en", 632030, 632953, 10932324, 10933247], ["github/Scala", "sbt/sbt", "Scala", 517861264, 517861971, 10933262, 10933969], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487558343, 487559294, 10933984, 10934935], ["tinystories/en", "TinyStories-valid", "en", 7391316, 7391828, 10934950, 10935462], ["github/C#", "dotnet/aspnetcore", "C#", 442544599, 442559374, 10935477, 10950252], ["github/TypeScript", "vuejs/core", "TypeScript", 320921141, 320925403, 10950267, 10954529], ["github/Scala", "scala/scala", "Scala", 502801096, 502802734, 10954544, 10956182], ["tinystories/en", "TinyStories-valid", "en", 8176552, 8177260, 10956197, 10956905], ["github/Scala", "sbt/sbt", "Scala", 519764158, 519764212, 10956920, 10956974], ["github/JavaScript", "webpack/webpack", "JavaScript", 303168029, 303176332, 10956989, 10965292], ["tinystories/en", "TinyStories-valid", "en", 11886664, 11888406, 10965307, 10967049], ["github/Scala", "playframework/playframework", "Scala", 507850013, 507851449, 10967064, 10968500], ["github/TypeScript", "nestjs/nest", "TypeScript", 332423919, 332424826, 10968515, 10969422], ["github/Go", "gohugoio/hugo", "Go", 366959813, 366982168, 10969437, 10991792], ["github/C", "curl/curl", "C", 374544381, 374574751, 10991807, 11022177], ["tinystories/en", "TinyStories-valid", "en", 12404356, 12405051, 11022192, 11022887], ["github/TypeScript", "nestjs/nest", "TypeScript", 337739818, 337740052, 11022902, 11023136], ["github/Rust", "rust-lang/cargo", "Rust", 351054730, 351080144, 11023151, 11048565], ["github/TypeScript", "nestjs/nest", "TypeScript", 337850024, 337850080, 11048580, 11048636], ["tinystories/en", "TinyStories-valid", "en", 11923491, 11923917, 11048651, 11049077], ["github/TypeScript", "angular/angular", "TypeScript", 325208729, 325209687, 11049092, 11050050], ["tinystories/en", "TinyStories-valid", "en", 18613654, 18614406, 11050065, 11050817], ["github/Kotlin", "ktorio/ktor", "Kotlin", 493258971, 493265409, 11050832, 11057270], ["github/Python", "django/django", "Python", 285281672, 285289646, 11057285, 11065259], ["github/Java", "spring-projects/spring-framework", "Java", 418958663, 418974302, 11065274, 11080913], ["tinystories/en", "TinyStories-valid", "en", 672403, 673221, 11080928, 11081746], ["tinystories/en", "TinyStories-valid", "en", 9733049, 9733868, 11081761, 11082580], ["github/PHP", "symfony/symfony", "PHP", 479553082, 479559256, 11082595, 11088769], ["github/TypeScript", "vuejs/core", "TypeScript", 323426810, 323429794, 11088784, 11091768], ["github/Swift", "Alamofire/Alamofire", "Swift", 496536506, 496542323, 11091783, 11097600], ["tinystories/en", "TinyStories-valid", "en", 13329496, 13330689, 11097615, 11098808], ["github/TypeScript", "nestjs/nest", "TypeScript", 337883181, 337883442, 11098823, 11099084], ["tinystories/en", "TinyStories-valid", "en", 6700172, 6700959, 11099099, 11099886], ["github/TypeScript", "nestjs/nest", "TypeScript", 333121009, 333122699, 11099901, 11101591], ["tinystories/en", "TinyStories-valid", "en", 16960528, 16960891, 11101606, 11101969], ["tinystories/en", "TinyStories-valid", "en", 18394200, 18395002, 11101984, 11102786], ["tinystories/en", "TinyStories-valid", "en", 3574170, 3574796, 11102801, 11103427], ["github/Ruby", "jekyll/jekyll", "Ruby", 461777937, 461778065, 11103442, 11103570], ["github/Kotlin", "ktorio/ktor", "Kotlin", 495792080, 495794405, 11103585, 11105910], ["tinystories/en", "TinyStories-valid", "en", 18383913, 18384575, 11105925, 11106587], ["github/Java", "spring-projects/spring-framework", "Java", 417928939, 417929682, 11106602, 11107345], ["github/Python", "django/django", "Python", 289128918, 289132786, 11107360, 11111228], ["tinystories/en", "TinyStories-valid", "en", 18187506, 18188210, 11111243, 11111947], ["github/C++", "protocolbuffers/protobuf", "C++", 403728752, 403771831, 11111962, 11155041], ["github/JavaScript", "webpack/webpack", "JavaScript", 305875827, 305886918, 11155056, 11166147], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 451935107, 451938488, 11166162, 11169543], ["tinystories/en", "TinyStories-valid", "en", 10300594, 10301232, 11169558, 11170196], ["tinystories/en", "TinyStories-valid", "en", 9338836, 9339389, 11170211, 11170764], ["github/Ruby", "rails/rails", "Ruby", 460369702, 460372764, 11170779, 11173841], ["github/PHP", "laravel/framework", "PHP", 469589624, 469597612, 11173856, 11181844], ["tinystories/en", "TinyStories-valid", "en", 18090988, 18092179, 11181859, 11183050], ["github/Java", "apache/commons-lang", "Java", 435538092, 435548227, 11183065, 11193200], ["tinystories/en", "TinyStories-valid", "en", 14674841, 14675758, 11193215, 11194132], ["github/Python", "django/django", "Python", 286839604, 286842675, 11194147, 11197218], ["tinystories/en", "TinyStories-valid", "en", 18809240, 18809831, 11197233, 11197824], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 451836801, 451838869, 11197839, 11199907], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490150430, 490156009, 11199922, 11205501], ["tinystories/en", "TinyStories-valid", "en", 1495982, 1496701, 11205516, 11206235], ["tinystories/en", "TinyStories-valid", "en", 7900041, 7900725, 11206250, 11206934], ["github/Go", "prometheus/prometheus", "Go", 359781159, 359782159, 11206949, 11207949], ["github/Rust", "rust-lang/cargo", "Rust", 353021454, 353021979, 11207964, 11208489], ["tinystories/en", "TinyStories-valid", "en", 9967696, 9968772, 11208504, 11209580], ["github/Rust", "serde-rs/serde", "Rust", 346858358, 346858476, 11209595, 11209713], ["github/Go", "gohugoio/hugo", "Go", 366077573, 366078295, 11209728, 11210450], ["github/TypeScript", "nestjs/nest", "TypeScript", 332980537, 332998822, 11210465, 11228750], ["tinystories/en", "TinyStories-valid", "en", 9538144, 9539002, 11228765, 11229623], ["tinystories/en", "TinyStories-valid", "en", 932296, 932957, 11229638, 11230299], ["tinystories/en", "TinyStories-valid", "en", 13708640, 13709303, 11230314, 11230977], ["books/en", "PG #331", "en", 169997847, 170685847, 11230992, 11918992], ["github/Go", "gohugoio/hugo", "Go", 370381532, 370384686, 11918994, 11922148], ["tinystories/en", "TinyStories-valid", "en", 8239130, 8239824, 11922163, 11922857], ["tinystories/en", "TinyStories-valid", "en", 12480402, 12481371, 11922872, 11923841], ["github/JavaScript", "webpack/webpack", "JavaScript", 302622890, 302630391, 11923856, 11931357], ["tinystories/en", "TinyStories-valid", "en", 17463913, 17464565, 11931372, 11932024], ["github/Python", "scikit-learn/scikit-learn", "Python", 290905093, 290916340, 11932039, 11943286], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494252844, 494258250, 11943301, 11948707], ["github/C#", "dotnet/aspnetcore", "C#", 439652792, 439662803, 11948722, 11958733], ["github/Rust", "tokio-rs/tokio", "Rust", 340514002, 340525139, 11958748, 11969885], ["tinystories/en", "TinyStories-valid", "en", 5259188, 5261441, 11969900, 11972153], ["tinystories/en", "TinyStories-valid", "en", 17123380, 17124003, 11972168, 11972791], ["github/PHP", "laravel/framework", "PHP", 470675041, 470690022, 11972806, 11987787], ["tinystories/en", "TinyStories-valid", "en", 561435, 562351, 11987802, 11988718], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486306420, 486307145, 11988733, 11989458], ["tinystories/en", "TinyStories-valid", "en", 6479925, 6480648, 11989473, 11990196], ["github/TypeScript", "angular/angular", "TypeScript", 324174589, 324175219, 11990211, 11990841], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486436410, 486437102, 11990856, 11991548], ["tinystories/en", "TinyStories-valid", "en", 10690045, 10690849, 11991563, 11992367], ["tinystories/en", "TinyStories-valid", "en", 19379958, 19380440, 11992382, 11992864], ["github/TypeScript", "angular/angular", "TypeScript", 325021918, 325023539, 11992879, 11994500], ["tinystories/en", "TinyStories-valid", "en", 17810801, 17812223, 11994515, 11995937], ["github/Python", "scikit-learn/scikit-learn", "Python", 295624774, 295626846, 11995952, 11998024], ["github/Rust", "tokio-rs/tokio", "Rust", 339974832, 339975841, 11998039, 11999048], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492346180, 492349388, 11999063, 12002271], ["github/TypeScript", "nestjs/nest", "TypeScript", 334292328, 334294397, 12002286, 12004355], ["tinystories/en", "TinyStories-valid", "en", 4182215, 4183367, 12004370, 12005522], ["github/C#", "dotnet/aspnetcore", "C#", 442304359, 442306466, 12005537, 12007644], ["github/Python", "django/django", "Python", 282367212, 282368299, 12007659, 12008746], ["tinystories/en", "TinyStories-valid", "en", 10093774, 10094701, 12008761, 12009688], ["github/TypeScript", "microsoft/vscode", "TypeScript", 319093680, 319094373, 12009703, 12010396], ["github/TypeScript", "vuejs/core", "TypeScript", 323514741, 323514922, 12010411, 12010592], ["github/JavaScript", "expressjs/express", "JavaScript", 299991985, 300005097, 12010607, 12023719], ["tinystories/en", "TinyStories-valid", "en", 14716519, 14717565, 12023734, 12024780], ["github/C#", "dotnet/aspnetcore", "C#", 444360155, 444360724, 12024795, 12025364], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 483586298, 483587402, 12025379, 12026483], ["github/TypeScript", "angular/angular", "TypeScript", 324513795, 324515445, 12026498, 12028148], ["github/Java", "spring-projects/spring-framework", "Java", 424791818, 424837900, 12028163, 12074245], ["github/PHP", "laravel/framework", "PHP", 464105399, 464105969, 12074260, 12074830], ["tinystories/en", "TinyStories-valid", "en", 18368795, 18369615, 12074845, 12075665], ["github/Python", "django/django", "Python", 283198483, 283203071, 12075680, 12080268], ["github/Rust", "tokio-rs/tokio", "Rust", 340837833, 340844967, 12080283, 12087417], ["github/PHP", "laravel/framework", "PHP", 470019930, 470020667, 12087432, 12088169], ["tinystories/en", "TinyStories-valid", "en", 17064705, 17065240, 12088184, 12088719], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 447022288, 447024705, 12088734, 12091151], ["tinystories/en", "TinyStories-valid", "en", 101649, 102372, 12091166, 12091889], ["github/PHP", "symfony/symfony", "PHP", 476776458, 476777157, 12091904, 12092603], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490390910, 490392941, 12092618, 12094649], ["github/C++", "nlohmann/json", "C++", 388672445, 388688418, 12094664, 12110637], ["github/TypeScript", "nestjs/nest", "TypeScript", 333115806, 333119260, 12110652, 12114106], ["tinystories/en", "TinyStories-valid", "en", 424968, 425792, 12114121, 12114945], ["tinystories/en", "TinyStories-valid", "en", 4988759, 4989521, 12114960, 12115722], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 450057604, 450059305, 12115737, 12117438], ["tinystories/en", "TinyStories-valid", "en", 15277977, 15279218, 12117453, 12118694], ["github/PHP", "symfony/symfony", "PHP", 471723711, 471728229, 12118709, 12123227], ["github/TypeScript", "angular/angular", "TypeScript", 324074440, 324075465, 12123242, 12124267], ["github/TypeScript", "angular/angular", "TypeScript", 324781819, 324782125, 12124282, 12124588], ["github/Python", "django/django", "Python", 288130093, 288133519, 12124603, 12128029], ["github/Ruby", "rails/rails", "Ruby", 455784363, 455806644, 12128044, 12150325], ["tinystories/en", "TinyStories-valid", "en", 414178, 415061, 12150340, 12151223], ["github/Rust", "rust-lang/cargo", "Rust", 352746215, 352747352, 12151238, 12152375], ["tinystories/en", "TinyStories-valid", "en", 12513148, 12513964, 12152390, 12153206], ["github/Rust", "tokio-rs/tokio", "Rust", 340056712, 340057992, 12153221, 12154501], ["tinystories/en", "TinyStories-valid", "en", 4054175, 4054820, 12154516, 12155161], ["github/Go", "gohugoio/hugo", "Go", 366143595, 366174229, 12155176, 12185810], ["github/Rust", "rust-lang/cargo", "Rust", 353020213, 353020590, 12185825, 12186202], ["github/PHP", "symfony/symfony", "PHP", 478522864, 478524295, 12186217, 12187648], ["tinystories/en", "TinyStories-valid", "en", 5247090, 5248460, 12187663, 12189033], ["github/Swift", "vapor/vapor", "Swift", 497895767, 497900355, 12189048, 12193636], ["github/Python", "django/django", "Python", 282466276, 282469550, 12193651, 12196925], ["tinystories/en", "TinyStories-valid", "en", 17894740, 17895671, 12196940, 12197871], ["github/Rust", "tokio-rs/tokio", "Rust", 341549645, 341553315, 12197886, 12201556], ["tinystories/en", "TinyStories-valid", "en", 18483434, 18484107, 12201571, 12202244], ["tinystories/en", "TinyStories-valid", "en", 6412817, 6413688, 12202259, 12203130], ["github/Python", "django/django", "Python", 288115175, 288115788, 12203145, 12203758], ["github/C", "libuv/libuv", "C", 381737177, 381760850, 12203773, 12227446], ["github/Python", "django/django", "Python", 287544812, 287545248, 12227461, 12227897], ["tinystories/en", "TinyStories-valid", "en", 5779136, 5779793, 12227912, 12228569], ["github/PHP", "laravel/framework", "PHP", 463980007, 463986164, 12228584, 12234741], ["github/Python", "django/django", "Python", 282452585, 282453267, 12234756, 12235438], ["tinystories/en", "TinyStories-valid", "en", 12182457, 12183186, 12235453, 12236182], ["github/TypeScript", "microsoft/vscode", "TypeScript", 319222363, 319237977, 12236197, 12251811], ["tinystories/en", "TinyStories-valid", "en", 9233898, 9234597, 12251826, 12252525], ["github/Python", "django/django", "Python", 282388178, 282389893, 12252540, 12254255], ["github/Rust", "tokio-rs/tokio", "Rust", 344853680, 344857332, 12254270, 12257922], ["github/Python", "django/django", "Python", 288111658, 288111682, 12257937, 12257961], ["tinystories/en", "TinyStories-valid", "en", 5518352, 5520502, 12257976, 12260126], ["github/PHP", "laravel/framework", "PHP", 467833654, 467834707, 12260141, 12261194], ["tinystories/en", "TinyStories-valid", "en", 1582575, 1583199, 12261209, 12261833], ["github/Python", "scikit-learn/scikit-learn", "Python", 292772007, 292776335, 12261848, 12266176], ["tinystories/en", "TinyStories-valid", "en", 16965726, 16966586, 12266191, 12267051], ["tinystories/en", "TinyStories-valid", "en", 1179354, 1180315, 12267066, 12268027], ["github/Scala", "scala/scala", "Scala", 502148236, 502251469, 12268042, 12371275], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 313482195, 313504152, 12371290, 12393247], ["github/C++", "protocolbuffers/protobuf", "C++", 408571300, 408593850, 12393262, 12415812], ["tinystories/en", "TinyStories-valid", "en", 10934293, 10935049, 12415827, 12416583], ["tinystories/en", "TinyStories-valid", "en", 4035530, 4035907, 12416598, 12416975], ["github/Python", "django/django", "Python", 287055452, 287056124, 12416990, 12417662], ["github/PHP", "laravel/framework", "PHP", 466074930, 466081784, 12417677, 12424531], ["tinystories/en", "TinyStories-valid", "en", 10848062, 10848842, 12424546, 12425326], ["tinystories/en", "TinyStories-valid", "en", 17138370, 17139226, 12425341, 12426197], ["github/C#", "dotnet/aspnetcore", "C#", 440109968, 440133930, 12426212, 12450174], ["github/TypeScript", "nestjs/nest", "TypeScript", 333681618, 333682322, 12450189, 12450893], ["tinystories/en", "TinyStories-valid", "en", 9017786, 9018492, 12450908, 12451614], ["tinystories/en", "TinyStories-valid", "en", 16306973, 16307928, 12451629, 12452584], ["github/TypeScript", "nestjs/nest", "TypeScript", 334645706, 334647783, 12452599, 12454676], ["tinystories/en", "TinyStories-valid", "en", 3544680, 3545345, 12454691, 12455356], ["github/TypeScript", "nestjs/nest", "TypeScript", 334676111, 334676161, 12455371, 12455421], ["tinystories/en", "TinyStories-valid", "en", 592268, 593335, 12455436, 12456503], ["tinystories/en", "TinyStories-valid", "en", 11429804, 11430858, 12456518, 12457572], ["github/PHP", "symfony/symfony", "PHP", 478880425, 478884445, 12457587, 12461607], ["books/fr", "PG #7263", "fr", 238848912, 239139745, 12461622, 12752455], ["github/TypeScript", "nestjs/nest", "TypeScript", 337429909, 337434325, 12752457, 12756873], ["tinystories/en", "TinyStories-valid", "en", 17100141, 17100940, 12756888, 12757687], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491227553, 491262202, 12757702, 12792351], ["tinystories/en", "TinyStories-valid", "en", 5763046, 5763894, 12792366, 12793214], ["github/Go", "gohugoio/hugo", "Go", 372231063, 372233536, 12793229, 12795702], ["books/en", "PG #58", "en", 61138875, 61230446, 12795717, 12887288], ["github/PHP", "symfony/symfony", "PHP", 474504260, 474505049, 12887290, 12888079], ["tinystories/en", "TinyStories-valid", "en", 7246122, 7247706, 12888094, 12889678], ["github/C++", "opencv/opencv", "C++", 398380486, 398382647, 12889693, 12891854], ["github/PHP", "symfony/symfony", "PHP", 474489752, 474490686, 12891869, 12892803], ["github/TypeScript", "nestjs/nest", "TypeScript", 337123569, 337126062, 12892818, 12895311], ["tinystories/en", "TinyStories-valid", "en", 2041480, 2042266, 12895326, 12896112], ["github/Rust", "BurntSushi/ripgrep", "Rust", 339391153, 339416750, 12896127, 12921724], ["github/PHP", "symfony/symfony", "PHP", 477313777, 477314708, 12921739, 12922670], ["tinystories/en", "TinyStories-valid", "en", 4061368, 4062007, 12922685, 12923324], ["github/C++", "protocolbuffers/protobuf", "C++", 403249110, 403251372, 12923339, 12925601], ["github/PHP", "laravel/framework", "PHP", 468097924, 468098229, 12925616, 12925921], ["tinystories/en", "TinyStories-valid", "en", 5470779, 5472350, 12925936, 12927507], ["github/PHP", "symfony/symfony", "PHP", 479099833, 479101261, 12927522, 12928950], ["github/TypeScript", "angular/angular", "TypeScript", 326658984, 326661470, 12928965, 12931451], ["tinystories/en", "TinyStories-valid", "en", 11957728, 11958466, 12931466, 12932204], ["github/Go", "gohugoio/hugo", "Go", 372116264, 372122500, 12932219, 12938455], ["tinystories/en", "TinyStories-valid", "en", 14087396, 14089356, 12938470, 12940430], ["github/Ruby", "rails/rails", "Ruby", 456506981, 456513111, 12940445, 12946575], ["github/TypeScript", "nestjs/nest", "TypeScript", 335665083, 335668827, 12946590, 12950334], ["tinystories/en", "TinyStories-valid", "en", 18175854, 18176511, 12950349, 12951006], ["github/Swift", "vapor/vapor", "Swift", 497851636, 497854969, 12951021, 12954354], ["tinystories/en", "TinyStories-valid", "en", 15017597, 15018284, 12954369, 12955056], ["github/PHP", "symfony/symfony", "PHP", 479189226, 479197420, 12955071, 12963265], ["tinystories/en", "TinyStories-valid", "en", 2981361, 2982570, 12963280, 12964489], ["github/Go", "gohugoio/hugo", "Go", 369952512, 369953193, 12964504, 12965185], ["github/C#", "dotnet/aspnetcore", "C#", 443912529, 443913974, 12965200, 12966645], ["tinystories/en", "TinyStories-valid", "en", 17020966, 17021538, 12966660, 12967232], ["github/TypeScript", "nestjs/nest", "TypeScript", 333741958, 333744861, 12967247, 12970150], ["tinystories/en", "TinyStories-valid", "en", 342625, 343245, 12970165, 12970785], ["tinystories/en", "TinyStories-valid", "en", 2227667, 2228501, 12970800, 12971634], ["github/C++", "protocolbuffers/protobuf", "C++", 408545849, 408565686, 12971649, 12991486], ["tinystories/en", "TinyStories-valid", "en", 490513, 491188, 12991501, 12992176], ["tinystories/en", "TinyStories-valid", "en", 6122754, 6123780, 12992191, 12993217], ["github/C#", "dotnet/aspnetcore", "C#", 442496809, 442500606, 12993232, 12997029], ["github/PHP", "laravel/framework", "PHP", 467055468, 467056233, 12997044, 12997809], ["github/TypeScript", "nestjs/nest", "TypeScript", 336605133, 336609345, 12997824, 13002036], ["tinystories/en", "TinyStories-valid", "en", 18214904, 18215803, 13002051, 13002950], ["github/Go", "gohugoio/hugo", "Go", 370363711, 370370984, 13002965, 13010238], ["github/PHP", "symfony/symfony", "PHP", 476846275, 476847063, 13010253, 13011041], ["tinystories/en", "TinyStories-valid", "en", 6634866, 6635403, 13011056, 13011593], ["github/Ruby", "rails/rails", "Ruby", 457064604, 457067103, 13011608, 13014107], ["github/PHP", "laravel/framework", "PHP", 469451184, 469451664, 13014122, 13014602], ["books/en", "PG #391", "en", 190322073, 190514279, 13014617, 13206823], ["tinystories/en", "TinyStories-valid", "en", 4159975, 4160657, 13206825, 13207507], ["github/Rust", "serde-rs/serde", "Rust", 346862173, 346862366, 13207522, 13207715], ["github/PHP", "symfony/symfony", "PHP", 477921573, 477922878, 13207730, 13209035], ["tinystories/en", "TinyStories-valid", "en", 9717649, 9718698, 13209050, 13210099], ["github/C#", "dotnet/aspnetcore", "C#", 440502627, 440503682, 13210114, 13211169], ["github/TypeScript", "nestjs/nest", "TypeScript", 335580993, 335582385, 13211184, 13212576], ["tinystories/en", "TinyStories-valid", "en", 4030209, 4030632, 13212591, 13213014], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515318640, 515337101, 13213029, 13231490], ["tinystories/en", "TinyStories-valid", "en", 466849, 467508, 13231505, 13232164], ["github/Ruby", "sinatra/sinatra", "Ruby", 462094665, 462094991, 13232179, 13232505], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315781584, 315811676, 13232520, 13262612], ["tinystories/en", "TinyStories-valid", "en", 7384779, 7385501, 13262627, 13263349], ["github/PHP", "guzzle/guzzle", "PHP", 481192516, 481195645, 13263364, 13266493], ["github/C#", "dotnet/aspnetcore", "C#", 445857583, 445860639, 13266508, 13269564], ["tinystories/en", "TinyStories-valid", "en", 13306738, 13307618, 13269579, 13270459], ["github/Ruby", "jekyll/jekyll", "Ruby", 461379111, 461380476, 13270474, 13271839], ["github/TypeScript", "angular/angular", "TypeScript", 324816722, 324821160, 13271854, 13276292], ["github/C", "madler/zlib", "C", 384284824, 384308225, 13276307, 13299708], ["tinystories/en", "TinyStories-valid", "en", 7785367, 7785952, 13299723, 13300308], ["github/Go", "gohugoio/hugo", "Go", 367068087, 367070580, 13300323, 13302816], ["tinystories/en", "TinyStories-valid", "en", 16900357, 16900964, 13302831, 13303438], ["github/Python", "scikit-learn/scikit-learn", "Python", 299004617, 299057678, 13303453, 13356514], ["github/Ruby", "rails/rails", "Ruby", 453285993, 453286302, 13356529, 13356838], ["tinystories/en", "TinyStories-valid", "en", 8095873, 8096426, 13356853, 13357406], ["github/Rust", "tokio-rs/tokio", "Rust", 341539052, 341549630, 13357421, 13367999], ["github/C++", "protocolbuffers/protobuf", "C++", 405993412, 405997295, 13368014, 13371897], ["tinystories/en", "TinyStories-valid", "en", 17107718, 17108597, 13371912, 13372791], ["github/PHP", "laravel/framework", "PHP", 462884072, 462887674, 13372806, 13376408], ["github/TypeScript", "microsoft/vscode", "TypeScript", 318837177, 318838046, 13376423, 13377292], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 447141714, 447143863, 13377307, 13379456], ["github/Kotlin", "ktorio/ktor", "Kotlin", 495650057, 495651227, 13379471, 13380641], ["tinystories/en", "TinyStories-valid", "en", 9094152, 9094874, 13380656, 13381378], ["github/TypeScript", "nestjs/nest", "TypeScript", 337940575, 337942302, 13381393, 13383120], ["tinystories/en", "TinyStories-valid", "en", 7299132, 7301182, 13383135, 13385185], ["github/C++", "opencv/opencv", "C++", 400304136, 400308637, 13385200, 13389701], ["tinystories/en", "TinyStories-valid", "en", 8662073, 8662803, 13389716, 13390446], ["github/Ruby", "rails/rails", "Ruby", 460410604, 460414827, 13390461, 13394684], ["github/TypeScript", "nestjs/nest", "TypeScript", 335897779, 335900868, 13394699, 13397788], ["tinystories/en", "TinyStories-valid", "en", 2587504, 2588524, 13397803, 13398823], ["stdlib/python", "python3.13 stdlib", "Python", 20148261, 20182825, 13398838, 13433402], ["tinystories/en", "TinyStories-valid", "en", 11200815, 11201809, 13433404, 13434398], ["github/Rust", "rust-lang/cargo", "Rust", 352738296, 352739332, 13434413, 13435449], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492532224, 492538565, 13435464, 13441805], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 448310346, 448316730, 13441820, 13448204], ["github/TypeScript", "angular/angular", "TypeScript", 328288518, 328290520, 13448219, 13450221], ["github/PHP", "symfony/symfony", "PHP", 476739467, 476747884, 13450236, 13458653], ["tinystories/en", "TinyStories-valid", "en", 6597840, 6598747, 13458668, 13459575], ["github/C++", "protocolbuffers/protobuf", "C++", 401187361, 401193642, 13459590, 13465871], ["tinystories/en", "TinyStories-valid", "en", 11471153, 11471899, 13465886, 13466632], ["github/Rust", "rust-lang/cargo", "Rust", 348002625, 348005507, 13466647, 13469529], ["github/TypeScript", "microsoft/vscode", "TypeScript", 318899319, 318900023, 13469544, 13470248], ["tinystories/en", "TinyStories-valid", "en", 7675379, 7675987, 13470263, 13470871], ["github/TypeScript", "vuejs/core", "TypeScript", 320707607, 320708087, 13470886, 13471366], ["github/TypeScript", "vuejs/core", "TypeScript", 319528568, 319528675, 13471381, 13471488], ["tinystories/en", "TinyStories-valid", "en", 11416339, 11416725, 13471503, 13471889], ["github/TypeScript", "nestjs/nest", "TypeScript", 337835095, 337835200, 13471904, 13472009], ["github/TypeScript", "nestjs/nest", "TypeScript", 337888753, 337890075, 13472024, 13473346], ["tinystories/en", "TinyStories-valid", "en", 11703256, 11705192, 13473361, 13475297], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 482019632, 482019864, 13475312, 13475544], ["github/C++", "google/leveldb", "C++", 392325357, 392326824, 13475559, 13477026], ["books/en", "PG #1232 (prince)", "en", 31938266, 32077302, 13477041, 13616077], ["tinystories/en", "TinyStories-valid", "en", 1476371, 1477079, 13616079, 13616787], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 450052848, 450054254, 13616802, 13618208], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486014294, 486015979, 13618223, 13619908], ["github/PHP", "symfony/symfony", "PHP", 472000747, 472001860, 13619923, 13621036], ["tinystories/en", "TinyStories-valid", "en", 11993688, 11994415, 13621051, 13621778], ["github/PHP", "laravel/framework", "PHP", 468067041, 468067498, 13621793, 13622250], ["github/Ruby", "rails/rails", "Ruby", 454939532, 454943959, 13622265, 13626692], ["github/Go", "gin-gonic/gin", "Go", 356905979, 356927182, 13626707, 13647910], ["tinystories/en", "TinyStories-valid", "en", 6703443, 6704295, 13647925, 13648777], ["github/PHP", "laravel/framework", "PHP", 463041079, 463041353, 13648792, 13649066], ["github/C#", "dotnet/aspnetcore", "C#", 442289541, 442291132, 13649081, 13650672], ["github/C++", "protocolbuffers/protobuf", "C++", 401108263, 401113612, 13650687, 13656036], ["tinystories/en", "TinyStories-valid", "en", 16974258, 16974899, 13656051, 13656692], ["github/PHP", "symfony/symfony", "PHP", 473282878, 473284503, 13656707, 13658332], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486480675, 486482832, 13658347, 13660504], ["github/Swift", "vapor/vapor", "Swift", 498705812, 498710588, 13660519, 13665295], ["github/JavaScript", "axios/axios", "JavaScript", 308590200, 308593705, 13665310, 13668815], ["tinystories/en", "TinyStories-valid", "en", 2731089, 2732017, 13668830, 13669758], ["tinystories/en", "TinyStories-valid", "en", 7072434, 7073076, 13669773, 13670415], ["github/PHP", "laravel/framework", "PHP", 464480570, 464481535, 13670430, 13671395], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486328275, 486328707, 13671410, 13671842], ["github/C++", "opencv/opencv", "C++", 392445931, 392446228, 13671857, 13672154], ["tinystories/en", "TinyStories-valid", "en", 5434708, 5435656, 13672169, 13673117], ["github/Kotlin", "ktorio/ktor", "Kotlin", 495316221, 495317562, 13673132, 13674473], ["tinystories/en", "TinyStories-valid", "en", 16443313, 16444686, 13674488, 13675861], ["github/Ruby", "rails/rails", "Ruby", 458486757, 458487036, 13675876, 13676155], ["github/Scala", "playframework/playframework", "Scala", 511044984, 511045518, 13676170, 13676704], ["tinystories/en", "TinyStories-valid", "en", 18241837, 18242721, 13676719, 13677603], ["github/Rust", "alacritty/alacritty", "Rust", 355288452, 355305922, 13677618, 13695088], ["github/Ruby", "sinatra/sinatra", "Ruby", 462620636, 462621901, 13695103, 13696368], ["github/Scala", "scala/scala", "Scala", 499119130, 499122082, 13696383, 13699335], ["tinystories/en", "TinyStories-valid", "en", 406221, 407082, 13699350, 13700211], ["github/C#", "dotnet/aspnetcore", "C#", 440403469, 440411251, 13700226, 13708008], ["github/C", "curl/curl", "C", 377475172, 377480190, 13708023, 13713041], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489665358, 489668563, 13713056, 13716261], ["github/Ruby", "rails/rails", "Ruby", 453396192, 453396221, 13716276, 13716305], ["tinystories/en", "TinyStories-valid", "en", 18975705, 18976502, 13716320, 13717117], ["tinystories/en", "TinyStories-valid", "en", 766894, 767654, 13717132, 13717892], ["tinystories/en", "TinyStories-valid", "en", 13087955, 13088852, 13717907, 13718804], ["github/C++", "opencv/opencv", "C++", 392849319, 392864572, 13718819, 13734072], ["tinystories/en", "TinyStories-valid", "en", 6743590, 6744226, 13734087, 13734723], ["github/PHP", "laravel/framework", "PHP", 470837304, 470850418, 13734738, 13747852], ["tinystories/en", "TinyStories-valid", "en", 12271174, 12271948, 13747867, 13748641], ["github/Scala", "scala/scala", "Scala", 501373433, 501380576, 13748656, 13755799], ["tinystories/en", "TinyStories-valid", "en", 18134125, 18134856, 13755814, 13756545], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494981821, 494985763, 13756560, 13760502], ["tinystories/en", "TinyStories-valid", "en", 13479481, 13480389, 13760517, 13761425], ["github/Ruby", "rails/rails", "Ruby", 456274058, 456279019, 13761440, 13766401], ["tinystories/en", "TinyStories-valid", "en", 710545, 711267, 13766416, 13767138], ["github/C", "curl/curl", "C", 379853841, 379856859, 13767153, 13770171], ["github/Go", "gohugoio/hugo", "Go", 366690034, 366691213, 13770186, 13771365], ["tinystories/en", "TinyStories-valid", "en", 10876196, 10876882, 13771380, 13772066], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 448771134, 448774955, 13772081, 13775902], ["tinystories/en", "TinyStories-valid", "en", 8708234, 8708923, 13775917, 13776606], ["tinystories/en", "TinyStories-valid", "en", 1233457, 1234207, 13776621, 13777371], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486309767, 486310741, 13777386, 13778360], ["github/Rust", "rust-lang/cargo", "Rust", 347697748, 347697811, 13778375, 13778438], ["github/Python", "django/django", "Python", 282419485, 282420235, 13778453, 13779203], ["tinystories/en", "TinyStories-valid", "en", 7557564, 7558517, 13779218, 13780171], ["tinystories/en", "TinyStories-valid", "en", 8085705, 8086342, 13780186, 13780823], ["github/C#", "dotnet/aspnetcore", "C#", 444980925, 444981581, 13780838, 13781494], ["github/C++", "opencv/opencv", "C++", 397975800, 397979373, 13781509, 13785082], ["github/PHP", "laravel/framework", "PHP", 469945178, 469946005, 13785097, 13785924], ["github/Rust", "tokio-rs/tokio", "Rust", 344824969, 344829095, 13785939, 13790065], ["github/PHP", "laravel/framework", "PHP", 467970006, 467970379, 13790080, 13790453], ["tinystories/en", "TinyStories-valid", "en", 11695401, 11697361, 13790468, 13792428], ["github/JavaScript", "webpack/webpack", "JavaScript", 306726570, 306754222, 13792443, 13820095], ["github/Python", "scikit-learn/scikit-learn", "Python", 291165846, 291170522, 13820110, 13824786], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487828839, 487833494, 13824801, 13829456], ["github/C++", "protocolbuffers/protobuf", "C++", 408842178, 408843230, 13829471, 13830523], ["github/Go", "prometheus/prometheus", "Go", 361203433, 361211577, 13830538, 13838682], ["tinystories/en", "TinyStories-valid", "en", 3551015, 3551949, 13838697, 13839631], ["github/PHP", "symfony/symfony", "PHP", 471387054, 471390000, 13839646, 13842592], ["github/Rust", "rust-lang/cargo", "Rust", 352795749, 352796793, 13842607, 13843651], ["tinystories/en", "TinyStories-valid", "en", 11049779, 11050579, 13843666, 13844466], ["tinystories/en", "TinyStories-valid", "en", 10298538, 10299408, 13844481, 13845351], ["github/PHP", "laravel/framework", "PHP", 470467838, 470468268, 13845366, 13845796], ["tinystories/en", "TinyStories-valid", "en", 1061590, 1062296, 13845811, 13846517], ["github/Rust", "rust-lang/cargo", "Rust", 350917715, 350920283, 13846532, 13849100], ["github/Java", "google/guava", "Java", 410775403, 410974908, 13849115, 14048620], ["github/PHP", "laravel/framework", "PHP", 468166875, 468168334, 14048635, 14050094], ["tinystories/en", "TinyStories-valid", "en", 19307706, 19308334, 14050109, 14050737], ["github/Scala", "sbt/sbt", "Scala", 519733581, 519751794, 14050752, 14068965], ["tinystories/en", "TinyStories-valid", "en", 2741669, 2742527, 14068980, 14069838], ["github/Rust", "rust-lang/cargo", "Rust", 352886503, 352886809, 14069853, 14070159], ["github/PHP", "laravel/framework", "PHP", 463865537, 463867695, 14070174, 14072332], ["tinystories/en", "TinyStories-valid", "en", 8882950, 8884084, 14072347, 14073481], ["tinystories/en", "TinyStories-valid", "en", 4286196, 4287074, 14073496, 14074374], ["tinystories/en", "TinyStories-valid", "en", 4772616, 4773353, 14074389, 14075126], ["tinystories/en", "TinyStories-valid", "en", 19025777, 19026442, 14075141, 14075806], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487639359, 487648267, 14075821, 14084729], ["github/C", "libuv/libuv", "C", 382572815, 382589031, 14084744, 14100960], ["tinystories/en", "TinyStories-valid", "en", 4662317, 4663311, 14100975, 14101969], ["github/Rust", "alacritty/alacritty", "Rust", 355713965, 355722065, 14101984, 14110084], ["github/C++", "nlohmann/json", "C++", 386223842, 386245833, 14110099, 14132090], ["tinystories/en", "TinyStories-valid", "en", 6979004, 6979844, 14132105, 14132945], ["github/PHP", "symfony/symfony", "PHP", 479091987, 479099818, 14132960, 14140791], ["tinystories/en", "TinyStories-valid", "en", 16747638, 16748458, 14140806, 14141626], ["tinystories/en", "TinyStories-valid", "en", 16812531, 16813297, 14141641, 14142407], ["github/Python", "django/django", "Python", 282682010, 282701384, 14142422, 14161796], ["tinystories/en", "TinyStories-valid", "en", 8697670, 8698377, 14161811, 14162518], ["tinystories/en", "TinyStories-valid", "en", 12765822, 12766690, 14162533, 14163401], ["github/Scala", "scala/scala", "Scala", 506818736, 506820685, 14163416, 14165365], ["github/Go", "gohugoio/hugo", "Go", 372438372, 372453124, 14165380, 14180132], ["tinystories/en", "TinyStories-valid", "en", 2943951, 2944737, 14180147, 14180933], ["github/JavaScript", "webpack/webpack", "JavaScript", 305765222, 305766071, 14180948, 14181797], ["tinystories/en", "TinyStories-valid", "en", 3519760, 3520542, 14181812, 14182594], ["github/Rust", "tokio-rs/tokio", "Rust", 344836491, 344839138, 14182609, 14185256], ["github/PHP", "laravel/framework", "PHP", 467926430, 467926826, 14185271, 14185667], ["github/C#", "dotnet/aspnetcore", "C#", 439987808, 440014016, 14185682, 14211890], ["tinystories/en", "TinyStories-valid", "en", 17004613, 17005418, 14211905, 14212710], ["github/PHP", "laravel/framework", "PHP", 466577486, 466578810, 14212725, 14214049], ["tinystories/en", "TinyStories-valid", "en", 127040, 127643, 14214064, 14214667], ["github/Rust", "rust-lang/cargo", "Rust", 352728231, 352728626, 14214682, 14215077], ["github/PHP", "symfony/symfony", "PHP", 471235906, 471236387, 14215092, 14215573], ["github/Rust", "rust-lang/cargo", "Rust", 353114251, 353114572, 14215588, 14215909], ["tinystories/en", "TinyStories-valid", "en", 13090444, 13091183, 14215924, 14216663], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490961898, 490965488, 14216678, 14220268], ["tinystories/en", "TinyStories-valid", "en", 18134871, 18135665, 14220283, 14221077], ["tinystories/en", "TinyStories-valid", "en", 3849601, 3850375, 14221092, 14221866], ["github/Scala", "scala/scala", "Scala", 500165580, 500175722, 14221881, 14232023], ["github/PHP", "laravel/framework", "PHP", 465540320, 465544733, 14232038, 14236451], ["tinystories/en", "TinyStories-valid", "en", 15081417, 15082251, 14236466, 14237300], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 483971338, 483972411, 14237315, 14238388], ["tinystories/en", "TinyStories-valid", "en", 13099627, 13100329, 14238403, 14239105], ["tinystories/en", "TinyStories-valid", "en", 7563575, 7564298, 14239120, 14239843], ["github/C++", "nlohmann/json", "C++", 385668585, 385675761, 14239858, 14247034], ["tinystories/en", "TinyStories-valid", "en", 11546081, 11546677, 14247049, 14247645], ["github/C", "libuv/libuv", "C", 381015255, 381016131, 14247660, 14248536], ["tinystories/en", "TinyStories-valid", "en", 13744592, 13745177, 14248551, 14249136], ["books/en", "PG #161", "en", 111926093, 112606430, 14249151, 14929488], ["github/Ruby", "rails/rails", "Ruby", 457223585, 457247782, 14929490, 14953687], ["tinystories/en", "TinyStories-valid", "en", 16850812, 16851445, 14953702, 14954335], ["github/Python", "django/django", "Python", 283290032, 283291607, 14954350, 14955925], ["tinystories/en", "TinyStories-valid", "en", 13244066, 13244764, 14955940, 14956638], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490303008, 490307752, 14956653, 14961397], ["tinystories/en", "TinyStories-valid", "en", 13190278, 13191202, 14961412, 14962336], ["github/C++", "nlohmann/json", "C++", 385614217, 385614661, 14962351, 14962795], ["github/C", "jqlang/jq", "C", 385249873, 385252520, 14962810, 14965457], ["github/Python", "django/django", "Python", 282456239, 282457258, 14965472, 14966491], ["github/Go", "prometheus/prometheus", "Go", 359584701, 359588638, 14966506, 14970443], ["tinystories/en", "TinyStories-valid", "en", 18191581, 18192208, 14970458, 14971085], ["github/Scala", "sbt/sbt", "Scala", 520481600, 520484180, 14971100, 14973680], ["tinystories/en", "TinyStories-valid", "en", 1659833, 1660760, 14973695, 14974622], ["github/Python", "django/django", "Python", 282802092, 282804514, 14974637, 14977059], ["github/Scala", "playframework/playframework", "Scala", 511162997, 511163171, 14977074, 14977248], ["github/Scala", "sbt/sbt", "Scala", 519753527, 519753700, 14977263, 14977436], ["tinystories/en", "TinyStories-valid", "en", 10408472, 10409456, 14977451, 14978435], ["github/TypeScript", "angular/angular", "TypeScript", 331682561, 331781859, 14978450, 15077748], ["github/PHP", "symfony/symfony", "PHP", 473271585, 473282863, 15077763, 15089041], ["tinystories/en", "TinyStories-valid", "en", 12038174, 12038799, 15089056, 15089681], ["github/Scala", "sbt/sbt", "Scala", 520744068, 520747379, 15089696, 15093007], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490049396, 490051430, 15093022, 15095056], ["tinystories/en", "TinyStories-valid", "en", 8825876, 8826809, 15095071, 15096004], ["github/Go", "gohugoio/hugo", "Go", 366371679, 366374591, 15096019, 15098931], ["tinystories/en", "TinyStories-valid", "en", 17176748, 17177338, 15098946, 15099536], ["tinystories/en", "TinyStories-valid", "en", 11323017, 11323809, 15099551, 15100343], ["tinystories/en", "TinyStories-valid", "en", 5474289, 5474980, 15100358, 15101049], ["github/C", "curl/curl", "C", 378804861, 378810304, 15101064, 15106507], ["tinystories/en", "TinyStories-valid", "en", 4795517, 4796174, 15106522, 15107179], ["github/Scala", "scala/scala", "Scala", 506182158, 506185706, 15107194, 15110742], ["tinystories/en", "TinyStories-valid", "en", 10261373, 10262038, 15110757, 15111422], ["tinystories/en", "TinyStories-valid", "en", 17475985, 17476635, 15111437, 15112087], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490217942, 490222960, 15112102, 15117120], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449728914, 449730454, 15117135, 15118675], ["tinystories/en", "TinyStories-valid", "en", 4636973, 4638585, 15118690, 15120302], ["github/Python", "scikit-learn/scikit-learn", "Python", 291855555, 291867109, 15120317, 15131871], ["github/Go", "prometheus/prometheus", "Go", 361196558, 361203418, 15131886, 15138746], ["tinystories/en", "TinyStories-valid", "en", 16294408, 16295245, 15138761, 15139598], ["github/Rust", "tokio-rs/tokio", "Rust", 341856549, 341891660, 15139613, 15174724], ["tinystories/en", "TinyStories-valid", "en", 15906734, 15907712, 15174739, 15175717], ["github/C", "curl/curl", "C", 380187643, 380189663, 15175732, 15177752], ["tinystories/en", "TinyStories-valid", "en", 638073, 638660, 15177767, 15178354], ["github/Scala", "sbt/sbt", "Scala", 518849767, 518857598, 15178369, 15186200], ["github/PHP", "symfony/symfony", "PHP", 471762269, 471769325, 15186215, 15193271], ["tinystories/en", "TinyStories-valid", "en", 18173539, 18174166, 15193286, 15193913], ["tinystories/en", "TinyStories-valid", "en", 17164264, 17165314, 15193928, 15194978], ["tinystories/en", "TinyStories-valid", "en", 8144250, 8144991, 15194993, 15195734], ["github/C#", "dotnet/aspnetcore", "C#", 438485574, 438493500, 15195749, 15203675], ["github/C", "curl/curl", "C", 380334240, 380336582, 15203690, 15206032], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 487302859, 487308107, 15206047, 15211295], ["tinystories/en", "TinyStories-valid", "en", 9806701, 9807487, 15211310, 15212096], ["github/Go", "gohugoio/hugo", "Go", 370532085, 370533579, 15212111, 15213605], ["tinystories/en", "TinyStories-valid", "en", 6733914, 6734503, 15213620, 15214209], ["tinystories/en", "TinyStories-valid", "en", 8674698, 8675678, 15214224, 15215204], ["github/PHP", "guzzle/guzzle", "PHP", 480531679, 480532897, 15215219, 15216437], ["books/fr", "PG #6739", "fr", 236285411, 236691443, 15216452, 15622484], ["tinystories/en", "TinyStories-valid", "en", 8284792, 8285679, 15622486, 15623373], ["github/PHP", "symfony/symfony", "PHP", 478157977, 478159191, 15623388, 15624602], ["tinystories/en", "TinyStories-valid", "en", 15066661, 15067361, 15624617, 15625317], ["github/Scala", "playframework/playframework", "Scala", 512312389, 512318339, 15625332, 15631282], ["github/PHP", "guzzle/guzzle", "PHP", 479803292, 479803521, 15631297, 15631526], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491033792, 491034614, 15631541, 15632363], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 311895974, 311951144, 15632378, 15687548], ["tinystories/en", "TinyStories-valid", "en", 9121583, 9122586, 15687563, 15688566], ["github/PHP", "symfony/symfony", "PHP", 472304980, 472305856, 15688581, 15689457], ["tinystories/en", "TinyStories-valid", "en", 6727293, 6728186, 15689472, 15690365], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486549674, 486550827, 15690380, 15691533], ["github/Python", "django/django", "Python", 286051672, 286061258, 15691548, 15701134], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 450095370, 450096739, 15701149, 15702518], ["tinystories/en", "TinyStories-valid", "en", 8128236, 8129033, 15702533, 15703330], ["tinystories/en", "TinyStories-valid", "en", 16449061, 16450412, 15703345, 15704696], ["github/C#", "dotnet/aspnetcore", "C#", 442357521, 442358982, 15704711, 15706172], ["github/PHP", "laravel/framework", "PHP", 465183823, 465189465, 15706187, 15711829], ["github/Kotlin", "ktorio/ktor", "Kotlin", 493522603, 493525776, 15711844, 15715017], ["tinystories/en", "TinyStories-valid", "en", 5332611, 5333591, 15715032, 15716012], ["github/C#", "dotnet/aspnetcore", "C#", 442462843, 442464148, 15716027, 15717332], ["tinystories/en", "TinyStories-valid", "en", 1095013, 1095888, 15717347, 15718222], ["github/Scala", "playframework/playframework", "Scala", 509790162, 509797893, 15718237, 15725968], ["tinystories/en", "TinyStories-valid", "en", 15960926, 15961656, 15725983, 15726713], ["github/C", "curl/curl", "C", 378733228, 378744326, 15726728, 15737826], ["github/C#", "dotnet/aspnetcore", "C#", 440107325, 440108775, 15737841, 15739291], ["tinystories/en", "TinyStories-valid", "en", 13335841, 13337381, 15739306, 15740846], ["github/Ruby", "rails/rails", "Ruby", 453224706, 453230278, 15740861, 15746433], ["github/C#", "dotnet/aspnetcore", "C#", 445940261, 445940887, 15746448, 15747074], ["tinystories/en", "TinyStories-valid", "en", 4820155, 4820722, 15747089, 15747656], ["tinystories/en", "TinyStories-valid", "en", 3716246, 3717087, 15747671, 15748512], ["github/C#", "dotnet/aspnetcore", "C#", 445741333, 445741940, 15748527, 15749134], ["tinystories/en", "TinyStories-valid", "en", 10024109, 10024599, 15749149, 15749639], ["github/Scala", "sbt/sbt", "Scala", 520640190, 520640771, 15749654, 15750235], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 483284077, 483289996, 15750250, 15756169], ["github/PHP", "symfony/symfony", "PHP", 474556368, 474563180, 15756184, 15762996], ["tinystories/en", "TinyStories-valid", "en", 15709795, 15710638, 15763011, 15763854], ["tinystories/en", "TinyStories-valid", "en", 808326, 809046, 15763869, 15764589], ["github/Rust", "tokio-rs/tokio", "Rust", 344518524, 344520513, 15764604, 15766593], ["tinystories/en", "TinyStories-valid", "en", 11927570, 11928177, 15766608, 15767215], ["tinystories/en", "TinyStories-valid", "en", 19160541, 19161914, 15767230, 15768603], ["github/Python", "django/django", "Python", 289898710, 289911399, 15768618, 15781307], ["github/Scala", "playframework/playframework", "Scala", 509604897, 509611995, 15781322, 15788420], ["tinystories/en", "TinyStories-valid", "en", 3244468, 3245116, 15788435, 15789083], ["github/PHP", "symfony/symfony", "PHP", 479069110, 479070171, 15789098, 15790159], ["tinystories/en", "TinyStories-valid", "en", 5073334, 5073841, 15790174, 15790681], ["github/Go", "prometheus/prometheus", "Go", 360405305, 360434947, 15790696, 15820338], ["tinystories/en", "TinyStories-valid", "en", 5679465, 5680338, 15820353, 15821226], ["github/Rust", "serde-rs/serde", "Rust", 346807612, 346813421, 15821241, 15827050], ["github/PHP", "symfony/symfony", "PHP", 474866921, 474868406, 15827065, 15828550], ["tinystories/en", "TinyStories-valid", "en", 142510, 143251, 15828565, 15829306], ["tinystories/en", "TinyStories-valid", "en", 15271873, 15273080, 15829321, 15830528], ["github/PHP", "symfony/symfony", "PHP", 473293671, 473295700, 15830543, 15832572], ["tinystories/en", "TinyStories-valid", "en", 7948192, 7949402, 15832587, 15833797], ["tinystories/en", "TinyStories-valid", "en", 9585356, 9586445, 15833812, 15834901], ["github/Rust", "tokio-rs/tokio", "Rust", 343146583, 343148787, 15834916, 15837120], ["github/Scala", "scala/scala", "Scala", 506029279, 506035918, 15837135, 15843774], ["tinystories/en", "TinyStories-valid", "en", 5029303, 5030148, 15843789, 15844634], ["tinystories/en", "TinyStories-valid", "en", 13016586, 13017625, 15844649, 15845688], ["github/C++", "protocolbuffers/protobuf", "C++", 407156703, 407256856, 15845703, 15945856], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481824020, 481835654, 15945871, 15957505], ["tinystories/en", "TinyStories-valid", "en", 6505016, 6505739, 15957520, 15958243], ["github/Ruby", "rails/rails", "Ruby", 459049167, 459058282, 15958258, 15967373], ["github/Scala", "sbt/sbt", "Scala", 519830014, 519830058, 15967388, 15967432], ["github/Scala", "playframework/playframework", "Scala", 512645753, 512646340, 15967447, 15968034], ["tinystories/en", "TinyStories-valid", "en", 16224595, 16225846, 15968049, 15969300], ["github/Scala", "playframework/playframework", "Scala", 511105735, 511106237, 15969315, 15969817], ["tinystories/en", "TinyStories-valid", "en", 14486607, 14487811, 15969832, 15971036], ["github/Python", "django/django", "Python", 286097459, 286105924, 15971051, 15979516], ["tinystories/en", "TinyStories-valid", "en", 18538425, 18538982, 15979531, 15980088], ["github/C", "curl/curl", "C", 380260189, 380275621, 15980103, 15995535], ["github/PHP", "laravel/framework", "PHP", 466214027, 466229159, 15995550, 16010682], ["tinystories/en", "TinyStories-valid", "en", 17813383, 17815415, 16010697, 16012729], ["github/Scala", "playframework/playframework", "Scala", 507404242, 507411184, 16012744, 16019686], ["tinystories/en", "TinyStories-valid", "en", 16938762, 16939371, 16019701, 16020310], ["tinystories/en", "TinyStories-valid", "en", 14710181, 14710929, 16020325, 16021073], ["github/Swift", "vapor/vapor", "Swift", 497763599, 497785464, 16021088, 16042953], ["tinystories/en", "TinyStories-valid", "en", 12795646, 12796426, 16042968, 16043748], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 317935850, 317936988, 16043763, 16044901], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492012976, 492013885, 16044916, 16045825], ["tinystories/en", "TinyStories-valid", "en", 10524737, 10525761, 16045840, 16046864], ["github/Scala", "sbt/sbt", "Scala", 519756702, 519756756, 16046879, 16046933], ["github/JavaScript", "webpack/webpack", "JavaScript", 306946826, 306948483, 16046948, 16048605], ["tinystories/en", "TinyStories-valid", "en", 3026896, 3027574, 16048620, 16049298], ["github/Scala", "playframework/playframework", "Scala", 513392331, 513395002, 16049313, 16051984], ["github/TypeScript", "nestjs/nest", "TypeScript", 337749059, 337749366, 16051999, 16052306], ["tinystories/en", "TinyStories-valid", "en", 2386815, 2387383, 16052321, 16052889], ["tinystories/en", "TinyStories-valid", "en", 16982888, 16983705, 16052904, 16053721], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486232964, 486236322, 16053736, 16057094], ["github/Go", "gohugoio/hugo", "Go", 369903841, 369904107, 16057109, 16057375], ["github/Python", "scikit-learn/scikit-learn", "Python", 297159454, 297166823, 16057390, 16064759], ["github/TypeScript", "angular/angular", "TypeScript", 326415774, 326418374, 16064774, 16067374], ["github/Scala", "scala/scala", "Scala", 499229111, 499230362, 16067389, 16068640], ["tinystories/en", "TinyStories-valid", "en", 10370802, 10372036, 16068655, 16069889], ["github/JavaScript", "webpack/webpack", "JavaScript", 304608198, 304611114, 16069904, 16072820], ["tinystories/en", "TinyStories-valid", "en", 572111, 572711, 16072835, 16073435], ["github/PHP", "symfony/symfony", "PHP", 474779806, 474780399, 16073450, 16074043], ["github/Scala", "playframework/playframework", "Scala", 507860868, 507862117, 16074058, 16075307], ["github/Go", "gohugoio/hugo", "Go", 369300420, 369304221, 16075322, 16079123], ["github/PHP", "laravel/framework", "PHP", 466908717, 466909954, 16079138, 16080375], ["books/en", "PG #290", "en", 159187230, 159605906, 16080390, 16499066], ["tinystories/en", "TinyStories-valid", "en", 4667870, 4669595, 16499068, 16500793], ["github/Scala", "playframework/playframework", "Scala", 508886147, 508888265, 16500808, 16502926], ["tinystories/en", "TinyStories-valid", "en", 10431559, 10432316, 16502941, 16503698], ["github/Scala", "sbt/sbt", "Scala", 519779651, 519779692, 16503713, 16503754], ["github/TypeScript", "angular/angular", "TypeScript", 325907954, 325913848, 16503769, 16509663], ["github/Scala", "sbt/sbt", "Scala", 519878470, 519878518, 16509678, 16509726], ["github/Scala", "sbt/sbt", "Scala", 519763229, 519763270, 16509741, 16509782], ["github/Ruby", "rails/rails", "Ruby", 456381301, 456387364, 16509797, 16515860], ["github/Go", "gohugoio/hugo", "Go", 368733103, 368733711, 16515875, 16516483], ["github/PHP", "symfony/symfony", "PHP", 471315181, 471318277, 16516498, 16519594], ["tinystories/en", "TinyStories-valid", "en", 3405732, 3407263, 16519609, 16521140], ["stdlib/python", "python3.13 stdlib", "Python", 24556377, 24589267, 16521155, 16554045], ["github/Python", "scikit-learn/scikit-learn", "Python", 291444965, 291448283, 16554047, 16557365], ["github/Go", "gohugoio/hugo", "Go", 369690936, 369692349, 16557380, 16558793], ["github/C", "curl/curl", "C", 379821564, 379823305, 16558808, 16560549], ["tinystories/en", "TinyStories-valid", "en", 19080231, 19081746, 16560564, 16562079], ["github/Scala", "playframework/playframework", "Scala", 513115398, 513122033, 16562094, 16568729], ["tinystories/en", "TinyStories-valid", "en", 13749005, 13749708, 16568744, 16569447], ["tinystories/en", "TinyStories-valid", "en", 1189069, 1189572, 16569462, 16569965], ["tinystories/en", "TinyStories-valid", "en", 9192652, 9193114, 16569980, 16570442], ["github/C", "libuv/libuv", "C", 381964464, 381966469, 16570457, 16572462], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 450776744, 450827620, 16572477, 16623353], ["github/Python", "scikit-learn/scikit-learn", "Python", 290810477, 290813739, 16623368, 16626630], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 484642099, 484653350, 16626645, 16637896], ["github/Java", "spring-projects/spring-framework", "Java", 420936608, 420981349, 16637911, 16682652], ["tinystories/en", "TinyStories-valid", "en", 17376452, 17377027, 16682667, 16683242], ["github/TypeScript", "vuejs/core", "TypeScript", 321015587, 321021832, 16683257, 16689502], ["github/PHP", "symfony/symfony", "PHP", 473891460, 473898656, 16689517, 16696713], ["tinystories/en", "TinyStories-valid", "en", 15382744, 15384267, 16696728, 16698251], ["github/Rust", "rust-lang/cargo", "Rust", 348095594, 348140203, 16698266, 16742875], ["tinystories/en", "TinyStories-valid", "en", 5188568, 5190296, 16742890, 16744618], ["github/Python", "django/django", "Python", 285954544, 285957093, 16744633, 16747182], ["github/Scala", "sbt/sbt", "Scala", 520188368, 520192144, 16747197, 16750973], ["tinystories/en", "TinyStories-valid", "en", 17341971, 17342809, 16750988, 16751826], ["tinystories/en", "TinyStories-valid", "en", 16077707, 16078459, 16751841, 16752593], ["github/Scala", "playframework/playframework", "Scala", 511622042, 511623128, 16752608, 16753694], ["github/Python", "django/django", "Python", 287444471, 287446621, 16753709, 16755859], ["tinystories/en", "TinyStories-valid", "en", 13723649, 13724358, 16755874, 16756583], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 309890800, 309915258, 16756598, 16781056], ["github/Scala", "playframework/playframework", "Scala", 508130454, 508131594, 16781071, 16782211], ["tinystories/en", "TinyStories-valid", "en", 12752690, 12753522, 16782226, 16783058], ["github/Ruby", "rails/rails", "Ruby", 459927608, 459932698, 16783073, 16788163], ["github/PHP", "laravel/framework", "PHP", 464257280, 464261625, 16788178, 16792523], ["tinystories/en", "TinyStories-valid", "en", 8661306, 8662058, 16792538, 16793290], ["github/TypeScript", "nestjs/nest", "TypeScript", 335333750, 335341016, 16793305, 16800571], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481472431, 481473233, 16800586, 16801388], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492908332, 492908722, 16801403, 16801793], ["tinystories/en", "TinyStories-valid", "en", 5989955, 5991965, 16801808, 16803818], ["github/PHP", "laravel/framework", "PHP", 467007691, 467008275, 16803833, 16804417], ["github/Kotlin", "ktorio/ktor", "Kotlin", 488397929, 488399133, 16804432, 16805636], ["tinystories/en", "TinyStories-valid", "en", 5570868, 5571631, 16805651, 16806414], ["github/PHP", "symfony/symfony", "PHP", 472152465, 472153891, 16806429, 16807855], ["tinystories/en", "TinyStories-valid", "en", 3938410, 3939087, 16807870, 16808547], ["github/TypeScript", "microsoft/vscode", "TypeScript", 319148289, 319148419, 16808562, 16808692], ["tinystories/en", "TinyStories-valid", "en", 18510745, 18511429, 16808707, 16809391], ["github/Ruby", "rails/rails", "Ruby", 456339607, 456339633, 16809406, 16809432], ["github/Python", "django/django", "Python", 285754520, 285764775, 16809447, 16819702], ["tinystories/en", "TinyStories-valid", "en", 1496716, 1497466, 16819717, 16820467], ["github/PHP", "symfony/symfony", "PHP", 471308290, 471310183, 16820482, 16822375], ["tinystories/en", "TinyStories-valid", "en", 326217, 326752, 16822390, 16822925], ["tinystories/en", "TinyStories-valid", "en", 16461429, 16463117, 16822940, 16824628], ["tinystories/en", "TinyStories-valid", "en", 13647640, 13648342, 16824643, 16825345], ["github/PHP", "symfony/symfony", "PHP", 474010198, 474014786, 16825360, 16829948], ["tinystories/en", "TinyStories-valid", "en", 4448712, 4449200, 16829963, 16830451], ["github/TypeScript", "angular/angular", "TypeScript", 329314957, 329324888, 16830466, 16840397], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486636555, 486645138, 16840412, 16848995], ["github/Scala", "sbt/sbt", "Scala", 516035273, 516055397, 16849010, 16869134], ["tinystories/en", "TinyStories-valid", "en", 4477435, 4478347, 16869149, 16870061], ["tinystories/en", "TinyStories-valid", "en", 5836106, 5836639, 16870076, 16870609], ["github/Java", "spring-projects/spring-framework", "Java", 419658942, 419665543, 16870624, 16877225], ["tinystories/en", "TinyStories-valid", "en", 18135680, 18136328, 16877240, 16877888], ["github/PHP", "guzzle/guzzle", "PHP", 479798399, 479798619, 16877903, 16878123], ["tinystories/en", "TinyStories-valid", "en", 17456563, 17457160, 16878138, 16878735], ["github/JavaScript", "webpack/webpack", "JavaScript", 300469144, 300469197, 16878750, 16878803], ["tinystories/en", "TinyStories-valid", "en", 18995060, 18995520, 16878818, 16879278], ["tinystories/en", "TinyStories-valid", "en", 3004894, 3005615, 16879293, 16880014], ["github/Java", "square/okhttp", "Java", 430446168, 430447866, 16880029, 16881727], ["tinystories/en", "TinyStories-valid", "en", 19147477, 19148375, 16881742, 16882640], ["github/C", "curl/curl", "C", 373749593, 373775695, 16882655, 16908757], ["tinystories/en", "TinyStories-valid", "en", 13750675, 13751543, 16908772, 16909640], ["github/Java", "apache/commons-lang", "Java", 435657751, 435659069, 16909655, 16910973], ["github/TypeScript", "angular/angular", "TypeScript", 325044195, 325046084, 16910988, 16912877], ["github/C++", "opencv/opencv", "C++", 393208436, 393214218, 16912892, 16918674], ["github/Ruby", "rails/rails", "Ruby", 458180863, 458191382, 16918689, 16929208], ["tinystories/en", "TinyStories-valid", "en", 16400161, 16400845, 16929223, 16929907], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315668342, 315676103, 16929922, 16937683], ["tinystories/en", "TinyStories-valid", "en", 17170745, 17171387, 16937698, 16938340], ["github/TypeScript", "angular/angular", "TypeScript", 326341953, 326342813, 16938355, 16939215], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 487112071, 487114589, 16939230, 16941748], ["tinystories/en", "TinyStories-valid", "en", 13789039, 13789661, 16941763, 16942385], ["github/TypeScript", "nestjs/nest", "TypeScript", 332431875, 332433565, 16942400, 16944090], ["tinystories/en", "TinyStories-valid", "en", 7259628, 7261173, 16944105, 16945650], ["github/C++", "nlohmann/json", "C++", 385426153, 385427427, 16945665, 16946939], ["github/Java", "google/guava", "Java", 415630584, 415640346, 16946954, 16956716], ["github/TypeScript", "nestjs/nest", "TypeScript", 333614035, 333614636, 16956731, 16957332], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486338475, 486339326, 16957347, 16958198], ["tinystories/en", "TinyStories-valid", "en", 15016715, 15017582, 16958213, 16959080], ["github/C++", "nlohmann/json", "C++", 385537316, 385538347, 16959095, 16960126], ["github/PHP", "symfony/symfony", "PHP", 474898912, 474914061, 16960141, 16975290], ["tinystories/en", "TinyStories-valid", "en", 6981362, 6982031, 16975305, 16975974], ["github/Rust", "tokio-rs/tokio", "Rust", 340211303, 340213687, 16975989, 16978373], ["github/TypeScript", "vuejs/core", "TypeScript", 320969989, 320972472, 16978388, 16980871], ["tinystories/en", "TinyStories-valid", "en", 1023660, 1024475, 16980886, 16981701], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 487488002, 487489773, 16981716, 16983487], ["tinystories/en", "TinyStories-valid", "en", 13889726, 13890619, 16983502, 16984395], ["github/TypeScript", "angular/angular", "TypeScript", 326968663, 326969653, 16984410, 16985400], ["github/Rust", "rust-lang/cargo", "Rust", 352858106, 352859147, 16985415, 16986456], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487542570, 487543144, 16986471, 16987045], ["tinystories/en", "TinyStories-valid", "en", 12112680, 12113412, 16987060, 16987792], ["github/Java", "spring-projects/spring-framework", "Java", 419330952, 419333005, 16987807, 16989860], ["tinystories/en", "TinyStories-valid", "en", 3495191, 3495809, 16989875, 16990493], ["github/TypeScript", "nestjs/nest", "TypeScript", 336962516, 336964104, 16990508, 16992096], ["github/Python", "django/django", "Python", 282955256, 282978933, 16992111, 17015788], ["tinystories/en", "TinyStories-valid", "en", 8412592, 8413227, 17015803, 17016438], ["books/en", "PG #381", "en", 187282740, 187579803, 17016453, 17313516], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492331033, 492333203, 17313518, 17315688], ["github/TypeScript", "nestjs/nest", "TypeScript", 337718003, 337718336, 17315703, 17316036], ["github/Scala", "scala/scala", "Scala", 504965995, 504977022, 17316051, 17327078], ["tinystories/en", "TinyStories-valid", "en", 491802, 492567, 17327093, 17327858], ["github/TypeScript", "nestjs/nest", "TypeScript", 337764630, 337764799, 17327873, 17328042], ["github/TypeScript", "angular/angular", "TypeScript", 326358149, 326358677, 17328057, 17328585], ["tinystories/en", "TinyStories-valid", "en", 18899524, 18900149, 17328600, 17329225], ["github/Java", "google/guava", "Java", 414220120, 414226003, 17329240, 17335123], ["github/TypeScript", "vuejs/core", "TypeScript", 322345376, 322346077, 17335138, 17335839], ["github/JavaScript", "webpack/webpack", "JavaScript", 308373889, 308384109, 17335854, 17346074], ["tinystories/en", "TinyStories-valid", "en", 14085893, 14086436, 17346089, 17346632], ["github/TypeScript", "angular/angular", "TypeScript", 329123444, 329124306, 17346647, 17347509], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481569934, 481570919, 17347524, 17348509], ["tinystories/en", "TinyStories-valid", "en", 7178015, 7178639, 17348524, 17349148], ["github/C#", "dotnet/aspnetcore", "C#", 445970399, 445972457, 17349163, 17351221], ["github/Go", "spf13/cobra", "Go", 357167104, 357228246, 17351236, 17412378], ["tinystories/en", "TinyStories-valid", "en", 5915464, 5917925, 17412393, 17414854], ["github/Java", "spring-projects/spring-framework", "Java", 424897289, 424899349, 17414869, 17416929], ["github/TypeScript", "nestjs/nest", "TypeScript", 332606975, 332609980, 17416944, 17419949], ["github/Kotlin", "ktorio/ktor", "Kotlin", 495739694, 495741987, 17419964, 17422257], ["github/PHP", "symfony/symfony", "PHP", 471322672, 471324289, 17422272, 17423889], ["github/Ruby", "sinatra/sinatra", "Ruby", 462239031, 462242086, 17423904, 17426959], ["github/PHP", "laravel/framework", "PHP", 464083870, 464083991, 17426974, 17427095], ["tinystories/en", "TinyStories-valid", "en", 16130306, 16130875, 17427110, 17427679], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449618438, 449619837, 17427694, 17429093], ["github/Scala", "playframework/playframework", "Scala", 511562762, 511564469, 17429108, 17430815], ["tinystories/en", "TinyStories-valid", "en", 14491222, 14492627, 17430830, 17432235], ["github/Java", "google/guava", "Java", 413907832, 413914012, 17432250, 17438430], ["github/Kotlin", "ktorio/ktor", "Kotlin", 488443546, 488445114, 17438445, 17440013], ["github/Scala", "playframework/playframework", "Scala", 507389743, 507389971, 17440028, 17440256], ["github/C#", "dotnet/aspnetcore", "C#", 444227838, 444228871, 17440271, 17441304], ["tinystories/en", "TinyStories-valid", "en", 9915241, 9915878, 17441319, 17441956], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316853008, 316853858, 17441971, 17442821], ["github/TypeScript", "angular/angular", "TypeScript", 325216337, 325221450, 17442836, 17447949], ["tinystories/en", "TinyStories-valid", "en", 5396913, 5397489, 17447964, 17448540], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316841257, 316842233, 17448555, 17449531], ["github/Scala", "playframework/playframework", "Scala", 509212116, 509214878, 17449546, 17452308], ["github/Ruby", "rails/rails", "Ruby", 454764106, 454764831, 17452323, 17453048], ["github/PHP", "symfony/symfony", "PHP", 475080851, 475087214, 17453063, 17459426], ["tinystories/en", "TinyStories-valid", "en", 8014997, 8015777, 17459441, 17460221], ["github/Java", "spring-projects/spring-framework", "Java", 424348142, 424350260, 17460236, 17462354], ["tinystories/en", "TinyStories-valid", "en", 16063209, 16064016, 17462369, 17463176], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492982721, 492986025, 17463191, 17466495], ["tinystories/en", "TinyStories-valid", "en", 13597182, 13597966, 17466510, 17467294], ["github/JavaScript", "webpack/webpack", "JavaScript", 306578972, 306581806, 17467309, 17470143], ["tinystories/en", "TinyStories-valid", "en", 17931448, 17932231, 17470158, 17470941], ["github/TypeScript", "angular/angular", "TypeScript", 328398985, 328401144, 17470956, 17473115], ["tinystories/en", "TinyStories-valid", "en", 6072645, 6073306, 17473130, 17473791], ["github/C#", "dotnet/aspnetcore", "C#", 444779201, 444786256, 17473806, 17480861], ["github/Ruby", "rails/rails", "Ruby", 457220481, 457223570, 17480876, 17483965], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492892735, 492893136, 17483980, 17484381], ["tinystories/en", "TinyStories-valid", "en", 391391, 392045, 17484396, 17485050], ["tinystories/en", "TinyStories-valid", "en", 12085873, 12086785, 17485065, 17485977], ["github/Java", "spring-projects/spring-framework", "Java", 420981364, 420990762, 17485992, 17495390], ["tinystories/en", "TinyStories-valid", "en", 13203886, 13204600, 17495405, 17496119], ["tinystories/en", "TinyStories-valid", "en", 4983140, 4983694, 17496134, 17496688], ["github/TypeScript", "angular/angular", "TypeScript", 329393639, 329398315, 17496703, 17501379], ["github/PHP", "guzzle/guzzle", "PHP", 480845616, 480851130, 17501394, 17506908], ["github/Scala", "sbt/sbt", "Scala", 520690689, 520702067, 17506923, 17518301], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316209327, 316215293, 17518316, 17524282], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489454264, 489457879, 17524297, 17527912], ["tinystories/en", "TinyStories-valid", "en", 8380278, 8380777, 17527927, 17528426], ["tinystories/en", "TinyStories-valid", "en", 13315025, 13315756, 17528441, 17529172], ["github/Python", "scikit-learn/scikit-learn", "Python", 297456220, 297463835, 17529187, 17536802], ["tinystories/en", "TinyStories-valid", "en", 18729870, 18730651, 17536817, 17537598], ["github/Java", "spring-projects/spring-framework", "Java", 423378988, 423381549, 17537613, 17540174], ["tinystories/en", "TinyStories-valid", "en", 3341803, 3343326, 17540189, 17541712], ["github/JavaScript", "webpack/webpack", "JavaScript", 300475609, 300475844, 17541727, 17541962], ["github/C#", "dotnet/aspnetcore", "C#", 439326743, 439329329, 17541977, 17544563], ["github/Java", "google/guava", "Java", 413473695, 413475041, 17544578, 17545924], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485080403, 485082530, 17545939, 17548066], ["tinystories/en", "TinyStories-valid", "en", 4253907, 4254692, 17548081, 17548866], ["books/en", "PG #406", "en", 195591168, 195669045, 17548881, 17626758], ["github/Java", "square/okhttp", "Java", 428149834, 428150561, 17626760, 17627487], ["github/PHP", "laravel/framework", "PHP", 468617193, 468620657, 17627502, 17630966], ["tinystories/en", "TinyStories-valid", "en", 33349, 33946, 17630981, 17631578], ["github/Java", "spring-projects/spring-framework", "Java", 421164227, 421165718, 17631593, 17633084], ["tinystories/en", "TinyStories-valid", "en", 5618350, 5618975, 17633099, 17633724], ["github/Scala", "playframework/playframework", "Scala", 511623143, 511623673, 17633739, 17634269], ["github/Scala", "sbt/sbt", "Scala", 519851730, 519851919, 17634284, 17634473], ["tinystories/en", "TinyStories-valid", "en", 1490732, 1491802, 17634488, 17635558], ["github/Scala", "sbt/sbt", "Scala", 519874183, 519874707, 17635573, 17636097], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449713140, 449715284, 17636112, 17638256], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 483668038, 483670061, 17638271, 17640294], ["github/Scala", "sbt/sbt", "Scala", 519826951, 519827198, 17640309, 17640556], ["tinystories/en", "TinyStories-valid", "en", 18955041, 18955926, 17640571, 17641456], ["stdlib/python", "python3.13 stdlib", "Python", 27676974, 27679103, 17641471, 17643600], ["github/Scala", "playframework/playframework", "Scala", 511695433, 511697144, 17643602, 17645313], ["tinystories/en", "TinyStories-valid", "en", 19096322, 19097168, 17645328, 17646174], ["github/PHP", "laravel/framework", "PHP", 466363458, 466366874, 17646189, 17649605], ["tinystories/en", "TinyStories-valid", "en", 19257672, 19258156, 17649620, 17650104], ["github/Ruby", "rails/rails", "Ruby", 460815921, 460824452, 17650119, 17658650], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 311001757, 311012559, 17658665, 17669467], ["tinystories/en", "TinyStories-valid", "en", 291281, 291850, 17669482, 17670051], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485689033, 485691651, 17670066, 17672684], ["tinystories/en", "TinyStories-valid", "en", 16141234, 16141787, 17672699, 17673252], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515383401, 515386394, 17673267, 17676260], ["tinystories/en", "TinyStories-valid", "en", 9712256, 9713129, 17676275, 17677148], ["github/TypeScript", "angular/angular", "TypeScript", 329435376, 329454219, 17677163, 17696006], ["tinystories/en", "TinyStories-valid", "en", 6944826, 6945412, 17696021, 17696607], ["github/Java", "spring-projects/spring-framework", "Java", 424562454, 424579742, 17696622, 17713910], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491788659, 491789032, 17713925, 17714298], ["github/C", "curl/curl", "C", 373315769, 373337574, 17714313, 17736118], ["tinystories/en", "TinyStories-valid", "en", 5930379, 5931889, 17736133, 17737643], ["books/en", "PG #355", "en", 179154692, 179249711, 17737658, 17832677], ["tinystories/en", "TinyStories-valid", "en", 19013622, 19014331, 17832679, 17833388], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481647383, 481650880, 17833403, 17836900], ["tinystories/en", "TinyStories-valid", "en", 15097103, 15097707, 17836915, 17837519], ["tinystories/en", "TinyStories-valid", "en", 4029381, 4030194, 17837534, 17838347], ["github/JavaScript", "webpack/webpack", "JavaScript", 300537286, 300537453, 17838362, 17838529], ["github/JavaScript", "axios/axios", "JavaScript", 308795599, 308796072, 17838544, 17839017], ["tinystories/en", "TinyStories-valid", "en", 11267563, 11268375, 17839032, 17839844], ["github/Python", "django/django", "Python", 290624763, 290644881, 17839859, 17859977], ["tinystories/en", "TinyStories-valid", "en", 6790186, 6790766, 17859992, 17860572], ["tinystories/en", "TinyStories-valid", "en", 1930599, 1931058, 17860587, 17861046], ["tinystories/en", "TinyStories-valid", "en", 6686515, 6687289, 17861061, 17861835], ["github/Ruby", "rails/rails", "Ruby", 457069070, 457069648, 17861850, 17862428], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 310667115, 310671658, 17862443, 17866986], ["tinystories/en", "TinyStories-valid", "en", 11481842, 11482598, 17867001, 17867757], ["github/Java", "google/guava", "Java", 410037204, 410041158, 17867772, 17871726], ["books/fr", "PG #2419", "fr", 215922034, 216302493, 17871741, 18252200], ["tinystories/en", "TinyStories-valid", "en", 241051, 242775, 18252202, 18253926], ["github/TypeScript", "nestjs/nest", "TypeScript", 337779454, 337779579, 18253941, 18254066], ["github/Ruby", "rails/rails", "Ruby", 453021669, 453023868, 18254081, 18256280], ["tinystories/en", "TinyStories-valid", "en", 13170656, 13171357, 18256295, 18256996], ["github/C++", "opencv/opencv", "C++", 392738178, 392837487, 18257011, 18356320], ["github/Java", "spring-projects/spring-framework", "Java", 424162529, 424165809, 18356335, 18359615], ["github/TypeScript", "nestjs/nest", "TypeScript", 336014179, 336015825, 18359630, 18361276], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316128869, 316130897, 18361291, 18363319], ["tinystories/en", "TinyStories-valid", "en", 6530124, 6530612, 18363334, 18363822], ["github/C#", "dotnet/aspnetcore", "C#", 441407501, 441429775, 18363837, 18386111], ["tinystories/en", "TinyStories-valid", "en", 8886835, 8887937, 18386126, 18387228], ["github/TypeScript", "nestjs/nest", "TypeScript", 333099603, 333099790, 18387243, 18387430], ["github/TypeScript", "angular/angular", "TypeScript", 325093529, 325093862, 18387445, 18387778], ["tinystories/en", "TinyStories-valid", "en", 7584530, 7584881, 18387793, 18388144], ["github/TypeScript", "angular/angular", "TypeScript", 324976274, 324976927, 18388159, 18388812], ["github/Java", "spring-projects/spring-framework", "Java", 425038653, 425040636, 18388827, 18390810], ["tinystories/en", "TinyStories-valid", "en", 951809, 952450, 18390825, 18391466], ["github/Rust", "rust-lang/cargo", "Rust", 353440403, 353516752, 18391481, 18467830], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494471069, 494482695, 18467845, 18479471], ["github/Java", "spring-projects/spring-framework", "Java", 424912703, 424914969, 18479486, 18481752], ["tinystories/en", "TinyStories-valid", "en", 14097143, 14098828, 18481767, 18483452], ["github/TypeScript", "vuejs/core", "TypeScript", 320694810, 320698520, 18483467, 18487177], ["github/Java", "google/guava", "Java", 409983903, 409983998, 18487192, 18487287], ["github/Ruby", "rails/rails", "Ruby", 460696117, 460699121, 18487302, 18490306], ["tinystories/en", "TinyStories-valid", "en", 1385381, 1386045, 18490321, 18490985], ["tinystories/en", "TinyStories-valid", "en", 4302058, 4302700, 18491000, 18491642], ["github/Python", "scikit-learn/scikit-learn", "Python", 296435259, 296435635, 18491657, 18492033], ["tinystories/en", "TinyStories-valid", "en", 18131833, 18132526, 18492048, 18492741], ["github/TypeScript", "angular/angular", "TypeScript", 326461384, 326462991, 18492756, 18494363], ["tinystories/en", "TinyStories-valid", "en", 10325411, 10326345, 18494378, 18495312], ["github/PHP", "laravel/framework", "PHP", 464732519, 464768391, 18495327, 18531199], ["tinystories/en", "TinyStories-valid", "en", 10092987, 10093759, 18531214, 18531986], ["tinystories/en", "TinyStories-valid", "en", 6515491, 6516299, 18532001, 18532809], ["github/Go", "prometheus/prometheus", "Go", 359588653, 359596985, 18532824, 18541156], ["github/TypeScript", "angular/angular", "TypeScript", 326284543, 326288246, 18541171, 18544874], ["tinystories/en", "TinyStories-valid", "en", 3718057, 3718918, 18544889, 18545750], ["github/Python", "django/django", "Python", 288143205, 288150691, 18545765, 18553251], ["tinystories/en", "TinyStories-valid", "en", 4252484, 4253107, 18553266, 18553889], ["tinystories/en", "TinyStories-valid", "en", 13985764, 13986824, 18553904, 18554964], ["github/Java", "google/guava", "Java", 415435931, 415457882, 18554979, 18576930], ["tinystories/en", "TinyStories-valid", "en", 604119, 605205, 18576945, 18578031], ["github/C", "libuv/libuv", "C", 381362120, 381368319, 18578046, 18584245], ["tinystories/en", "TinyStories-valid", "en", 2753676, 2754622, 18584260, 18585206], ["github/TypeScript", "nestjs/nest", "TypeScript", 332342460, 332348082, 18585221, 18590843], ["tinystories/en", "TinyStories-valid", "en", 15580443, 15581272, 18590858, 18591687], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 487257272, 487263115, 18591702, 18597545], ["tinystories/en", "TinyStories-valid", "en", 7055120, 7056174, 18597560, 18598614], ["tinystories/en", "TinyStories-valid", "en", 4891305, 4892180, 18598629, 18599504], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449787657, 449789011, 18599519, 18600873], ["tinystories/en", "TinyStories-valid", "en", 15924001, 15924834, 18600888, 18601721], ["github/Go", "gohugoio/hugo", "Go", 367121226, 367126680, 18601736, 18607190], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515518910, 515519396, 18607205, 18607691], ["tinystories/en", "TinyStories-valid", "en", 18022767, 18024309, 18607706, 18609248], ["github/C", "curl/curl", "C", 380070255, 380072717, 18609263, 18611725], ["github/C#", "dotnet/aspnetcore", "C#", 438723635, 438726247, 18611740, 18614352], ["github/Python", "scikit-learn/scikit-learn", "Python", 292132853, 292141951, 18614367, 18623465], ["tinystories/en", "TinyStories-valid", "en", 11080320, 11081242, 18623480, 18624402], ["github/TypeScript", "nestjs/nest", "TypeScript", 336491025, 336497777, 18624417, 18631169], ["github/Kotlin", "ktorio/ktor", "Kotlin", 488577110, 488579766, 18631184, 18633840], ["tinystories/en", "TinyStories-valid", "en", 10124925, 10125764, 18633855, 18634694], ["tinystories/en", "TinyStories-valid", "en", 6069498, 6070284, 18634709, 18635495], ["github/Go", "gohugoio/hugo", "Go", 367608775, 367610409, 18635510, 18637144], ["tinystories/en", "TinyStories-valid", "en", 13551611, 13552404, 18637159, 18637952], ["github/C#", "dotnet/aspnetcore", "C#", 438744111, 438746121, 18637967, 18639977], ["github/Java", "spring-projects/spring-framework", "Java", 420432697, 420441627, 18639992, 18648922], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494482710, 494483188, 18648937, 18649415], ["github/Swift", "Alamofire/Alamofire", "Swift", 496683359, 496691609, 18649430, 18657680], ["tinystories/en", "TinyStories-valid", "en", 3934012, 3934694, 18657695, 18658377], ["github/Ruby", "jekyll/jekyll", "Ruby", 462076907, 462091976, 18658392, 18673461], ["github/Go", "gin-gonic/gin", "Go", 356928303, 356929123, 18673476, 18674296], ["tinystories/en", "TinyStories-valid", "en", 13782551, 13783525, 18674311, 18675285], ["tinystories/en", "TinyStories-valid", "en", 7096984, 7098081, 18675300, 18676397], ["github/TypeScript", "angular/angular", "TypeScript", 325785428, 325788662, 18676412, 18679646], ["github/Python", "scikit-learn/scikit-learn", "Python", 290982431, 290984536, 18679661, 18681766], ["tinystories/en", "TinyStories-valid", "en", 11490514, 11491152, 18681781, 18682419], ["github/Java", "spring-projects/spring-framework", "Java", 422722585, 422723309, 18682434, 18683158], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485488416, 485493342, 18683173, 18688099], ["tinystories/en", "TinyStories-valid", "en", 11979471, 11980253, 18688114, 18688896], ["github/Java", "square/okhttp", "Java", 429280455, 429282457, 18688911, 18690913], ["github/PHP", "symfony/symfony", "PHP", 473925954, 473926737, 18690928, 18691711], ["tinystories/en", "TinyStories-valid", "en", 19012853, 19013607, 18691726, 18692480], ["github/C", "libuv/libuv", "C", 383375437, 383383740, 18692495, 18700798], ["github/PHP", "symfony/symfony", "PHP", 476213658, 476214268, 18700813, 18701423], ["github/Java", "spring-projects/spring-framework", "Java", 418080516, 418081913, 18701438, 18702835], ["tinystories/en", "TinyStories-valid", "en", 12113427, 12114309, 18702850, 18703732], ["github/TypeScript", "angular/angular", "TypeScript", 326646145, 326649686, 18703747, 18707288], ["github/Python", "scikit-learn/scikit-learn", "Python", 295645917, 295650586, 18707303, 18711972], ["tinystories/en", "TinyStories-valid", "en", 3258768, 3259542, 18711987, 18712761], ["github/JavaScript", "webpack/webpack", "JavaScript", 308407231, 308458908, 18712776, 18764453], ["github/PHP", "symfony/symfony", "PHP", 473265547, 473267514, 18764468, 18766435], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489111245, 489111814, 18766450, 18767019], ["github/Java", "apache/commons-lang", "Java", 433433515, 433437740, 18767034, 18771259], ["github/C#", "dotnet/aspnetcore", "C#", 444389349, 444399270, 18771274, 18781195], ["github/TypeScript", "nestjs/nest", "TypeScript", 337803643, 337803860, 18781210, 18781427], ["tinystories/en", "TinyStories-valid", "en", 10628237, 10630333, 18781442, 18783538], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 482064114, 482064821, 18783553, 18784260], ["github/TypeScript", "nestjs/nest", "TypeScript", 337503360, 337506158, 18784275, 18787073], ["github/PHP", "symfony/symfony", "PHP", 477248695, 477251453, 18787088, 18789846], ["tinystories/en", "TinyStories-valid", "en", 13881269, 13882063, 18789861, 18790655], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486475418, 486477545, 18790670, 18792797], ["tinystories/en", "TinyStories-valid", "en", 1552503, 1553096, 18792812, 18793405], ["github/Go", "gohugoio/hugo", "Go", 369973418, 369989095, 18793420, 18809097], ["github/Java", "spring-projects/spring-framework", "Java", 422723324, 422729172, 18809112, 18814960], ["tinystories/en", "TinyStories-valid", "en", 12189016, 12190068, 18814975, 18816027], ["github/C", "curl/curl", "C", 372591457, 372591924, 18816042, 18816509], ["tinystories/en", "TinyStories-valid", "en", 11054247, 11055110, 18816524, 18817387], ["github/PHP", "symfony/symfony", "PHP", 472167699, 472171496, 18817402, 18821199], ["tinystories/en", "TinyStories-valid", "en", 16889685, 16890412, 18821214, 18821941], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 483569776, 483571943, 18821956, 18824123], ["github/Java", "square/okhttp", "Java", 427418256, 427419747, 18824138, 18825629], ["tinystories/en", "TinyStories-valid", "en", 12052315, 12052852, 18825644, 18826181], ["tinystories/en", "TinyStories-valid", "en", 9001787, 9002303, 18826196, 18826712], ["tinystories/en", "TinyStories-valid", "en", 286339, 287021, 18826727, 18827409], ["github/TypeScript", "angular/angular", "TypeScript", 327040347, 327048951, 18827424, 18836028], ["github/Scala", "playframework/playframework", "Scala", 508777006, 508883453, 18836043, 18942490], ["books/en", "PG #202", "en", 131627463, 132393959, 18942505, 19709001], ["tinystories/en", "TinyStories-valid", "en", 10582317, 10583169, 19709003, 19709855], ["github/C#", "dotnet/aspnetcore", "C#", 440778330, 440780641, 19709870, 19712181], ["tinystories/en", "TinyStories-valid", "en", 19436675, 19437340, 19712196, 19712861], ["github/Java", "apache/commons-lang", "Java", 435668372, 435675547, 19712876, 19720051], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486505349, 486508919, 19720066, 19723636], ["tinystories/en", "TinyStories-valid", "en", 6625282, 6625818, 19723651, 19724187], ["tinystories/en", "TinyStories-valid", "en", 7493668, 7494552, 19724202, 19725086], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449970961, 449972518, 19725101, 19726658], ["tinystories/en", "TinyStories-valid", "en", 3255441, 3256396, 19726673, 19727628], ["github/PHP", "symfony/symfony", "PHP", 471299152, 471306913, 19727643, 19735404], ["tinystories/en", "TinyStories-valid", "en", 9283697, 9284372, 19735419, 19736094], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491050909, 491051425, 19736109, 19736625], ["github/TypeScript", "angular/angular", "TypeScript", 324778763, 324780135, 19736640, 19738012], ["tinystories/en", "TinyStories-valid", "en", 11266170, 11266955, 19738027, 19738812], ["github/Java", "spring-projects/spring-framework", "Java", 424558264, 424562439, 19738827, 19743002], ["github/TypeScript", "nestjs/nest", "TypeScript", 334249478, 334249711, 19743017, 19743250], ["tinystories/en", "TinyStories-valid", "en", 14891971, 14893611, 19743265, 19744905], ["github/C++", "opencv/opencv", "C++", 395862859, 395871855, 19744920, 19753916], ["github/TypeScript", "nestjs/nest", "TypeScript", 334926156, 334928664, 19753931, 19756439], ["tinystories/en", "TinyStories-valid", "en", 10060242, 10060881, 19756454, 19757093], ["tinystories/en", "TinyStories-valid", "en", 11140712, 11141657, 19757108, 19758053], ["github/TypeScript", "angular/angular", "TypeScript", 326967886, 326968208, 19758068, 19758390], ["github/PHP", "laravel/framework", "PHP", 468908594, 468909376, 19758405, 19759187], ["github/TypeScript", "vuejs/core", "TypeScript", 319505155, 319505344, 19759202, 19759391], ["github/PHP", "laravel/framework", "PHP", 466616272, 466616752, 19759406, 19759886], ["tinystories/en", "TinyStories-valid", "en", 17458938, 17459625, 19759901, 19760588], ["tinystories/en", "TinyStories-valid", "en", 7678148, 7679073, 19760603, 19761528], ["stdlib/python", "python3.13 stdlib", "Python", 27295138, 27330401, 19761543, 19796806], ["github/Python", "scikit-learn/scikit-learn", "Python", 297903160, 297933372, 19796808, 19827020], ["github/PHP", "symfony/symfony", "PHP", 471759880, 471762254, 19827035, 19829409], ["tinystories/en", "TinyStories-valid", "en", 15351008, 15351966, 19829424, 19830382], ["tinystories/en", "TinyStories-valid", "en", 12108503, 12109175, 19830397, 19831069], ["github/Go", "prometheus/prometheus", "Go", 362503502, 362514695, 19831084, 19842277], ["tinystories/en", "TinyStories-valid", "en", 13380381, 13381046, 19842292, 19842957], ["github/TypeScript", "nestjs/nest", "TypeScript", 336550656, 336558876, 19842972, 19851192], ["github/PHP", "symfony/symfony", "PHP", 478428397, 478430516, 19851207, 19853326], ["tinystories/en", "TinyStories-valid", "en", 7036436, 7037294, 19853341, 19854199], ["github/C#", "dotnet/aspnetcore", "C#", 438469960, 438485559, 19854214, 19869813], ["tinystories/en", "TinyStories-valid", "en", 13553934, 13555102, 19869828, 19870996], ["github/PHP", "symfony/symfony", "PHP", 476074748, 476075598, 19871011, 19871861], ["github/Rust", "rust-lang/cargo", "Rust", 351628849, 351644851, 19871876, 19887878], ["tinystories/en", "TinyStories-valid", "en", 6978025, 6978989, 19887893, 19888857], ["github/PHP", "symfony/symfony", "PHP", 474524350, 474525839, 19888872, 19890361], ["github/Kotlin", "ktorio/ktor", "Kotlin", 488853266, 488870021, 19890376, 19907131], ["tinystories/en", "TinyStories-valid", "en", 3903709, 3904261, 19907146, 19907698], ["github/Ruby", "rails/rails", "Ruby", 454699024, 454714516, 19907713, 19923205], ["tinystories/en", "TinyStories-valid", "en", 18267982, 18268715, 19923220, 19923953], ["github/PHP", "laravel/framework", "PHP", 468770154, 468771906, 19923968, 19925720], ["tinystories/en", "TinyStories-valid", "en", 12923364, 12924189, 19925735, 19926560], ["tinystories/en", "TinyStories-valid", "en", 6729592, 6730250, 19926575, 19927233], ["github/C++", "opencv/opencv", "C++", 395595931, 395615276, 19927248, 19946593], ["github/PHP", "laravel/framework", "PHP", 467450530, 467451348, 19946608, 19947426], ["tinystories/en", "TinyStories-valid", "en", 4263842, 4264784, 19947441, 19948383], ["github/Go", "gohugoio/hugo", "Go", 370189344, 370190368, 19948398, 19949422], ["tinystories/en", "TinyStories-valid", "en", 9030601, 9031507, 19949437, 19950343], ["github/Go", "gohugoio/hugo", "Go", 366982183, 366982918, 19950358, 19951093], ["tinystories/en", "TinyStories-valid", "en", 8363627, 8364198, 19951108, 19951679], ["tinystories/en", "TinyStories-valid", "en", 9489969, 9491216, 19951694, 19952941], ["github/Go", "prometheus/prometheus", "Go", 362271060, 362272817, 19952956, 19954713], ["tinystories/en", "TinyStories-valid", "en", 2069364, 2069933, 19954728, 19955297], ["github/PHP", "laravel/framework", "PHP", 468790891, 468798322, 19955312, 19962743], ["tinystories/en", "TinyStories-valid", "en", 13899709, 13900596, 19962758, 19963645], ["github/Go", "gin-gonic/gin", "Go", 356511863, 356512540, 19963660, 19964337], ["github/TypeScript", "nestjs/nest", "TypeScript", 337261341, 337275581, 19964352, 19978592], ["github/Java", "spring-projects/spring-framework", "Java", 423752469, 423803531, 19978607, 20029669], ["tinystories/en", "TinyStories-valid", "en", 6857872, 6858492, 20029684, 20030304], ["tinystories/en", "TinyStories-valid", "en", 4521404, 4521953, 20030319, 20030868], ["github/Rust", "rust-lang/cargo", "Rust", 347491795, 347495068, 20030883, 20034156], ["github/C#", "dotnet/aspnetcore", "C#", 440939320, 440941088, 20034171, 20035939], ["tinystories/en", "TinyStories-valid", "en", 4847127, 4847840, 20035954, 20036667], ["tinystories/en", "TinyStories-valid", "en", 4267011, 4267946, 20036682, 20037617], ["github/C#", "dotnet/aspnetcore", "C#", 440617756, 440618247, 20037632, 20038123], ["tinystories/en", "TinyStories-valid", "en", 13903363, 13904174, 20038138, 20038949], ["tinystories/en", "TinyStories-valid", "en", 10683661, 10684266, 20038964, 20039569], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494986314, 494988486, 20039584, 20041756], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 447017523, 447019584, 20041771, 20043832], ["tinystories/en", "TinyStories-valid", "en", 3231451, 3232140, 20043847, 20044536], ["github/Python", "scikit-learn/scikit-learn", "Python", 290934581, 290940041, 20044551, 20050011], ["tinystories/en", "TinyStories-valid", "en", 3390171, 3391187, 20050026, 20051042], ["github/Rust", "rust-lang/cargo", "Rust", 350805020, 350811250, 20051057, 20057287], ["tinystories/en", "TinyStories-valid", "en", 8438037, 8438886, 20057302, 20058151], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449617058, 449618423, 20058166, 20059531], ["tinystories/en", "TinyStories-valid", "en", 6057888, 6058616, 20059546, 20060274], ["github/Ruby", "rails/rails", "Ruby", 456337651, 456337934, 20060289, 20060572], ["tinystories/en", "TinyStories-valid", "en", 13716341, 13717069, 20060587, 20061315], ["github/PHP", "symfony/symfony", "PHP", 475477493, 475487073, 20061330, 20070910], ["github/TypeScript", "nestjs/nest", "TypeScript", 337824216, 337827612, 20070925, 20074321], ["github/Python", "django/django", "Python", 283012613, 283013023, 20074336, 20074746], ["tinystories/en", "TinyStories-valid", "en", 9158156, 9158895, 20074761, 20075500], ["github/C++", "nlohmann/json", "C++", 386279768, 386295435, 20075515, 20091182], ["tinystories/en", "TinyStories-valid", "en", 10531003, 10531454, 20091197, 20091648], ["github/Rust", "serde-rs/serde", "Rust", 346401043, 346401438, 20091663, 20092058], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 484756718, 484762707, 20092073, 20098062], ["tinystories/en", "TinyStories-valid", "en", 8321276, 8321908, 20098077, 20098709], ["tinystories/en", "TinyStories-valid", "en", 1164280, 1165299, 20098724, 20099743], ["github/TypeScript", "angular/angular", "TypeScript", 329419994, 329422253, 20099758, 20102017], ["tinystories/en", "TinyStories-valid", "en", 13811237, 13812039, 20102032, 20102834], ["github/JavaScript", "webpack/webpack", "JavaScript", 305456799, 305488864, 20102849, 20134914], ["github/TypeScript", "vuejs/core", "TypeScript", 322282651, 322282840, 20134929, 20135118], ["tinystories/en", "TinyStories-valid", "en", 15279233, 15280569, 20135133, 20136469], ["github/Go", "gohugoio/hugo", "Go", 368024142, 368046001, 20136484, 20158343], ["github/Python", "scikit-learn/scikit-learn", "Python", 291666006, 291673991, 20158358, 20166343], ["github/TypeScript", "nestjs/nest", "TypeScript", 337023746, 337025557, 20166358, 20168169], ["github/PHP", "laravel/framework", "PHP", 463107604, 463108045, 20168184, 20168625], ["tinystories/en", "TinyStories-valid", "en", 282721, 283382, 20168640, 20169301], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 482925792, 482925861, 20169316, 20169385], ["tinystories/en", "TinyStories-valid", "en", 13015350, 13016571, 20169400, 20170621], ["github/TypeScript", "nestjs/nest", "TypeScript", 335018052, 335019552, 20170636, 20172136], ["github/Rust", "tokio-rs/tokio", "Rust", 340902455, 340912211, 20172151, 20181907], ["tinystories/en", "TinyStories-valid", "en", 6741567, 6742239, 20181922, 20182594], ["github/TypeScript", "angular/angular", "TypeScript", 326335035, 326336136, 20182609, 20183710], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486838483, 486842546, 20183725, 20187788], ["tinystories/en", "TinyStories-valid", "en", 9551946, 9552942, 20187803, 20188799], ["tinystories/en", "TinyStories-valid", "en", 3078479, 3079116, 20188814, 20189451], ["github/TypeScript", "nestjs/nest", "TypeScript", 335907456, 335909080, 20189466, 20191090], ["github/Python", "django/django", "Python", 283211553, 283212416, 20191105, 20191968], ["github/Java", "google/guava", "Java", 413201059, 413202610, 20191983, 20193534], ["tinystories/en", "TinyStories-valid", "en", 3833170, 3833954, 20193549, 20194333], ["github/C++", "opencv/opencv", "C++", 398599441, 398606889, 20194348, 20201796], ["tinystories/en", "TinyStories-valid", "en", 14709261, 14710166, 20201811, 20202716], ["tinystories/en", "TinyStories-valid", "en", 10386274, 10386949, 20202731, 20203406], ["github/Java", "square/okhttp", "Java", 426649312, 426653922, 20203421, 20208031], ["tinystories/en", "TinyStories-valid", "en", 10585670, 10586877, 20208046, 20209253], ["tinystories/en", "TinyStories-valid", "en", 2771524, 2772166, 20209268, 20209910], ["github/Ruby", "jekyll/jekyll", "Ruby", 461958245, 461971992, 20209925, 20223672], ["tinystories/en", "TinyStories-valid", "en", 13206014, 13206619, 20223687, 20224292], ["github/PHP", "laravel/framework", "PHP", 465498451, 465515141, 20224307, 20240997], ["tinystories/en", "TinyStories-valid", "en", 3261905, 3262563, 20241012, 20241670], ["github/Java", "apache/commons-lang", "Java", 433437755, 433441344, 20241685, 20245274], ["tinystories/en", "TinyStories-valid", "en", 9227802, 9228821, 20245289, 20246308], ["github/Rust", "tokio-rs/tokio", "Rust", 342630663, 342637631, 20246323, 20253291], ["github/Java", "spring-projects/spring-framework", "Java", 425175731, 425176989, 20253306, 20254564], ["tinystories/en", "TinyStories-valid", "en", 2164214, 2164913, 20254579, 20255278], ["github/Python", "scikit-learn/scikit-learn", "Python", 297309537, 297321795, 20255293, 20267551], ["tinystories/en", "TinyStories-valid", "en", 12868617, 12869519, 20267566, 20268468], ["github/Kotlin", "ktorio/ktor", "Kotlin", 493383644, 493393166, 20268483, 20278005], ["github/TypeScript", "nestjs/nest", "TypeScript", 336140007, 336155878, 20278020, 20293891], ["tinystories/en", "TinyStories-valid", "en", 9515968, 9516395, 20293906, 20294333], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 514928103, 514935979, 20294348, 20302224], ["tinystories/en", "TinyStories-valid", "en", 5637711, 5638429, 20302239, 20302957], ["github/C++", "opencv/opencv", "C++", 393022429, 393035848, 20302972, 20316391], ["tinystories/en", "TinyStories-valid", "en", 17382823, 17383434, 20316406, 20317017], ["tinystories/en", "TinyStories-valid", "en", 11349609, 11350352, 20317032, 20317775], ["github/Scala", "playframework/playframework", "Scala", 511035691, 511040561, 20317790, 20322660], ["github/Rust", "tokio-rs/tokio", "Rust", 341652301, 341654409, 20322675, 20324783], ["tinystories/en", "TinyStories-valid", "en", 13299725, 13300661, 20324798, 20325734], ["books/en", "PG #212", "en", 136110965, 136358069, 20325749, 20572853], ["tinystories/en", "TinyStories-valid", "en", 10377877, 10378789, 20572855, 20573767], ["github/Java", "google/guava", "Java", 417041520, 417057257, 20573782, 20589519], ["github/JavaScript", "webpack/webpack", "JavaScript", 302750795, 302753307, 20589534, 20592046], ["github/Scala", "sbt/sbt", "Scala", 519755741, 519755776, 20592061, 20592096], ["tinystories/en", "TinyStories-valid", "en", 4519439, 4520353, 20592111, 20593025], ["github/Rust", "tokio-rs/tokio", "Rust", 340334247, 340336327, 20593040, 20595120], ["github/Scala", "sbt/sbt", "Scala", 520283193, 520284678, 20595135, 20596620], ["github/Python", "pallets/flask", "Python", 281796315, 281796744, 20596635, 20597064], ["github/PHP", "laravel/framework", "PHP", 468371059, 468372184, 20597079, 20598204], ["tinystories/en", "TinyStories-valid", "en", 5424359, 5425228, 20598219, 20599088], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491540217, 491541133, 20599103, 20600019], ["github/Python", "django/django", "Python", 288332505, 288333726, 20600034, 20601255], ["github/Scala", "sbt/sbt", "Scala", 516096342, 516098573, 20601270, 20603501], ["tinystories/en", "TinyStories-valid", "en", 14188186, 14190466, 20603516, 20605796], ["github/PHP", "laravel/framework", "PHP", 464378746, 464382049, 20605811, 20609114], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 317507848, 317512412, 20609129, 20613693], ["github/TypeScript", "vuejs/core", "TypeScript", 320812663, 320814425, 20613708, 20615470], ["tinystories/en", "TinyStories-valid", "en", 17374475, 17375063, 20615485, 20616073], ["github/Rust", "BurntSushi/ripgrep", "Rust", 338417081, 338422822, 20616088, 20621829], ["tinystories/en", "TinyStories-valid", "en", 11229542, 11229877, 20621844, 20622179], ["tinystories/en", "TinyStories-valid", "en", 10065255, 10065889, 20622194, 20622828], ["github/PHP", "laravel/framework", "PHP", 466652353, 466652484, 20622843, 20622974], ["github/TypeScript", "angular/angular", "TypeScript", 329356726, 329358198, 20622989, 20624461], ["tinystories/en", "TinyStories-valid", "en", 10221917, 10222541, 20624476, 20625100], ["github/Python", "scikit-learn/scikit-learn", "Python", 292220210, 292226434, 20625115, 20631339], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490164141, 490169548, 20631354, 20636761], ["github/C++", "protocolbuffers/protobuf", "C++", 407721051, 407731872, 20636776, 20647597], ["github/PHP", "symfony/symfony", "PHP", 475834454, 475836182, 20647612, 20649340], ["tinystories/en", "TinyStories-valid", "en", 1372989, 1374031, 20649355, 20650397], ["github/Java", "spring-projects/spring-framework", "Java", 419440937, 419446138, 20650412, 20655613], ["books/fr", "PG #10160", "fr", 270015852, 270360282, 20655628, 21000058], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316348380, 316351587, 21000060, 21003267], ["tinystories/en", "TinyStories-valid", "en", 12879367, 12880528, 21003282, 21004443], ["github/TypeScript", "angular/angular", "TypeScript", 326352900, 326357786, 21004458, 21009344], ["tinystories/en", "TinyStories-valid", "en", 10419319, 10420264, 21009359, 21010304], ["github/JavaScript", "webpack/webpack", "JavaScript", 300480700, 300480775, 21010319, 21010394], ["github/Rust", "tokio-rs/tokio", "Rust", 345528983, 345532617, 21010409, 21014043], ["tinystories/en", "TinyStories-valid", "en", 12136498, 12137535, 21014058, 21015095], ["github/JavaScript", "webpack/webpack", "JavaScript", 303314848, 303315629, 21015110, 21015891], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 484125214, 484126105, 21015906, 21016797], ["github/Java", "spring-projects/spring-framework", "Java", 421026416, 421031048, 21016812, 21021444], ["github/PHP", "laravel/framework", "PHP", 466739680, 466746051, 21021459, 21027830], ["github/Ruby", "rails/rails", "Ruby", 454243878, 454249382, 21027845, 21033349], ["tinystories/en", "TinyStories-valid", "en", 14671555, 14672276, 21033364, 21034085], ["github/Python", "django/django", "Python", 287465403, 287468282, 21034100, 21036979], ["github/TypeScript", "nestjs/nest", "TypeScript", 337474325, 337474428, 21036994, 21037097], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 311268309, 311270453, 21037112, 21039256], ["tinystories/en", "TinyStories-valid", "en", 9675756, 9676990, 21039271, 21040505], ["github/Java", "spring-projects/spring-framework", "Java", 418131026, 418132190, 21040520, 21041684], ["github/TypeScript", "angular/angular", "TypeScript", 324469249, 324471721, 21041699, 21044171], ["tinystories/en", "TinyStories-valid", "en", 11551517, 11552109, 21044186, 21044778], ["github/Python", "django/django", "Python", 285289661, 285290861, 21044793, 21045993], ["github/JavaScript", "expressjs/express", "JavaScript", 299554651, 299555654, 21046008, 21047011], ["tinystories/en", "TinyStories-valid", "en", 3140306, 3140869, 21047026, 21047589], ["github/Java", "apache/commons-lang", "Java", 435914517, 435916903, 21047604, 21049990], ["github/TypeScript", "nestjs/nest", "TypeScript", 334198313, 334198396, 21050005, 21050088], ["github/JavaScript", "axios/axios", "JavaScript", 308755135, 308755408, 21050103, 21050376], ["github/TypeScript", "nestjs/nest", "TypeScript", 333736544, 333736676, 21050391, 21050523], ["tinystories/en", "TinyStories-valid", "en", 10421915, 10422514, 21050538, 21051137], ["github/TypeScript", "nestjs/nest", "TypeScript", 334256352, 334256678, 21051152, 21051478], ["github/PHP", "symfony/symfony", "PHP", 475938257, 475939204, 21051493, 21052440], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489181344, 489187242, 21052455, 21058353], ["tinystories/en", "TinyStories-valid", "en", 7063315, 7064232, 21058368, 21059285], ["github/Rust", "tokio-rs/tokio", "Rust", 341569040, 341575095, 21059300, 21065355], ["github/PHP", "laravel/framework", "PHP", 467983197, 467983690, 21065370, 21065863], ["github/TypeScript", "angular/angular", "TypeScript", 324958674, 324960862, 21065878, 21068066], ["github/Java", "square/okhttp", "Java", 426305916, 426309190, 21068081, 21071355], ["github/PHP", "laravel/framework", "PHP", 467004629, 467004815, 21071370, 21071556], ["github/PHP", "symfony/symfony", "PHP", 474787244, 474787735, 21071571, 21072062], ["tinystories/en", "TinyStories-valid", "en", 10779410, 10781134, 21072077, 21073801], ["github/PHP", "laravel/framework", "PHP", 465175029, 465177480, 21073816, 21076267], ["github/TypeScript", "angular/angular", "TypeScript", 328331604, 328333532, 21076282, 21078210], ["tinystories/en", "TinyStories-valid", "en", 12983129, 12984166, 21078225, 21079262], ["github/Java", "square/okhttp", "Java", 426595481, 426599895, 21079277, 21083691], ["github/Scala", "scala/scala", "Scala", 501606131, 501636834, 21083706, 21114409], ["github/Rust", "rust-lang/cargo", "Rust", 352963795, 352964177, 21114424, 21114806], ["tinystories/en", "TinyStories-valid", "en", 3692639, 3693285, 21114821, 21115467], ["github/TypeScript", "nestjs/nest", "TypeScript", 332424841, 332426055, 21115482, 21116696], ["github/Ruby", "jekyll/jekyll", "Ruby", 461588693, 461591578, 21116711, 21119596], ["tinystories/en", "TinyStories-valid", "en", 19406163, 19406875, 21119611, 21120323], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487662470, 487663215, 21120338, 21121083], ["github/Python", "django/django", "Python", 289620031, 289630525, 21121098, 21131592], ["github/PHP", "symfony/symfony", "PHP", 471217620, 471219639, 21131607, 21133626], ["github/TypeScript", "angular/angular", "TypeScript", 326583480, 326584366, 21133641, 21134527], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489550891, 489551649, 21134542, 21135300], ["github/Java", "apache/commons-lang", "Java", 435635150, 435636431, 21135315, 21136596], ["tinystories/en", "TinyStories-valid", "en", 1300194, 1301687, 21136611, 21138104], ["github/C++", "opencv/opencv", "C++", 393641310, 393666369, 21138119, 21163178], ["github/Java", "spring-projects/spring-framework", "Java", 424366196, 424368050, 21163193, 21165047], ["tinystories/en", "TinyStories-valid", "en", 18294671, 18295324, 21165062, 21165715], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486353863, 486355594, 21165730, 21167461], ["tinystories/en", "TinyStories-valid", "en", 12336931, 12337591, 21167476, 21168136], ["tinystories/en", "TinyStories-valid", "en", 17488329, 17489366, 21168151, 21169188], ["github/TypeScript", "vuejs/core", "TypeScript", 323431321, 323437381, 21169203, 21175263], ["tinystories/en", "TinyStories-valid", "en", 16855645, 16856220, 21175278, 21175853], ["tinystories/en", "TinyStories-valid", "en", 5327394, 5328236, 21175868, 21176710], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316457821, 316477681, 21176725, 21196585], ["tinystories/en", "TinyStories-valid", "en", 4405955, 4406690, 21196600, 21197335], ["github/Ruby", "rails/rails", "Ruby", 456478843, 456482388, 21197350, 21200895], ["github/Python", "django/django", "Python", 290553603, 290554533, 21200910, 21201840], ["github/PHP", "symfony/symfony", "PHP", 471567375, 471576460, 21201855, 21210940], ["tinystories/en", "TinyStories-valid", "en", 16871934, 16872359, 21210955, 21211380], ["tinystories/en", "TinyStories-valid", "en", 17001895, 17002578, 21211395, 21212078], ["github/Java", "google/guava", "Java", 414064003, 414077473, 21212093, 21225563], ["github/Python", "django/django", "Python", 284636687, 284637547, 21225578, 21226438], ["tinystories/en", "TinyStories-valid", "en", 5146553, 5147305, 21226453, 21227205], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485071721, 485078501, 21227220, 21234000], ["github/TypeScript", "angular/angular", "TypeScript", 326000411, 326002996, 21234015, 21236600], ["tinystories/en", "TinyStories-valid", "en", 9301167, 9301847, 21236615, 21237295], ["tinystories/en", "TinyStories-valid", "en", 6881189, 6881731, 21237310, 21237852], ["github/TypeScript", "angular/angular", "TypeScript", 325074886, 325075087, 21237867, 21238068], ["tinystories/en", "TinyStories-valid", "en", 16402094, 16402853, 21238083, 21238842], ["github/TypeScript", "angular/angular", "TypeScript", 327423874, 327425212, 21238857, 21240195], ["tinystories/en", "TinyStories-valid", "en", 9499161, 9501674, 21240210, 21242723], ["books/en", "PG #393", "en", 191226331, 191587086, 21242738, 21603493], ["github/Python", "scikit-learn/scikit-learn", "Python", 291502617, 291511548, 21603495, 21612426], ["github/TypeScript", "angular/angular", "TypeScript", 327444848, 327447964, 21612441, 21615557], ["tinystories/en", "TinyStories-valid", "en", 15806457, 15807061, 21615572, 21616176], ["github/Ruby", "rails/rails", "Ruby", 453665221, 453668788, 21616191, 21619758], ["github/Scala", "sbt/sbt", "Scala", 519829011, 519829036, 21619773, 21619798], ["tinystories/en", "TinyStories-valid", "en", 2456306, 2457123, 21619813, 21620630], ["github/Scala", "playframework/playframework", "Scala", 511831052, 511832176, 21620645, 21621769], ["github/Java", "google/guava", "Java", 412186965, 412193514, 21621784, 21628333], ["tinystories/en", "TinyStories-valid", "en", 14032009, 14032912, 21628348, 21629251], ["github/Scala", "playframework/playframework", "Scala", 511893505, 511894435, 21629266, 21630196], ["github/Kotlin", "ktorio/ktor", "Kotlin", 488201884, 488205533, 21630211, 21633860], ["github/TypeScript", "nestjs/nest", "TypeScript", 336958408, 336960307, 21633875, 21635774], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 448992646, 449081677, 21635789, 21724820], ["tinystories/en", "TinyStories-valid", "en", 12478882, 12479586, 21724835, 21725539], ["github/JavaScript", "axios/axios", "JavaScript", 309068058, 309068384, 21725554, 21725880], ["tinystories/en", "TinyStories-valid", "en", 17366416, 17367046, 21725895, 21726525], ["github/Java", "apache/commons-lang", "Java", 435497747, 435499080, 21726540, 21727873], ["stdlib/python", "python3.13 stdlib", "Python", 26007738, 26021895, 21727888, 21742045], ["tinystories/en", "TinyStories-valid", "en", 5057055, 5057733, 21742047, 21742725], ["tinystories/en", "TinyStories-valid", "en", 8385073, 8385638, 21742740, 21743305], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487662139, 487662455, 21743320, 21743636], ["github/Python", "django/django", "Python", 285871012, 285872126, 21743651, 21744765], ["github/Java", "spring-projects/spring-framework", "Java", 425013036, 425015168, 21744780, 21746912], ["tinystories/en", "TinyStories-valid", "en", 4357947, 4359106, 21746927, 21748086], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491372133, 491373663, 21748101, 21749631], ["github/Swift", "Alamofire/Alamofire", "Swift", 496090872, 496114059, 21749646, 21772833], ["github/Python", "django/django", "Python", 282373985, 282375340, 21772848, 21774203], ["github/Ruby", "rails/rails", "Ruby", 460910667, 460913074, 21774218, 21776625], ["tinystories/en", "TinyStories-valid", "en", 16780719, 16781436, 21776640, 21777357], ["tinystories/en", "TinyStories-valid", "en", 1512088, 1512839, 21777372, 21778123], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481655619, 481656718, 21778138, 21779237], ["github/Java", "spring-projects/spring-framework", "Java", 419050437, 419057075, 21779252, 21785890], ["github/TypeScript", "microsoft/vscode", "TypeScript", 318827399, 318837162, 21785905, 21795668], ["tinystories/en", "TinyStories-valid", "en", 2364503, 2365326, 21795683, 21796506], ["github/Python", "django/django", "Python", 290517895, 290520293, 21796521, 21798919], ["github/Scala", "playframework/playframework", "Scala", 510134259, 510147257, 21798934, 21811932], ["tinystories/en", "TinyStories-valid", "en", 11348990, 11349594, 21811947, 21812551], ["tinystories/en", "TinyStories-valid", "en", 13948901, 13949632, 21812566, 21813297], ["github/PHP", "laravel/framework", "PHP", 466235413, 466258023, 21813312, 21835922], ["tinystories/en", "TinyStories-valid", "en", 5432506, 5433360, 21835937, 21836791], ["github/Java", "google/guava", "Java", 415933993, 415934676, 21836806, 21837489], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492357501, 492360878, 21837504, 21840881], ["tinystories/en", "TinyStories-valid", "en", 11238154, 11238741, 21840896, 21841483], ["github/Ruby", "rails/rails", "Ruby", 454937126, 454939517, 21841498, 21843889], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 314210607, 314225463, 21843904, 21858760], ["tinystories/en", "TinyStories-valid", "en", 3086319, 3087276, 21858775, 21859732], ["github/Java", "google/guava", "Java", 417156680, 417161289, 21859747, 21864356], ["github/Python", "scikit-learn/scikit-learn", "Python", 291927871, 291933756, 21864371, 21870256], ["github/TypeScript", "microsoft/vscode", "TypeScript", 319144985, 319145019, 21870271, 21870305], ["github/TypeScript", "angular/angular", "TypeScript", 324976095, 324976259, 21870320, 21870484], ["tinystories/en", "TinyStories-valid", "en", 16694903, 16696393, 21870499, 21871989], ["tinystories/en", "TinyStories-valid", "en", 1647569, 1648600, 21872004, 21873035], ["github/Java", "spring-projects/spring-framework", "Java", 420377624, 420380816, 21873050, 21876242], ["tinystories/en", "TinyStories-valid", "en", 4579597, 4580883, 21876257, 21877543], ["github/Scala", "sbt/sbt", "Scala", 519628244, 519630228, 21877558, 21879542], ["github/Rust", "rust-lang/cargo", "Rust", 354697344, 354752589, 21879557, 21934802], ["github/Ruby", "sinatra/sinatra", "Ruby", 462711604, 462713876, 21934817, 21937089], ["github/Java", "spring-projects/spring-framework", "Java", 419699543, 419700492, 21937104, 21938053], ["github/Scala", "sbt/sbt", "Scala", 519813129, 519813148, 21938068, 21938087], ["tinystories/en", "TinyStories-valid", "en", 920991, 921841, 21938102, 21938952], ["github/Python", "django/django", "Python", 283616147, 283617658, 21938967, 21940478], ["github/Scala", "playframework/playframework", "Scala", 508494643, 508495656, 21940493, 21941506], ["tinystories/en", "TinyStories-valid", "en", 4481015, 4481959, 21941521, 21942465], ["github/Scala", "sbt/sbt", "Scala", 516354618, 516354861, 21942480, 21942723], ["github/Python", "scikit-learn/scikit-learn", "Python", 290971977, 290972376, 21942738, 21943137], ["github/Java", "google/guava", "Java", 417123665, 417127124, 21943152, 21946611], ["github/Scala", "playframework/playframework", "Scala", 511133332, 511134014, 21946626, 21947308], ["github/Python", "scikit-learn/scikit-learn", "Python", 294103179, 294104703, 21947323, 21948847], ["tinystories/en", "TinyStories-valid", "en", 17536437, 17538465, 21948862, 21950890], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491141317, 491150535, 21950905, 21960123], ["github/Java", "spring-projects/spring-framework", "Java", 420933468, 420935041, 21960138, 21961711], ["github/Scala", "sbt/sbt", "Scala", 520658339, 520661200, 21961726, 21964587], ["github/Ruby", "rails/rails", "Ruby", 460322683, 460324397, 21964602, 21966316], ["github/Python", "django/django", "Python", 286957070, 286957842, 21966331, 21967103], ["tinystories/en", "TinyStories-valid", "en", 14249016, 14249650, 21967118, 21967752], ["tinystories/en", "TinyStories-valid", "en", 3651844, 3652470, 21967767, 21968393], ["github/Scala", "playframework/playframework", "Scala", 511827037, 511827484, 21968408, 21968855], ["tinystories/en", "TinyStories-valid", "en", 725280, 725982, 21968870, 21969572], ["github/Scala", "playframework/playframework", "Scala", 511845018, 511845430, 21969587, 21969999], ["github/Java", "spring-projects/spring-framework", "Java", 420250107, 420255838, 21970014, 21975745], ["tinystories/en", "TinyStories-valid", "en", 17654895, 17655804, 21975760, 21976669], ["github/Scala", "scala/scala", "Scala", 504938202, 504942359, 21976684, 21980841], ["tinystories/en", "TinyStories-valid", "en", 12655720, 12657615, 21980856, 21982751], ["github/Ruby", "rails/rails", "Ruby", 458954438, 458957276, 21982766, 21985604], ["tinystories/en", "TinyStories-valid", "en", 11398090, 11398858, 21985619, 21986387], ["github/PHP", "laravel/framework", "PHP", 465862576, 465868986, 21986402, 21992812], ["tinystories/en", "TinyStories-valid", "en", 15634597, 15635393, 21992827, 21993623], ["github/Scala", "scala/scala", "Scala", 498777702, 498778521, 21993638, 21994457], ["github/Scala", "sbt/sbt", "Scala", 519871357, 519871397, 21994472, 21994512], ["tinystories/en", "TinyStories-valid", "en", 18247035, 18247655, 21994527, 21995147], ["tinystories/en", "TinyStories-valid", "en", 7430095, 7430857, 21995162, 21995924], ["github/Java", "square/okhttp", "Java", 427844589, 427856509, 21995939, 22007859], ["github/TypeScript", "angular/angular", "TypeScript", 327902646, 327933950, 22007874, 22039178], ["tinystories/en", "TinyStories-valid", "en", 13763755, 13764965, 22039193, 22040403], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 311244221, 311262327, 22040418, 22058524], ["tinystories/en", "TinyStories-valid", "en", 3219557, 3220059, 22058539, 22059041], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486108988, 486115572, 22059056, 22065640], ["github/Scala", "playframework/playframework", "Scala", 508182662, 508188812, 22065655, 22071805], ["tinystories/en", "TinyStories-valid", "en", 11850736, 11851695, 22071820, 22072779], ["github/Ruby", "rails/rails", "Ruby", 459019239, 459022460, 22072794, 22076015], ["github/PHP", "laravel/framework", "PHP", 470880916, 470884955, 22076030, 22080069], ["tinystories/en", "TinyStories-valid", "en", 18416575, 18417243, 22080084, 22080752], ["github/Python", "scikit-learn/scikit-learn", "Python", 294082942, 294103164, 22080767, 22100989], ["tinystories/en", "TinyStories-valid", "en", 5682400, 5683138, 22101004, 22101742], ["tinystories/en", "TinyStories-valid", "en", 10937316, 10937894, 22101757, 22102335], ["github/Java", "square/okhttp", "Java", 428182872, 428183715, 22102350, 22103193], ["github/Scala", "scala/scala", "Scala", 505429090, 505430012, 22103208, 22104130], ["tinystories/en", "TinyStories-valid", "en", 90651, 91331, 22104145, 22104825], ["github/Java", "google/guava", "Java", 413470711, 413472015, 22104840, 22106144], ["github/PHP", "symfony/symfony", "PHP", 475943582, 475944489, 22106159, 22107066], ["tinystories/en", "TinyStories-valid", "en", 2503404, 2504089, 22107081, 22107766], ["github/Java", "spring-projects/spring-framework", "Java", 419587675, 419588608, 22107781, 22108714], ["tinystories/en", "TinyStories-valid", "en", 4483944, 4484613, 22108729, 22109398], ["tinystories/en", "TinyStories-valid", "en", 1546457, 1547149, 22109413, 22110105], ["github/Java", "google/guava", "Java", 414961954, 414966282, 22110120, 22114448], ["tinystories/en", "TinyStories-valid", "en", 479921, 480716, 22114463, 22115258], ["github/C++", "protocolbuffers/protobuf", "C++", 405356143, 405447354, 22115273, 22206484], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490435337, 490439225, 22206499, 22210387], ["github/PHP", "symfony/symfony", "PHP", 475949955, 475954489, 22210402, 22214936], ["tinystories/en", "TinyStories-valid", "en", 15965642, 15966210, 22214951, 22215519], ["tinystories/en", "TinyStories-valid", "en", 1447618, 1448495, 22215534, 22216411], ["github/Java", "spring-projects/spring-framework", "Java", 420238824, 420240611, 22216426, 22218213], ["tinystories/en", "TinyStories-valid", "en", 12919876, 12920731, 22218228, 22219083], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515342530, 515343589, 22219098, 22220157], ["github/JavaScript", "webpack/webpack", "JavaScript", 308524888, 308525852, 22220172, 22221136], ["github/Java", "google/guava", "Java", 410628787, 410630388, 22221151, 22222752], ["tinystories/en", "TinyStories-valid", "en", 10234366, 10235126, 22222767, 22223527], ["github/PHP", "symfony/symfony", "PHP", 472500951, 472502181, 22223542, 22224772], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487989246, 487990171, 22224787, 22225712], ["tinystories/en", "TinyStories-valid", "en", 6332197, 6332958, 22225727, 22226488], ["github/Java", "google/guava", "Java", 413644553, 413646688, 22226503, 22228638], ["github/PHP", "laravel/framework", "PHP", 464048291, 464048772, 22228653, 22229134], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494858557, 494858888, 22229149, 22229480], ["github/Scala", "scala/scala", "Scala", 506917148, 506932946, 22229495, 22245293], ["tinystories/en", "TinyStories-valid", "en", 17454728, 17455812, 22245308, 22246392], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489037687, 489037853, 22246407, 22246573], ["github/JavaScript", "webpack/webpack", "JavaScript", 308526965, 308529814, 22246588, 22249437], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486328722, 486329053, 22249452, 22249783], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489604528, 489604817, 22249798, 22250087], ["github/Java", "apache/commons-lang", "Java", 436402370, 436404112, 22250102, 22251844], ["tinystories/en", "TinyStories-valid", "en", 11085480, 11086520, 22251859, 22252899], ["github/PHP", "symfony/symfony", "PHP", 478888608, 478891338, 22252914, 22255644], ["github/Python", "django/django", "Python", 282377257, 282378444, 22255659, 22256846], ["tinystories/en", "TinyStories-valid", "en", 13726880, 13727762, 22256861, 22257743], ["github/Java", "apache/commons-lang", "Java", 436172589, 436174679, 22257758, 22259848], ["github/C", "curl/curl", "C", 377965630, 378139572, 22259863, 22433805], ["tinystories/en", "TinyStories-valid", "en", 14468874, 14470254, 22433820, 22435200], ["github/PHP", "symfony/symfony", "PHP", 473669999, 473670929, 22435215, 22436145], ["github/TypeScript", "angular/angular", "TypeScript", 325407497, 325408786, 22436160, 22437449], ["github/Python", "django/django", "Python", 286471698, 286474124, 22437464, 22439890], ["github/Java", "google/guava", "Java", 411215357, 411219092, 22439905, 22443640], ["github/TypeScript", "nestjs/nest", "TypeScript", 334508006, 334508178, 22443655, 22443827], ["github/Ruby", "rails/rails", "Ruby", 458111257, 458122959, 22443842, 22455544], ["tinystories/en", "TinyStories-valid", "en", 16539946, 16541179, 22455559, 22456792], ["github/JavaScript", "axios/axios", "JavaScript", 309442590, 309447925, 22456807, 22462142], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 483824011, 483829924, 22462157, 22468070], ["tinystories/en", "TinyStories-valid", "en", 11167818, 11168640, 22468085, 22468907], ["github/Java", "apache/commons-lang", "Java", 432261321, 432262827, 22468922, 22470428], ["tinystories/en", "TinyStories-valid", "en", 4326530, 4327255, 22470443, 22471168], ["tinystories/en", "TinyStories-valid", "en", 8396102, 8396736, 22471183, 22471817], ["github/Python", "scikit-learn/scikit-learn", "Python", 292016041, 292020115, 22471832, 22475906], ["github/Java", "google/guava", "Java", 417419184, 417422316, 22475921, 22479053], ["tinystories/en", "TinyStories-valid", "en", 9551312, 9551931, 22479068, 22479687], ["tinystories/en", "TinyStories-valid", "en", 11350367, 11350878, 22479702, 22480213], ["tinystories/en", "TinyStories-valid", "en", 8494453, 8495415, 22480228, 22481190], ["tinystories/en", "TinyStories-valid", "en", 15932960, 15933675, 22481205, 22481920], ["github/TypeScript", "vuejs/core", "TypeScript", 320828483, 320840440, 22481935, 22493892], ["tinystories/en", "TinyStories-valid", "en", 18826286, 18826839, 22493907, 22494460], ["books/en", "PG #165", "en", 113400875, 114048109, 22494475, 23141709], ["github/PHP", "symfony/symfony", "PHP", 471496334, 471510026, 23141711, 23155403], ["tinystories/en", "TinyStories-valid", "en", 16838927, 16839614, 23155418, 23156105], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515584526, 515585129, 23156120, 23156723], ["github/Java", "spring-projects/spring-framework", "Java", 425655328, 425663979, 23156738, 23165389], ["tinystories/en", "TinyStories-valid", "en", 3355585, 3356896, 23165404, 23166715], ["tinystories/en", "TinyStories-valid", "en", 4999265, 5000027, 23166730, 23167492], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485379618, 485386514, 23167507, 23174403], ["github/Python", "django/django", "Python", 286027734, 286035743, 23174418, 23182427], ["tinystories/en", "TinyStories-valid", "en", 2325594, 2326549, 23182442, 23183397], ["github/Scala", "playframework/playframework", "Scala", 507301632, 507317320, 23183412, 23199100], ["tinystories/en", "TinyStories-valid", "en", 13149823, 13150612, 23199115, 23199904], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 314938941, 314954338, 23199919, 23215316], ["tinystories/en", "TinyStories-valid", "en", 16338596, 16339241, 23215331, 23215976], ["github/TypeScript", "nestjs/nest", "TypeScript", 332626434, 332626584, 23215991, 23216141], ["tinystories/en", "TinyStories-valid", "en", 322664, 323379, 23216156, 23216871], ["github/Java", "google/guava", "Java", 413475056, 413481488, 23216886, 23223318], ["github/TypeScript", "nestjs/nest", "TypeScript", 337784467, 337785610, 23223333, 23224476], ["tinystories/en", "TinyStories-valid", "en", 14673003, 14673939, 23224491, 23225427], ["tinystories/en", "TinyStories-valid", "en", 17953425, 17954277, 23225442, 23226294], ["github/Python", "django/django", "Python", 286461916, 286462522, 23226309, 23226915], ["tinystories/en", "TinyStories-valid", "en", 16174151, 16174921, 23226930, 23227700], ["github/Java", "spring-projects/spring-framework", "Java", 425178277, 425179868, 23227715, 23229306], ["github/TypeScript", "angular/angular", "TypeScript", 325795644, 325800223, 23229321, 23233900], ["tinystories/en", "TinyStories-valid", "en", 17141093, 17141842, 23233915, 23234664], ["github/Python", "django/django", "Python", 283654737, 283656542, 23234679, 23236484], ["github/Ruby", "rails/rails", "Ruby", 455465515, 455469521, 23236499, 23240505], ["tinystories/en", "TinyStories-valid", "en", 2116973, 2117998, 23240520, 23241545], ["tinystories/en", "TinyStories-valid", "en", 17350845, 17351679, 23241560, 23242394], ["github/TypeScript", "nestjs/nest", "TypeScript", 333269015, 333269664, 23242409, 23243058], ["tinystories/en", "TinyStories-valid", "en", 16953222, 16953923, 23243073, 23243774], ["github/PHP", "guzzle/guzzle", "PHP", 479884910, 479893582, 23243789, 23252461], ["tinystories/en", "TinyStories-valid", "en", 12218606, 12219594, 23252476, 23253464], ["github/Java", "google/guava", "Java", 417193938, 417203691, 23253479, 23263232], ["github/TypeScript", "angular/angular", "TypeScript", 328614202, 328616269, 23263247, 23265314], ["tinystories/en", "TinyStories-valid", "en", 15650670, 15651819, 23265329, 23266478], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515441885, 515442867, 23266493, 23267475], ["github/Python", "django/django", "Python", 289063729, 289070770, 23267490, 23274531], ["github/TypeScript", "angular/angular", "TypeScript", 325206800, 325206966, 23274546, 23274712], ["github/TypeScript", "angular/angular", "TypeScript", 325133954, 325134164, 23274727, 23274937], ["books/fr", "PG #11036", "fr", 279066157, 279371908, 23274952, 23580703], ["github/Ruby", "sinatra/sinatra", "Ruby", 462470491, 462471351, 23580705, 23581565], ["github/Rust", "rust-lang/cargo", "Rust", 350076463, 350115868, 23581580, 23620985], ["tinystories/en", "TinyStories-valid", "en", 3580704, 3581279, 23621000, 23621575], ["github/C#", "dotnet/aspnetcore", "C#", 440930431, 440939305, 23621590, 23630464], ["github/TypeScript", "nestjs/nest", "TypeScript", 333250147, 333251572, 23630479, 23631904], ["tinystories/en", "TinyStories-valid", "en", 12298756, 12299445, 23631919, 23632608], ["github/Ruby", "rails/rails", "Ruby", 458752788, 458753543, 23632623, 23633378], ["github/TypeScript", "nestjs/nest", "TypeScript", 337887349, 337888374, 23633393, 23634418], ["tinystories/en", "TinyStories-valid", "en", 19129205, 19130302, 23634433, 23635530], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491345893, 491359749, 23635545, 23649401], ["github/PHP", "symfony/symfony", "PHP", 474489310, 474489737, 23649416, 23649843], ["github/Scala", "playframework/playframework", "Scala", 510188448, 510199945, 23649858, 23661355], ["github/TypeScript", "angular/angular", "TypeScript", 325071193, 325071783, 23661370, 23661960], ["tinystories/en", "TinyStories-valid", "en", 10879726, 10880548, 23661975, 23662797], ["github/TypeScript", "microsoft/vscode", "TypeScript", 319156614, 319156993, 23662812, 23663191], ["github/Ruby", "rails/rails", "Ruby", 453715937, 453716913, 23663206, 23664182], ["github/TypeScript", "angular/angular", "TypeScript", 326747960, 326748776, 23664197, 23665013], ["tinystories/en", "TinyStories-valid", "en", 9119473, 9120234, 23665028, 23665789], ["github/Python", "psf/requests", "Python", 281571230, 281572134, 23665804, 23666708], ["github/TypeScript", "angular/angular", "TypeScript", 325072333, 325072546, 23666723, 23666936], ["tinystories/en", "TinyStories-valid", "en", 14616316, 14617233, 23666951, 23667868], ["github/Python", "django/django", "Python", 282393340, 282394051, 23667883, 23668594], ["github/Ruby", "rails/rails", "Ruby", 458752102, 458752773, 23668609, 23669280], ["github/TypeScript", "angular/angular", "TypeScript", 326613707, 326615807, 23669295, 23671395], ["tinystories/en", "TinyStories-valid", "en", 8105563, 8106191, 23671410, 23672038], ["github/Java", "apache/commons-lang", "Java", 437038119, 437048900, 23672053, 23682834], ["tinystories/en", "TinyStories-valid", "en", 10448120, 10449191, 23682849, 23683920], ["github/Go", "prometheus/prometheus", "Go", 362091246, 362271045, 23683935, 23863734], ["github/C#", "dotnet/aspnetcore", "C#", 438502126, 438502663, 23863749, 23864286], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 309937848, 309952697, 23864301, 23879150], ["github/TypeScript", "nestjs/nest", "TypeScript", 332933310, 332934247, 23879165, 23880102], ["github/Python", "django/django", "Python", 287884498, 287887747, 23880117, 23883366], ["tinystories/en", "TinyStories-valid", "en", 4772113, 4772601, 23883381, 23883869], ["github/TypeScript", "nestjs/nest", "TypeScript", 333206238, 333206478, 23883884, 23884124], ["tinystories/en", "TinyStories-valid", "en", 18940044, 18940754, 23884139, 23884849], ["github/TypeScript", "nestjs/nest", "TypeScript", 335890601, 335890855, 23884864, 23885118], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 451349460, 451351385, 23885133, 23887058], ["github/Ruby", "rails/rails", "Ruby", 459731608, 459734317, 23887073, 23889782], ["github/Scala", "sbt/sbt", "Scala", 519031105, 519032839, 23889797, 23891531], ["tinystories/en", "TinyStories-valid", "en", 165854, 167560, 23891546, 23893252], ["github/C++", "protocolbuffers/protobuf", "C++", 400799289, 400802354, 23893267, 23896332], ["github/C#", "dotnet/aspnetcore", "C#", 442216134, 442216525, 23896347, 23896738], ["github/TypeScript", "nestjs/nest", "TypeScript", 335992435, 335996118, 23896753, 23900436], ["github/Java", "apache/commons-lang", "Java", 436977352, 436979167, 23900451, 23902266], ["github/Scala", "sbt/sbt", "Scala", 519898491, 519898738, 23902281, 23902528], ["github/Scala", "sbt/sbt", "Scala", 519761847, 519761954, 23902543, 23902650], ["tinystories/en", "TinyStories-valid", "en", 11377187, 11377840, 23902665, 23903318], ["github/C#", "dotnet/aspnetcore", "C#", 439177120, 439178265, 23903333, 23904478], ["tinystories/en", "TinyStories-valid", "en", 2929986, 2930742, 23904493, 23905249], ["github/Python", "django/django", "Python", 283736098, 283740484, 23905264, 23909650], ["github/PHP", "laravel/framework", "PHP", 468021645, 468037634, 23909665, 23925654], ["tinystories/en", "TinyStories-valid", "en", 13032743, 13033401, 23925669, 23926327], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449735953, 449737301, 23926342, 23927690], ["tinystories/en", "TinyStories-valid", "en", 4630697, 4631645, 23927705, 23928653], ["github/C++", "opencv/opencv", "C++", 399743699, 399750666, 23928668, 23935635], ["github/Java", "spring-projects/spring-framework", "Java", 418693212, 418701447, 23935650, 23943885], ["tinystories/en", "TinyStories-valid", "en", 1699702, 1700465, 23943900, 23944663], ["github/C#", "dotnet/aspnetcore", "C#", 442461362, 442462278, 23944678, 23945594], ["tinystories/en", "TinyStories-valid", "en", 2778528, 2779208, 23945609, 23946289], ["tinystories/en", "TinyStories-valid", "en", 18038063, 18039310, 23946304, 23947551], ["github/C#", "dotnet/aspnetcore", "C#", 442681360, 442682765, 23947566, 23948971], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 482130754, 482136627, 23948986, 23954859], ["tinystories/en", "TinyStories-valid", "en", 9431756, 9433085, 23954874, 23956203], ["github/Java", "spring-projects/spring-framework", "Java", 425040651, 425042327, 23956218, 23957894], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 451822259, 451823491, 23957909, 23959141], ["tinystories/en", "TinyStories-valid", "en", 13728576, 13729153, 23959156, 23959733], ["github/TypeScript", "angular/angular", "TypeScript", 329159001, 329171863, 23959748, 23972610], ["github/Java", "google/guava", "Java", 410630403, 410632469, 23972625, 23974691], ["tinystories/en", "TinyStories-valid", "en", 18353771, 18354389, 23974706, 23975324], ["github/C#", "dotnet/aspnetcore", "C#", 438640733, 438641124, 23975339, 23975730], ["github/JavaScript", "webpack/webpack", "JavaScript", 301397118, 301403789, 23975745, 23982416], ["tinystories/en", "TinyStories-valid", "en", 12389725, 12390829, 23982431, 23983535], ["github/C#", "dotnet/aspnetcore", "C#", 444865020, 444866100, 23983550, 23984630], ["github/Python", "django/django", "Python", 283621750, 283632005, 23984645, 23994900], ["github/C++", "protocolbuffers/protobuf", "C++", 405083918, 405092479, 23994915, 24003476], ["tinystories/en", "TinyStories-valid", "en", 9941064, 9941833, 24003491, 24004260], ["github/PHP", "laravel/framework", "PHP", 463993157, 463993669, 24004275, 24004787], ["github/Scala", "playframework/playframework", "Scala", 512393243, 512414805, 24004802, 24026364], ["github/PHP", "laravel/framework", "PHP", 463278446, 463278675, 24026379, 24026608], ["tinystories/en", "TinyStories-valid", "en", 5726825, 5727594, 24026623, 24027392], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515475063, 515476656, 24027407, 24029000], ["github/PHP", "symfony/symfony", "PHP", 474834093, 474835560, 24029015, 24030482], ["tinystories/en", "TinyStories-valid", "en", 4106141, 4107171, 24030497, 24031527], ["github/JavaScript", "axios/axios", "JavaScript", 309060408, 309061101, 24031542, 24032235], ["github/Kotlin", "ktorio/ktor", "Kotlin", 495106299, 495110892, 24032250, 24036843], ["tinystories/en", "TinyStories-valid", "en", 18124482, 18125159, 24036858, 24037535], ["github/JavaScript", "axios/axios", "JavaScript", 308917523, 308917614, 24037550, 24037641], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449212569, 449217474, 24037656, 24042561], ["github/Java", "google/guava", "Java", 409609403, 409622223, 24042576, 24055396], ["tinystories/en", "TinyStories-valid", "en", 12163528, 12164345, 24055411, 24056228], ["github/C++", "google/leveldb", "C++", 392285826, 392286722, 24056243, 24057139], ["tinystories/en", "TinyStories-valid", "en", 12979570, 12980241, 24057154, 24057825], ["github/Rust", "tokio-rs/tokio", "Rust", 340329419, 340334232, 24057840, 24062653], ["github/TypeScript", "vuejs/core", "TypeScript", 319366788, 319367287, 24062668, 24063167], ["tinystories/en", "TinyStories-valid", "en", 19231403, 19232082, 24063182, 24063861], ["github/C++", "opencv/opencv", "C++", 398124060, 398126115, 24063876, 24065931], ["github/Python", "django/django", "Python", 283632590, 283633953, 24065946, 24067309], ["tinystories/en", "TinyStories-valid", "en", 12487473, 12488368, 24067324, 24068219], ["tinystories/en", "TinyStories-valid", "en", 16197658, 16198406, 24068234, 24068982], ["github/C++", "protocolbuffers/protobuf", "C++", 403135857, 403138483, 24068997, 24071623], ["github/PHP", "laravel/framework", "PHP", 467871448, 467880485, 24071638, 24080675], ["tinystories/en", "TinyStories-valid", "en", 13160230, 13161146, 24080690, 24081606], ["books/en", "PG #327", "en", 169088322, 169228308, 24081621, 24221607], ["tinystories/en", "TinyStories-valid", "en", 14041267, 14041847, 24221609, 24222189], ["github/C++", "fmtlib/fmt", "C++", 391345212, 391345672, 24222204, 24222664], ["github/TypeScript", "angular/angular", "TypeScript", 324214171, 324221331, 24222679, 24229839], ["tinystories/en", "TinyStories-valid", "en", 12187187, 12188059, 24229854, 24230726], ["github/Swift", "vapor/vapor", "Swift", 497504071, 497506798, 24230741, 24233468], ["tinystories/en", "TinyStories-valid", "en", 338204, 338674, 24233483, 24233953], ["github/C++", "protocolbuffers/protobuf", "C++", 404598084, 404601118, 24233968, 24237002], ["github/Java", "google/guava", "Java", 412404940, 412412174, 24237017, 24244251], ["tinystories/en", "TinyStories-valid", "en", 1451516, 1452346, 24244266, 24245096], ["tinystories/en", "TinyStories-valid", "en", 12857853, 12859034, 24245111, 24246292], ["github/Ruby", "rails/rails", "Ruby", 461299559, 461319251, 24246307, 24265999], ["github/Scala", "playframework/playframework", "Scala", 511828786, 511830677, 24266014, 24267905], ["github/Python", "scikit-learn/scikit-learn", "Python", 292329665, 292339989, 24267920, 24278244], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 452575155, 452584237, 24278259, 24287341], ["github/TypeScript", "angular/angular", "TypeScript", 324995289, 324995896, 24287356, 24287963], ["tinystories/en", "TinyStories-valid", "en", 18385276, 18386060, 24287978, 24288762], ["github/TypeScript", "nestjs/nest", "TypeScript", 337758566, 337758822, 24288777, 24289033], ["github/TypeScript", "nestjs/nest", "TypeScript", 337839442, 337839920, 24289048, 24289526], ["github/Java", "google/guava", "Java", 413870991, 413872601, 24289541, 24291151], ["tinystories/en", "TinyStories-valid", "en", 5897431, 5898515, 24291166, 24292250], ["github/TypeScript", "angular/angular", "TypeScript", 325132317, 325132636, 24292265, 24292584], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 487030966, 487043080, 24292599, 24304713], ["github/TypeScript", "nestjs/nest", "TypeScript", 337532130, 337532723, 24304728, 24305321], ["github/PHP", "laravel/framework", "PHP", 469072829, 469076946, 24305336, 24309453], ["tinystories/en", "TinyStories-valid", "en", 4780951, 4781603, 24309468, 24310120], ["github/TypeScript", "nestjs/nest", "TypeScript", 335910598, 335911015, 24310135, 24310552], ["github/TypeScript", "nestjs/nest", "TypeScript", 334782946, 334783034, 24310567, 24310655], ["github/TypeScript", "nestjs/nest", "TypeScript", 335745143, 335745256, 24310670, 24310783], ["tinystories/en", "TinyStories-valid", "en", 10421188, 10421900, 24310798, 24311510], ["github/TypeScript", "nestjs/nest", "TypeScript", 333620516, 333620743, 24311525, 24311752], ["github/TypeScript", "angular/angular", "TypeScript", 326386681, 326387098, 24311767, 24312184], ["github/Java", "spring-projects/spring-framework", "Java", 421655770, 421661092, 24312199, 24317521], ["github/Scala", "playframework/playframework", "Scala", 511753262, 511760430, 24317536, 24324704], ["tinystories/en", "TinyStories-valid", "en", 11871238, 11872749, 24324719, 24326230], ["tinystories/en", "TinyStories-valid", "en", 9952713, 9953649, 24326245, 24327181], ["github/PHP", "symfony/symfony", "PHP", 476990839, 476993370, 24327196, 24329727], ["github/TypeScript", "nestjs/nest", "TypeScript", 332353999, 332359042, 24329742, 24334785], ["github/C++", "protocolbuffers/protobuf", "C++", 406523403, 406540717, 24334800, 24352114], ["github/Java", "google/guava", "Java", 413731403, 413733073, 24352129, 24353799], ["tinystories/en", "TinyStories-valid", "en", 17183348, 17184341, 24353814, 24354807], ["github/Python", "scikit-learn/scikit-learn", "Python", 292540453, 292542333, 24354822, 24356702], ["tinystories/en", "TinyStories-valid", "en", 8131675, 8132293, 24356717, 24357335], ["github/Java", "spring-projects/spring-framework", "Java", 421499212, 421501090, 24357350, 24359228], ["github/Python", "django/django", "Python", 284037632, 284038231, 24359243, 24359842], ["tinystories/en", "TinyStories-valid", "en", 9680608, 9681394, 24359857, 24360643], ["github/Scala", "sbt/sbt", "Scala", 519429415, 519431080, 24360658, 24362323], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 312196196, 312228512, 24362338, 24394654], ["github/Java", "spring-projects/spring-framework", "Java", 418143155, 418144939, 24394669, 24396453], ["tinystories/en", "TinyStories-valid", "en", 13168118, 13168745, 24396468, 24397095], ["github/Rust", "rust-lang/cargo", "Rust", 354351009, 354376733, 24397110, 24422834], ["tinystories/en", "TinyStories-valid", "en", 17240450, 17241324, 24422849, 24423723], ["github/TypeScript", "microsoft/vscode", "TypeScript", 318503346, 318505271, 24423738, 24425663], ["github/Java", "spring-projects/spring-framework", "Java", 425413819, 425415588, 24425678, 24427447], ["github/Scala", "playframework/playframework", "Scala", 512003454, 512005289, 24427462, 24429297], ["github/PHP", "laravel/framework", "PHP", 470909987, 470916073, 24429312, 24435398], ["tinystories/en", "TinyStories-valid", "en", 5999356, 6000420, 24435413, 24436477], ["github/Python", "scikit-learn/scikit-learn", "Python", 292164648, 292169189, 24436492, 24441033], ["github/Java", "spring-projects/spring-framework", "Java", 417651579, 417652936, 24441048, 24442405], ["tinystories/en", "TinyStories-valid", "en", 7569767, 7570263, 24442420, 24442916], ["github/Scala", "playframework/playframework", "Scala", 511735840, 511737256, 24442931, 24444347], ["github/Java", "google/guava", "Java", 412731065, 412732329, 24444362, 24445626], ["tinystories/en", "TinyStories-valid", "en", 5906047, 5907144, 24445641, 24446738], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 487155529, 487159708, 24446753, 24450932], ["tinystories/en", "TinyStories-valid", "en", 11905032, 11906093, 24450947, 24452008], ["github/C++", "opencv/opencv", "C++", 397928763, 397928849, 24452023, 24452109], ["github/TypeScript", "nestjs/nest", "TypeScript", 334533128, 334538913, 24452124, 24457909], ["github/Java", "spring-projects/spring-framework", "Java", 420135890, 420140408, 24457924, 24462442], ["github/Scala", "sbt/sbt", "Scala", 518921057, 518926726, 24462457, 24468126], ["github/Swift", "vapor/vapor", "Swift", 497216682, 497219115, 24468141, 24470574], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481903665, 481903713, 24470589, 24470637], ["tinystories/en", "TinyStories-valid", "en", 6153706, 6157584, 24470652, 24474530], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491409664, 491410556, 24474545, 24475437], ["github/TypeScript", "angular/angular", "TypeScript", 326621732, 326622290, 24475452, 24476010], ["github/C++", "opencv/opencv", "C++", 398874300, 398882290, 24476025, 24484015], ["github/TypeScript", "nestjs/nest", "TypeScript", 333098099, 333098383, 24484030, 24484314], ["github/TypeScript", "angular/angular", "TypeScript", 325006203, 325006534, 24484329, 24484660], ["github/Python", "scikit-learn/scikit-learn", "Python", 291115359, 291123627, 24484675, 24492943], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492794819, 492796481, 24492958, 24494620], ["github/Scala", "scala/scala", "Scala", 503837328, 503838801, 24494635, 24496108], ["tinystories/en", "TinyStories-valid", "en", 12106676, 12107612, 24496123, 24497059], ["github/PHP", "laravel/framework", "PHP", 464210196, 464219327, 24497074, 24506205], ["github/TypeScript", "nestjs/nest", "TypeScript", 332604118, 332606960, 24506220, 24509062], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 446531974, 446551236, 24509077, 24528339], ["tinystories/en", "TinyStories-valid", "en", 13039830, 13040648, 24528354, 24529172], ["github/Scala", "scala/scala", "Scala", 503052148, 503053303, 24529187, 24530342], ["github/Java", "square/okhttp", "Java", 427520506, 427532406, 24530357, 24542257], ["tinystories/en", "TinyStories-valid", "en", 12495585, 12496202, 24542272, 24542889], ["github/Scala", "playframework/playframework", "Scala", 511190462, 511190707, 24542904, 24543149], ["books/en", "PG #299", "en", 162597400, 162920114, 24543164, 24865878], ["tinystories/en", "TinyStories-valid", "en", 7784287, 7785352, 24865880, 24866945], ["github/TypeScript", "angular/angular", "TypeScript", 325756872, 325758160, 24866960, 24868248], ["github/Scala", "scala/scala", "Scala", 506108463, 506110246, 24868263, 24870046], ["github/C++", "protocolbuffers/protobuf", "C++", 403257754, 403261441, 24870061, 24873748], ["github/TypeScript", "angular/angular", "TypeScript", 325618999, 325619365, 24873763, 24874129], ["tinystories/en", "TinyStories-valid", "en", 3454753, 3455570, 24874144, 24874961], ["tinystories/en", "TinyStories-valid", "en", 18154079, 18154809, 24874976, 24875706], ["tinystories/en", "TinyStories-valid", "en", 7554976, 7556103, 24875721, 24876848], ["github/PHP", "laravel/framework", "PHP", 470310948, 470311469, 24876863, 24877384], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490210222, 490217927, 24877399, 24885104], ["github/Scala", "playframework/playframework", "Scala", 511884848, 511889648, 24885119, 24889919], ["github/PHP", "symfony/symfony", "PHP", 478522070, 478522849, 24889934, 24890713], ["tinystories/en", "TinyStories-valid", "en", 5390423, 5391164, 24890728, 24891469], ["github/Java", "spring-projects/spring-framework", "Java", 424938273, 424941536, 24891484, 24894747], ["github/TypeScript", "angular/angular", "TypeScript", 330653969, 330660346, 24894762, 24901139], ["tinystories/en", "TinyStories-valid", "en", 543814, 544382, 24901154, 24901722], ["tinystories/en", "TinyStories-valid", "en", 11373894, 11374535, 24901737, 24902378], ["github/Rust", "tokio-rs/tokio", "Rust", 345454251, 345460750, 24902393, 24908892], ["tinystories/en", "TinyStories-valid", "en", 15615163, 15616061, 24908907, 24909805], ["github/Java", "spring-projects/spring-framework", "Java", 420380831, 420383143, 24909820, 24912132], ["github/C++", "opencv/opencv", "C++", 399671249, 399680396, 24912147, 24921294], ["github/Scala", "playframework/playframework", "Scala", 512326276, 512327015, 24921309, 24922048], ["tinystories/en", "TinyStories-valid", "en", 4110872, 4111541, 24922063, 24922732], ["github/Scala", "playframework/playframework", "Scala", 511014940, 511015255, 24922747, 24923062], ["github/JavaScript", "axios/axios", "JavaScript", 309100922, 309104264, 24923077, 24926419], ["github/Java", "spring-projects/spring-framework", "Java", 423544474, 423545360, 24926434, 24927320], ["tinystories/en", "TinyStories-valid", "en", 19370389, 19370984, 24927335, 24927930], ["tinystories/en", "TinyStories-valid", "en", 12840581, 12841285, 24927945, 24928649], ["tinystories/en", "TinyStories-valid", "en", 13199933, 13200463, 24928664, 24929194], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486754544, 486755537, 24929209, 24930202], ["tinystories/en", "TinyStories-valid", "en", 5896165, 5897416, 24930217, 24931468], ["github/Python", "django/django", "Python", 284515634, 284532400, 24931483, 24948249], ["tinystories/en", "TinyStories-valid", "en", 17754971, 17756014, 24948264, 24949307], ["github/C#", "dotnet/aspnetcore", "C#", 445736792, 445737935, 24949322, 24950465], ["tinystories/en", "TinyStories-valid", "en", 1956057, 1957021, 24950480, 24951444], ["github/JavaScript", "webpack/webpack", "JavaScript", 304124234, 304131173, 24951459, 24958398], ["tinystories/en", "TinyStories-valid", "en", 5535282, 5535846, 24958413, 24958977], ["github/C#", "dotnet/aspnetcore", "C#", 444196530, 444196950, 24958992, 24959412], ["tinystories/en", "TinyStories-valid", "en", 10454854, 10455563, 24959427, 24960136], ["github/Ruby", "rails/rails", "Ruby", 459616370, 459631023, 24960151, 24974804], ["tinystories/en", "TinyStories-valid", "en", 10810201, 10810956, 24974819, 24975574], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 452084336, 452086679, 24975589, 24977932], ["tinystories/en", "TinyStories-valid", "en", 16029880, 16030559, 24977947, 24978626], ["github/Java", "google/guava", "Java", 411514321, 411536803, 24978641, 25001123], ["tinystories/en", "TinyStories-valid", "en", 7623678, 7624588, 25001138, 25002048], ["tinystories/en", "TinyStories-valid", "en", 3539448, 3540243, 25002063, 25002858], ["github/C#", "dotnet/aspnetcore", "C#", 442495901, 442496794, 25002873, 25003766], ["tinystories/en", "TinyStories-valid", "en", 7804049, 7805078, 25003781, 25004810], ["github/JavaScript", "webpack/webpack", "JavaScript", 306817736, 306820638, 25004825, 25007727], ["github/C++", "opencv/opencv", "C++", 399750681, 399769537, 25007742, 25026598], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 482168494, 482180193, 25026613, 25038312], ["tinystories/en", "TinyStories-valid", "en", 15556179, 15556716, 25038327, 25038864], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 450017880, 450019426, 25038879, 25040425], ["github/PHP", "laravel/framework", "PHP", 470544991, 470571975, 25040440, 25067424], ["github/Rust", "BurntSushi/ripgrep", "Rust", 338760008, 338778636, 25067439, 25086067], ["tinystories/en", "TinyStories-valid", "en", 14700836, 14702008, 25086082, 25087254], ["github/JavaScript", "webpack/webpack", "JavaScript", 302189406, 302189797, 25087269, 25087660], ["tinystories/en", "TinyStories-valid", "en", 17445148, 17445867, 25087675, 25088394], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449980402, 449981974, 25088409, 25089981], ["tinystories/en", "TinyStories-valid", "en", 15160084, 15162098, 25089996, 25092010], ["tinystories/en", "TinyStories-valid", "en", 832425, 833245, 25092025, 25092845], ["github/JavaScript", "webpack/webpack", "JavaScript", 302361138, 302367366, 25092860, 25099088], ["github/Python", "scikit-learn/scikit-learn", "Python", 291921383, 291927856, 25099103, 25105576], ["tinystories/en", "TinyStories-valid", "en", 1260406, 1261097, 25105591, 25106282], ["github/Java", "spring-projects/spring-framework", "Java", 423018004, 423020429, 25106297, 25108722], ["tinystories/en", "TinyStories-valid", "en", 13683181, 13684079, 25108737, 25109635], ["tinystories/en", "TinyStories-valid", "en", 11077031, 11077679, 25109650, 25110298], ["github/C++", "protocolbuffers/protobuf", "C++", 406821572, 406822641, 25110313, 25111382], ["tinystories/en", "TinyStories-valid", "en", 4741771, 4742440, 25111397, 25112066], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489336584, 489337273, 25112081, 25112770], ["github/Java", "google/guava", "Java", 414128598, 414133503, 25112785, 25117690], ["github/JavaScript", "webpack/webpack", "JavaScript", 300516386, 300516731, 25117705, 25118050], ["github/C++", "protocolbuffers/protobuf", "C++", 401754228, 401754778, 25118065, 25118615], ["github/TypeScript", "vuejs/core", "TypeScript", 319792480, 319831333, 25118630, 25157483], ["github/Python", "django/django", "Python", 283708059, 283708310, 25157498, 25157749], ["tinystories/en", "TinyStories-valid", "en", 4641808, 4643356, 25157764, 25159312], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485605766, 485607278, 25159327, 25160839], ["github/JavaScript", "axios/axios", "JavaScript", 309467776, 309470249, 25160854, 25163327], ["tinystories/en", "TinyStories-valid", "en", 15964498, 15965627, 25163342, 25164471], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490593498, 490593844, 25164486, 25164832], ["github/Rust", "serde-rs/serde", "Rust", 346858089, 346858197, 25164847, 25164955], ["github/Python", "scikit-learn/scikit-learn", "Python", 292399714, 292403803, 25164970, 25169059], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491699419, 491700035, 25169074, 25169690], ["tinystories/en", "TinyStories-valid", "en", 8951990, 8953028, 25169705, 25170743], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315044399, 315045128, 25170758, 25171487], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491503475, 491503899, 25171502, 25171926], ["github/C#", "dotnet/aspnetcore", "C#", 440039070, 440052807, 25171941, 25185678], ["github/JavaScript", "webpack/webpack", "JavaScript", 300577074, 300578557, 25185693, 25187176], ["github/Scala", "scala/scala", "Scala", 499881066, 499931891, 25187191, 25238016], ["tinystories/en", "TinyStories-valid", "en", 11874995, 11876651, 25238031, 25239687], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485323537, 485324733, 25239702, 25240898], ["github/Java", "spring-projects/spring-framework", "Java", 418924117, 418933842, 25240913, 25250638], ["tinystories/en", "TinyStories-valid", "en", 19051387, 19052131, 25250653, 25251397], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489297249, 489298025, 25251412, 25252188], ["github/Python", "django/django", "Python", 283574962, 283576918, 25252203, 25254159], ["github/C++", "nlohmann/json", "C++", 389793471, 389808309, 25254174, 25269012], ["tinystories/en", "TinyStories-valid", "en", 10355683, 10356376, 25269027, 25269720], ["github/Swift", "Alamofire/Alamofire", "Swift", 496674455, 496683344, 25269735, 25278624], ["github/PHP", "guzzle/guzzle", "PHP", 480869237, 480871468, 25278639, 25280870], ["tinystories/en", "TinyStories-valid", "en", 14857007, 14858117, 25280885, 25281995], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315111987, 315117300, 25282010, 25287323], ["github/Python", "scikit-learn/scikit-learn", "Python", 291889234, 291891212, 25287338, 25289316], ["github/Java", "spring-projects/spring-framework", "Java", 425999779, 425999996, 25289331, 25289548], ["tinystories/en", "TinyStories-valid", "en", 530909, 531546, 25289563, 25290200], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 482059570, 482062879, 25290215, 25293524], ["tinystories/en", "TinyStories-valid", "en", 16878740, 16879425, 25293539, 25294224], ["books/en", "PG #372", "en", 185006461, 185363765, 25294239, 25651543], ["tinystories/en", "TinyStories-valid", "en", 12982442, 12983114, 25651545, 25652217], ["github/Ruby", "rails/rails", "Ruby", 454895744, 454903715, 25652232, 25660203], ["tinystories/en", "TinyStories-valid", "en", 4759550, 4760356, 25660218, 25661024], ["github/Rust", "tokio-rs/tokio", "Rust", 341891675, 341906977, 25661039, 25676341], ["github/Java", "square/okhttp", "Java", 428389097, 428396668, 25676356, 25683927], ["github/Python", "scikit-learn/scikit-learn", "Python", 290828078, 290831604, 25683942, 25687468], ["github/JavaScript", "webpack/webpack", "JavaScript", 303232512, 303233280, 25687483, 25688251], ["tinystories/en", "TinyStories-valid", "en", 5795438, 5796334, 25688266, 25689162], ["github/PHP", "laravel/framework", "PHP", 468896966, 468902380, 25689177, 25694591], ["tinystories/en", "TinyStories-valid", "en", 15078553, 15079273, 25694606, 25695326], ["tinystories/en", "TinyStories-valid", "en", 122551, 123274, 25695341, 25696064], ["github/C#", "dotnet/aspnetcore", "C#", 440958422, 440959256, 25696079, 25696913], ["books/fr", "PG #799", "fr", 214444673, 214795281, 25696928, 26047536], ["tinystories/en", "TinyStories-valid", "en", 582487, 583069, 26047538, 26048120], ["tinystories/en", "TinyStories-valid", "en", 13272487, 13273129, 26048135, 26048777], ["github/Java", "spring-projects/spring-framework", "Java", 423974817, 423977734, 26048792, 26051709], ["github/PHP", "symfony/symfony", "PHP", 474536333, 474536878, 26051724, 26052269], ["tinystories/en", "TinyStories-valid", "en", 14026204, 14026912, 26052284, 26052992], ["github/C++", "protocolbuffers/protobuf", "C++", 408783265, 408789604, 26053007, 26059346], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 311102501, 311109397, 26059361, 26066257], ["tinystories/en", "TinyStories-valid", "en", 16758329, 16758906, 26066272, 26066849], ["tinystories/en", "TinyStories-valid", "en", 17310231, 17311145, 26066864, 26067778], ["github/Java", "google/guava", "Java", 409308171, 409310557, 26067793, 26070179], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 483557782, 483567001, 26070194, 26079413], ["github/PHP", "symfony/symfony", "PHP", 479584400, 479588599, 26079428, 26083627], ["tinystories/en", "TinyStories-valid", "en", 13223562, 13224210, 26083642, 26084290], ["tinystories/en", "TinyStories-valid", "en", 10103528, 10104598, 26084305, 26085375], ["github/C++", "nlohmann/json", "C++", 385581797, 385582961, 26085390, 26086554], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 450598324, 450605294, 26086569, 26093539], ["github/Ruby", "rails/rails", "Ruby", 454573676, 454574287, 26093554, 26094165], ["tinystories/en", "TinyStories-valid", "en", 3830500, 3831303, 26094180, 26094983], ["github/TypeScript", "nestjs/nest", "TypeScript", 332779227, 332779610, 26094998, 26095381], ["tinystories/en", "TinyStories-valid", "en", 13123710, 13124557, 26095396, 26096243], ["github/TypeScript", "nestjs/nest", "TypeScript", 335881737, 335882144, 26096258, 26096665], ["github/Python", "scikit-learn/scikit-learn", "Python", 293839343, 293853052, 26096680, 26110389], ["github/PHP", "symfony/symfony", "PHP", 477924882, 477927326, 26110404, 26112848], ["github/TypeScript", "nestjs/nest", "TypeScript", 337747996, 337749044, 26112863, 26113911], ["tinystories/en", "TinyStories-valid", "en", 7795816, 7796836, 26113926, 26114946], ["github/C++", "protocolbuffers/protobuf", "C++", 401446029, 401452419, 26114961, 26121351], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 317559237, 317563867, 26121366, 26125996], ["tinystories/en", "TinyStories-valid", "en", 17606692, 17607760, 26126011, 26127079], ["github/PHP", "laravel/framework", "PHP", 465199180, 465199326, 26127094, 26127240], ["github/Java", "apache/commons-lang", "Java", 435564883, 435579402, 26127255, 26141774], ["github/TypeScript", "nestjs/nest", "TypeScript", 333498205, 333500313, 26141789, 26143897], ["tinystories/en", "TinyStories-valid", "en", 12331850, 12332791, 26143912, 26144853], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486885356, 486885928, 26144868, 26145440], ["github/TypeScript", "angular/angular", "TypeScript", 324968271, 324969263, 26145455, 26146447], ["github/C#", "dotnet/aspnetcore", "C#", 443724636, 443726161, 26146462, 26147987], ["tinystories/en", "TinyStories-valid", "en", 8028092, 8029214, 26148002, 26149124], ["github/PHP", "symfony/symfony", "PHP", 472147961, 472152450, 26149139, 26153628], ["github/C++", "protocolbuffers/protobuf", "C++", 404210785, 404212496, 26153643, 26155354], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481553017, 481554372, 26155369, 26156724], ["github/TypeScript", "nestjs/nest", "TypeScript", 337814906, 337816244, 26156739, 26158077], ["tinystories/en", "TinyStories-valid", "en", 10957082, 10957970, 26158092, 26158980], ["github/C++", "protocolbuffers/protobuf", "C++", 404595151, 404595696, 26158995, 26159540], ["github/TypeScript", "nestjs/nest", "TypeScript", 337820237, 337820435, 26159555, 26159753], ["tinystories/en", "TinyStories-valid", "en", 11498821, 11499458, 26159768, 26160405], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 483713495, 483714116, 26160420, 26161041], ["github/TypeScript", "nestjs/nest", "TypeScript", 333954737, 333956143, 26161056, 26162462], ["tinystories/en", "TinyStories-valid", "en", 9493166, 9494368, 26162477, 26163679], ["github/C++", "google/leveldb", "C++", 392197605, 392200532, 26163694, 26166621], ["github/Kotlin", "ktorio/ktor", "Kotlin", 488364311, 488365306, 26166636, 26167631], ["tinystories/en", "TinyStories-valid", "en", 16090903, 16092022, 26167646, 26168765], ["github/Rust", "rust-lang/cargo", "Rust", 353423521, 353440388, 26168780, 26185647], ["github/Python", "django/django", "Python", 282447069, 282447757, 26185662, 26186350], ["github/TypeScript", "nestjs/nest", "TypeScript", 337799673, 337801581, 26186365, 26188273], ["github/Java", "google/guava", "Java", 409731044, 409733953, 26188288, 26191197], ["github/C#", "dotnet/aspnetcore", "C#", 446122115, 446127201, 26191212, 26196298], ["github/C++", "nlohmann/json", "C++", 385485874, 385486312, 26196313, 26196751], ["tinystories/en", "TinyStories-valid", "en", 10181478, 10182206, 26196766, 26197494], ["github/Python", "scikit-learn/scikit-learn", "Python", 291607432, 291609154, 26197509, 26199231], ["github/JavaScript", "webpack/webpack", "JavaScript", 302190688, 302201340, 26199246, 26209898], ["tinystories/en", "TinyStories-valid", "en", 5648044, 5649074, 26209913, 26210943], ["github/Scala", "sbt/sbt", "Scala", 519047949, 519050580, 26210958, 26213589], ["github/C++", "opencv/opencv", "C++", 398789302, 398793462, 26213604, 26217764], ["github/Ruby", "rails/rails", "Ruby", 453065767, 453077213, 26217779, 26229225], ["tinystories/en", "TinyStories-valid", "en", 1586946, 1587383, 26229240, 26229677], ["github/TypeScript", "angular/angular", "TypeScript", 324429973, 324432967, 26229692, 26232686], ["github/PHP", "symfony/symfony", "PHP", 474020540, 474028664, 26232701, 26240825], ["tinystories/en", "TinyStories-valid", "en", 4274184, 4275163, 26240840, 26241819], ["github/Python", "django/django", "Python", 288085526, 288087171, 26241834, 26243479], ["stdlib/python", "python3.13 stdlib", "Python", 30842094, 30933018, 26243494, 26334418], ["tinystories/en", "TinyStories-valid", "en", 3730159, 3730978, 26334420, 26335239], ["github/C#", "dotnet/aspnetcore", "C#", 443941212, 443942321, 26335254, 26336363], ["github/Scala", "playframework/playframework", "Scala", 508669970, 508672757, 26336378, 26339165], ["books/en", "PG #137", "en", 99399037, 99489735, 26339180, 26429878], ["github/TypeScript", "angular/angular", "TypeScript", 325094790, 325096258, 26429880, 26431348], ["github/Python", "django/django", "Python", 282407166, 282408889, 26431363, 26433086], ["tinystories/en", "TinyStories-valid", "en", 11859347, 11861110, 26433101, 26434864], ["github/Scala", "sbt/sbt", "Scala", 519827213, 519827245, 26434879, 26434911], ["github/Java", "google/guava", "Java", 410692935, 410706352, 26434926, 26448343], ["github/Scala", "sbt/sbt", "Scala", 517709357, 517709652, 26448358, 26448653], ["github/Python", "django/django", "Python", 289127892, 289128903, 26448668, 26449679], ["tinystories/en", "TinyStories-valid", "en", 8407735, 8408533, 26449694, 26450492], ["github/C++", "opencv/opencv", "C++", 394313069, 394319969, 26450507, 26457407], ["github/Scala", "scala/scala", "Scala", 498849347, 498851709, 26457422, 26459784], ["github/PHP", "laravel/framework", "PHP", 464078409, 464078676, 26459799, 26460066], ["tinystories/en", "TinyStories-valid", "en", 16186911, 16187610, 26460081, 26460780], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 484541018, 484553417, 26460795, 26473194], ["github/TypeScript", "angular/angular", "TypeScript", 331788348, 331794078, 26473209, 26478939], ["github/PHP", "symfony/symfony", "PHP", 479323445, 479324720, 26478954, 26480229], ["tinystories/en", "TinyStories-valid", "en", 19132784, 19133830, 26480244, 26481290], ["tinystories/en", "TinyStories-valid", "en", 8145006, 8145876, 26481305, 26482175], ["github/Scala", "scala/scala", "Scala", 505340127, 505343137, 26482190, 26485200], ["github/C++", "nlohmann/json", "C++", 385486327, 385486944, 26485215, 26485832], ["tinystories/en", "TinyStories-valid", "en", 17309336, 17310216, 26485847, 26486727], ["github/JavaScript", "webpack/webpack", "JavaScript", 305526925, 305533098, 26486742, 26492915], ["github/C", "madler/zlib", "C", 383785021, 383792821, 26492930, 26500730], ["github/Swift", "vapor/vapor", "Swift", 497992427, 497992872, 26500745, 26501190], ["tinystories/en", "TinyStories-valid", "en", 15415708, 15416787, 26501205, 26502284], ["github/Scala", "playframework/playframework", "Scala", 511662058, 511662899, 26502299, 26503140], ["github/Java", "google/guava", "Java", 411782850, 411787041, 26503155, 26507346], ["github/C#", "dotnet/aspnetcore", "C#", 438069893, 438080806, 26507361, 26518274], ["tinystories/en", "TinyStories-valid", "en", 4948251, 4949249, 26518289, 26519287], ["github/Python", "scikit-learn/scikit-learn", "Python", 291310618, 291320555, 26519302, 26529239], ["tinystories/en", "TinyStories-valid", "en", 11465727, 11466359, 26529254, 26529886], ["github/Rust", "rust-lang/cargo", "Rust", 349855517, 349864609, 26529901, 26538993], ["github/C++", "protocolbuffers/protobuf", "C++", 401466917, 401476031, 26539008, 26548122], ["github/Scala", "playframework/playframework", "Scala", 508623474, 508628298, 26548137, 26552961], ["tinystories/en", "TinyStories-valid", "en", 9481949, 9483208, 26552976, 26554235], ["github/TypeScript", "angular/angular", "TypeScript", 325316060, 325322460, 26554250, 26560650], ["github/Java", "square/okhttp", "Java", 428806779, 428809972, 26560665, 26563858], ["github/Ruby", "rails/rails", "Ruby", 453524641, 453525474, 26563873, 26564706], ["tinystories/en", "TinyStories-valid", "en", 9543007, 9543690, 26564721, 26565404], ["tinystories/en", "TinyStories-valid", "en", 7419976, 7420730, 26565419, 26566173], ["github/Scala", "playframework/playframework", "Scala", 514803033, 514803763, 26566188, 26566918], ["github/JavaScript", "webpack/webpack", "JavaScript", 308302630, 308308044, 26566933, 26572347], ["github/Go", "spf13/cobra", "Go", 357547069, 357560680, 26572362, 26585973], ["github/C++", "nlohmann/json", "C++", 385563555, 385563778, 26585988, 26586211], ["tinystories/en", "TinyStories-valid", "en", 1301702, 1304452, 26586226, 26588976], ["github/Scala", "sbt/sbt", "Scala", 519786438, 519787882, 26588991, 26590435], ["github/PHP", "laravel/framework", "PHP", 468188159, 468205182, 26590450, 26607473], ["github/C++", "nlohmann/json", "C++", 390580575, 390581118, 26607488, 26608031], ["github/C++", "protocolbuffers/protobuf", "C++", 408164669, 408165082, 26608046, 26608459], ["github/C++", "nlohmann/json", "C++", 385530992, 385531414, 26608474, 26608896], ["github/C++", "nlohmann/json", "C++", 385612126, 385612687, 26608911, 26609472], ["github/C#", "dotnet/aspnetcore", "C#", 442323821, 442324299, 26609487, 26609965], ["tinystories/en", "TinyStories-valid", "en", 13989885, 13990567, 26609980, 26610662], ["github/C++", "nlohmann/json", "C++", 385586945, 385587650, 26610677, 26611382], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494450361, 494455926, 26611397, 26616962], ["tinystories/en", "TinyStories-valid", "en", 10305836, 10306561, 26616977, 26617702], ["github/JavaScript", "lodash/lodash", "JavaScript", 300129021, 300130031, 26617717, 26618727], ["github/C#", "dotnet/aspnetcore", "C#", 438794103, 438795043, 26618742, 26619682], ["github/C", "madler/zlib", "C", 384176813, 384181371, 26619697, 26624255], ["tinystories/en", "TinyStories-valid", "en", 18142930, 18143737, 26624270, 26625077], ["github/JavaScript", "webpack/webpack", "JavaScript", 300922112, 300922478, 26625092, 26625458], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 309619018, 309619607, 26625473, 26626062], ["github/TypeScript", "vuejs/core", "TypeScript", 319997286, 320005956, 26626077, 26634747], ["tinystories/en", "TinyStories-valid", "en", 8263497, 8264412, 26634762, 26635677], ["tinystories/en", "TinyStories-valid", "en", 18345591, 18346086, 26635692, 26636187], ["github/Python", "django/django", "Python", 282701399, 282710398, 26636202, 26645201], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 447092823, 447095708, 26645216, 26648101], ["github/Scala", "scala/scala", "Scala", 500687157, 500696753, 26648116, 26657712], ["tinystories/en", "TinyStories-valid", "en", 10500922, 10501975, 26657727, 26658780], ["tinystories/en", "TinyStories-valid", "en", 2915234, 2915750, 26658795, 26659311], ["github/Swift", "vapor/vapor", "Swift", 498641421, 498644792, 26659326, 26662697], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491411571, 491413113, 26662712, 26664254], ["tinystories/en", "TinyStories-valid", "en", 4511710, 4512379, 26664269, 26664938], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 450681220, 450682792, 26664953, 26666525], ["github/Go", "gohugoio/hugo", "Go", 371950955, 371951989, 26666540, 26667574], ["tinystories/en", "TinyStories-valid", "en", 12728074, 12729540, 26667589, 26669055], ["github/TypeScript", "vuejs/core", "TypeScript", 323514547, 323514726, 26669070, 26669249], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491684977, 491685406, 26669264, 26669693], ["github/TypeScript", "angular/angular", "TypeScript", 326681868, 326682325, 26669708, 26670165], ["github/JavaScript", "webpack/webpack", "JavaScript", 304615733, 304625116, 26670180, 26679563], ["tinystories/en", "TinyStories-valid", "en", 14451009, 14451963, 26679578, 26680532], ["github/TypeScript", "angular/angular", "TypeScript", 327380491, 327381854, 26680547, 26681910], ["github/Scala", "scala/scala", "Scala", 502985807, 502986622, 26681925, 26682740], ["github/Python", "django/django", "Python", 286444223, 286445212, 26682755, 26683744], ["tinystories/en", "TinyStories-valid", "en", 18521111, 18522093, 26683759, 26684741], ["github/Java", "google/guava", "Java", 416726966, 416765866, 26684756, 26723656], ["github/Scala", "playframework/playframework", "Scala", 509546124, 509547216, 26723671, 26724763], ["tinystories/en", "TinyStories-valid", "en", 11097154, 11097860, 26724778, 26725484], ["github/Ruby", "rails/rails", "Ruby", 454649961, 454663448, 26725499, 26738986], ["tinystories/en", "TinyStories-valid", "en", 13258773, 13259198, 26739001, 26739426], ["github/Rust", "tokio-rs/tokio", "Rust", 343163122, 343183928, 26739441, 26760247], ["tinystories/en", "TinyStories-valid", "en", 280187, 280979, 26760262, 26761054], ["tinystories/en", "TinyStories-valid", "en", 3470078, 3470768, 26761069, 26761759], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 446517731, 446524232, 26761774, 26768275], ["tinystories/en", "TinyStories-valid", "en", 8977740, 8978427, 26768290, 26768977], ["github/Python", "django/django", "Python", 283264925, 283270919, 26768992, 26774986], ["github/JavaScript", "webpack/webpack", "JavaScript", 303383036, 303383762, 26775001, 26775727], ["tinystories/en", "TinyStories-valid", "en", 7411969, 7412950, 26775742, 26776723], ["github/Go", "gohugoio/hugo", "Go", 366196876, 366208690, 26776738, 26788552], ["tinystories/en", "TinyStories-valid", "en", 14312350, 14315479, 26788567, 26791696], ["github/JavaScript", "webpack/webpack", "JavaScript", 303854788, 303858770, 26791711, 26795693], ["github/Scala", "playframework/playframework", "Scala", 507441776, 507454010, 26795708, 26807942], ["github/Python", "scikit-learn/scikit-learn", "Python", 291787757, 291789894, 26807957, 26810094], ["tinystories/en", "TinyStories-valid", "en", 7822407, 7823150, 26810109, 26810852], ["github/TypeScript", "vuejs/core", "TypeScript", 320224023, 320241976, 26810867, 26828820], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481784857, 481801267, 26828835, 26845245], ["github/JavaScript", "expressjs/express", "JavaScript", 299557958, 299559151, 26845260, 26846453], ["github/Python", "scikit-learn/scikit-learn", "Python", 290984871, 290985285, 26846468, 26846882], ["tinystories/en", "TinyStories-valid", "en", 4686228, 4688241, 26846897, 26848910], ["github/JavaScript", "axios/axios", "JavaScript", 309206094, 309207178, 26848925, 26850009], ["tinystories/en", "TinyStories-valid", "en", 1216566, 1217211, 26850024, 26850669], ["github/PHP", "symfony/symfony", "PHP", 479432137, 479455851, 26850684, 26874398], ["github/Swift", "vapor/vapor", "Swift", 497387673, 497388772, 26874413, 26875512], ["tinystories/en", "TinyStories-valid", "en", 8930785, 8931782, 26875527, 26876524], ["books/en", "PG #76", "en", 64932753, 65523410, 26876539, 27467196], ["github/C#", "dotnet/aspnetcore", "C#", 441208200, 441216588, 27467198, 27475586], ["github/Scala", "sbt/sbt", "Scala", 519800194, 519800262, 27475601, 27475669], ["tinystories/en", "TinyStories-valid", "en", 3459194, 3459742, 27475684, 27476232], ["github/JavaScript", "webpack/webpack", "JavaScript", 306504121, 306507731, 27476247, 27479857], ["github/Scala", "sbt/sbt", "Scala", 516739938, 516740601, 27479872, 27480535], ["tinystories/en", "TinyStories-valid", "en", 6122051, 6122739, 27480550, 27481238], ["github/Scala", "playframework/playframework", "Scala", 511114566, 511114927, 27481253, 27481614], ["github/Scala", "playframework/playframework", "Scala", 511170206, 511171053, 27481629, 27482476], ["tinystories/en", "TinyStories-valid", "en", 8625676, 8626285, 27482491, 27483100], ["github/Ruby", "rails/rails", "Ruby", 453416158, 453416584, 27483115, 27483541], ["tinystories/en", "TinyStories-valid", "en", 10237602, 10238516, 27483556, 27484470], ["github/Scala", "scala/scala", "Scala", 503159072, 503160268, 27484485, 27485681], ["github/Go", "gohugoio/hugo", "Go", 372233551, 372238215, 27485696, 27490360], ["tinystories/en", "TinyStories-valid", "en", 15080510, 15081402, 27490375, 27491267], ["github/Ruby", "rails/rails", "Ruby", 454725173, 454726128, 27491282, 27492237], ["tinystories/en", "TinyStories-valid", "en", 18202711, 18203857, 27492252, 27493398], ["github/TypeScript", "nestjs/nest", "TypeScript", 332945666, 332945906, 27493413, 27493653], ["github/Scala", "playframework/playframework", "Scala", 508472366, 508477044, 27493668, 27498346], ["tinystories/en", "TinyStories-valid", "en", 18619310, 18620090, 27498361, 27499141], ["github/TypeScript", "angular/angular", "TypeScript", 330671277, 330673555, 27499156, 27501434], ["tinystories/en", "TinyStories-valid", "en", 10440414, 10441455, 27501449, 27502490], ["github/Ruby", "rails/rails", "Ruby", 458427388, 458429409, 27502505, 27504526], ["github/Python", "django/django", "Python", 288175540, 288194438, 27504541, 27523439], ["tinystories/en", "TinyStories-valid", "en", 15083149, 15084015, 27523454, 27524320], ["github/Scala", "sbt/sbt", "Scala", 519835926, 519835934, 27524335, 27524343], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485640423, 485640974, 27524358, 27524909], ["github/TypeScript", "angular/angular", "TypeScript", 326385617, 326386666, 27524924, 27525973], ["tinystories/en", "TinyStories-valid", "en", 4382253, 4382806, 27525988, 27526541], ["github/Scala", "playframework/playframework", "Scala", 512500844, 512502070, 27526556, 27527782], ["github/Rust", "rust-lang/cargo", "Rust", 349666828, 349682492, 27527797, 27543461], ["github/Go", "gohugoio/hugo", "Go", 366040647, 366045490, 27543476, 27548319], ["tinystories/en", "TinyStories-valid", "en", 2539238, 2539982, 27548334, 27549078], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 451342770, 451347840, 27549093, 27554163], ["github/Scala", "sbt/sbt", "Scala", 519806352, 519806407, 27554178, 27554233], ["github/TypeScript", "angular/angular", "TypeScript", 324776901, 324778748, 27554248, 27556095], ["tinystories/en", "TinyStories-valid", "en", 11483958, 11484667, 27556110, 27556819], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 482792081, 482794738, 27556834, 27559491], ["tinystories/en", "TinyStories-valid", "en", 7238231, 7239574, 27559506, 27560849], ["github/TypeScript", "angular/angular", "TypeScript", 324065637, 324067917, 27560864, 27563144], ["tinystories/en", "TinyStories-valid", "en", 17149640, 17150521, 27563159, 27564040], ["github/JavaScript", "expressjs/express", "JavaScript", 299879308, 299896585, 27564055, 27581332], ["github/PHP", "laravel/framework", "PHP", 464778193, 464779248, 27581347, 27582402], ["tinystories/en", "TinyStories-valid", "en", 11212312, 11213152, 27582417, 27583257], ["github/Go", "prometheus/prometheus", "Go", 357786159, 357787809, 27583272, 27584922], ["github/TypeScript", "nestjs/nest", "TypeScript", 337788263, 337788644, 27584937, 27585318], ["github/Ruby", "rails/rails", "Ruby", 459015311, 459019224, 27585333, 27589246], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485543530, 485545562, 27589261, 27591293], ["tinystories/en", "TinyStories-valid", "en", 12105190, 12106001, 27591308, 27592119], ["github/TypeScript", "nestjs/nest", "TypeScript", 332951738, 332953256, 27592134, 27593652], ["github/PHP", "symfony/symfony", "PHP", 475450413, 475452823, 27593667, 27596077], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 452425704, 452429128, 27596092, 27599516], ["github/Go", "gohugoio/hugo", "Go", 370152587, 370153827, 27599531, 27600771], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515221008, 515236186, 27600786, 27615964], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486825737, 486826201, 27615979, 27616443], ["github/TypeScript", "microsoft/vscode", "TypeScript", 319096010, 319096804, 27616458, 27617252], ["tinystories/en", "TinyStories-valid", "en", 4692994, 4695053, 27617267, 27619326], ["github/TypeScript", "angular/angular", "TypeScript", 324153346, 324153783, 27619341, 27619778], ["github/C", "curl/curl", "C", 378611365, 378653091, 27619793, 27661519], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491485823, 491487191, 27661534, 27662902], ["github/Go", "prometheus/prometheus", "Go", 359542269, 359543961, 27662917, 27664609], ["tinystories/en", "TinyStories-valid", "en", 7387908, 7388567, 27664624, 27665283], ["tinystories/en", "TinyStories-valid", "en", 6508972, 6509642, 27665298, 27665968], ["github/Ruby", "rails/rails", "Ruby", 457060587, 457061311, 27665983, 27666707], ["tinystories/en", "TinyStories-valid", "en", 8338307, 8339106, 27666722, 27667521], ["github/Rust", "tokio-rs/tokio", "Rust", 344777968, 344779945, 27667536, 27669513], ["github/Swift", "vapor/vapor", "Swift", 497583501, 497587969, 27669528, 27673996], ["github/TypeScript", "vuejs/core", "TypeScript", 320470340, 320475897, 27674011, 27679568], ["tinystories/en", "TinyStories-valid", "en", 8275368, 8276113, 27679583, 27680328], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 447055750, 447059431, 27680343, 27684024], ["tinystories/en", "TinyStories-valid", "en", 7514978, 7515651, 27684039, 27684712], ["github/Rust", "rust-lang/cargo", "Rust", 352989892, 352991329, 27684727, 27686164], ["github/PHP", "laravel/framework", "PHP", 467838086, 467847058, 27686179, 27695151], ["tinystories/en", "TinyStories-valid", "en", 3890878, 3891434, 27695166, 27695722], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491004415, 491008919, 27695737, 27700241], ["tinystories/en", "TinyStories-valid", "en", 5514475, 5515618, 27700256, 27701399], ["github/Python", "psf/requests", "Python", 281483590, 281489631, 27701414, 27707455], ["github/JavaScript", "webpack/webpack", "JavaScript", 300456593, 300456774, 27707470, 27707651], ["tinystories/en", "TinyStories-valid", "en", 5803164, 5803998, 27707666, 27708500], ["github/Go", "prometheus/prometheus", "Go", 361921421, 361929659, 27708515, 27716753], ["github/Rust", "BurntSushi/ripgrep", "Rust", 337993507, 337996494, 27716768, 27719755], ["github/Java", "square/okhttp", "Java", 429697831, 429758658, 27719770, 27780597], ["github/JavaScript", "webpack/webpack", "JavaScript", 305489788, 305492610, 27780612, 27783434], ["tinystories/en", "TinyStories-valid", "en", 596404, 597326, 27783449, 27784371], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 447045997, 447049176, 27784386, 27787565], ["tinystories/en", "TinyStories-valid", "en", 18307027, 18308207, 27787580, 27788760], ["github/Ruby", "rails/rails", "Ruby", 457627673, 457634054, 27788775, 27795156], ["github/JavaScript", "webpack/webpack", "JavaScript", 303251667, 303252917, 27795171, 27796421], ["github/C#", "dotnet/aspnetcore", "C#", 444036045, 444037254, 27796436, 27797645], ["tinystories/en", "TinyStories-valid", "en", 16620252, 16624087, 27797660, 27801495], ["github/Rust", "rust-lang/cargo", "Rust", 349136314, 349141268, 27801510, 27806464], ["github/JavaScript", "webpack/webpack", "JavaScript", 302431155, 302433085, 27806479, 27808409], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489187257, 489193206, 27808424, 27814373], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315021252, 315021775, 27814388, 27814911], ["github/C#", "dotnet/aspnetcore", "C#", 440497891, 440499123, 27814926, 27816158], ["tinystories/en", "TinyStories-valid", "en", 17676003, 17676827, 27816173, 27816997], ["books/fr", "PG #10982", "fr", 278506000, 278755601, 27817012, 28066613], ["github/C#", "dotnet/aspnetcore", "C#", 440954753, 440955139, 28066615, 28067001], ["tinystories/en", "TinyStories-valid", "en", 1388558, 1389363, 28067016, 28067821], ["github/C#", "dotnet/aspnetcore", "C#", 439247906, 439248703, 28067836, 28068633], ["tinystories/en", "TinyStories-valid", "en", 15106159, 15107011, 28068648, 28069500], ["github/Go", "gohugoio/hugo", "Go", 369488468, 369494459, 28069515, 28075506], ["github/TypeScript", "microsoft/vscode", "TypeScript", 318901259, 318920974, 28075521, 28095236], ["tinystories/en", "TinyStories-valid", "en", 10445756, 10446472, 28095251, 28095967], ["github/PHP", "laravel/framework", "PHP", 468375255, 468388040, 28095982, 28108767], ["github/Rust", "tokio-rs/tokio", "Rust", 341266107, 341270621, 28108782, 28113296], ["tinystories/en", "TinyStories-valid", "en", 16305988, 16306398, 28113311, 28113721], ["github/Python", "scikit-learn/scikit-learn", "Python", 298361177, 298375883, 28113736, 28128442], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316337103, 316345172, 28128457, 28136526], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 483723862, 483726549, 28136541, 28139228], ["tinystories/en", "TinyStories-valid", "en", 214442, 215865, 28139243, 28140666], ["github/Ruby", "rails/rails", "Ruby", 458964359, 458966131, 28140681, 28142453], ["github/C#", "dotnet/aspnetcore", "C#", 444422291, 444427021, 28142468, 28147198], ["tinystories/en", "TinyStories-valid", "en", 2023696, 2024788, 28147213, 28148305], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485835972, 485836443, 28148320, 28148791], ["tinystories/en", "TinyStories-valid", "en", 2922937, 2923601, 28148806, 28149470], ["tinystories/en", "TinyStories-valid", "en", 10800877, 10801705, 28149485, 28150313], ["github/Ruby", "rails/rails", "Ruby", 453420981, 453422617, 28150328, 28151964], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485939086, 485940969, 28151979, 28153862], ["tinystories/en", "TinyStories-valid", "en", 18492480, 18493084, 28153877, 28154481], ["tinystories/en", "TinyStories-valid", "en", 8356342, 8356999, 28154496, 28155153], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449612609, 449614083, 28155168, 28156642], ["tinystories/en", "TinyStories-valid", "en", 17150536, 17151209, 28156657, 28157330], ["github/Scala", "sbt/sbt", "Scala", 520484195, 520546744, 28157345, 28219894], ["tinystories/en", "TinyStories-valid", "en", 5859428, 5860131, 28219909, 28220612], ["github/Kotlin", "ktorio/ktor", "Kotlin", 495776686, 495778473, 28220627, 28222414], ["tinystories/en", "TinyStories-valid", "en", 16325185, 16325977, 28222429, 28223221], ["github/Rust", "BurntSushi/ripgrep", "Rust", 338018231, 338029375, 28223236, 28234380], ["tinystories/en", "TinyStories-valid", "en", 13996505, 13997059, 28234395, 28234949], ["github/PHP", "symfony/symfony", "PHP", 476858247, 476861745, 28234964, 28238462], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 484855145, 484855627, 28238477, 28238959], ["tinystories/en", "TinyStories-valid", "en", 9247432, 9248091, 28238974, 28239633], ["books/en", "PG #163", "en", 112606432, 112795220, 28239648, 28428436], ["github/TypeScript", "angular/angular", "TypeScript", 326040413, 326041498, 28428438, 28429523], ["github/Ruby", "rails/rails", "Ruby", 457128693, 457131962, 28429538, 28432807], ["tinystories/en", "TinyStories-valid", "en", 12185176, 12185878, 28432822, 28433524], ["tinystories/en", "TinyStories-valid", "en", 1027751, 1028228, 28433539, 28434016], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489176729, 489179322, 28434031, 28436624], ["github/Python", "django/django", "Python", 286141200, 286145916, 28436639, 28441355], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 451501781, 451508162, 28441370, 28447751], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 313192578, 313204214, 28447766, 28459402], ["tinystories/en", "TinyStories-valid", "en", 14915131, 14916882, 28459417, 28461168], ["tinystories/en", "TinyStories-valid", "en", 578059, 578949, 28461183, 28462073], ["github/TypeScript", "vuejs/core", "TypeScript", 323739167, 323744808, 28462088, 28467729], ["tinystories/en", "TinyStories-valid", "en", 3064821, 3065322, 28467744, 28468245], ["github/Python", "django/django", "Python", 283010924, 283011270, 28468260, 28468606], ["github/Ruby", "rails/rails", "Ruby", 456080389, 456081584, 28468621, 28469816], ["tinystories/en", "TinyStories-valid", "en", 5757980, 5758552, 28469831, 28470403], ["github/Python", "django/django", "Python", 288936974, 288937791, 28470418, 28471235], ["tinystories/en", "TinyStories-valid", "en", 19000292, 19000677, 28471250, 28471635], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491373678, 491377250, 28471650, 28475222], ["github/Python", "scikit-learn/scikit-learn", "Python", 291043883, 291044554, 28475237, 28475908], ["tinystories/en", "TinyStories-valid", "en", 13494753, 13495543, 28475923, 28476713], ["github/Python", "scikit-learn/scikit-learn", "Python", 290972734, 290973539, 28476728, 28477533], ["tinystories/en", "TinyStories-valid", "en", 5686236, 5686866, 28477548, 28478178], ["tinystories/en", "TinyStories-valid", "en", 2329357, 2330277, 28478193, 28479113], ["github/Java", "square/okhttp", "Java", 427132982, 427147520, 28479128, 28493666], ["github/Python", "scikit-learn/scikit-learn", "Python", 294079650, 294080569, 28493681, 28494600], ["github/Rust", "rust-lang/cargo", "Rust", 346869266, 346874447, 28494615, 28499796], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494842088, 494842389, 28499811, 28500112], ["tinystories/en", "TinyStories-valid", "en", 6939965, 6940584, 28500127, 28500746], ["tinystories/en", "TinyStories-valid", "en", 14678599, 14679354, 28500761, 28501516], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 487119950, 487121090, 28501531, 28502671], ["github/C#", "dotnet/aspnetcore", "C#", 441998174, 442003347, 28502686, 28507859], ["github/PHP", "laravel/framework", "PHP", 468656825, 468672414, 28507874, 28523463], ["tinystories/en", "TinyStories-valid", "en", 5115957, 5116889, 28523478, 28524410], ["github/C", "curl/curl", "C", 379583578, 379587621, 28524425, 28528468], ["github/Python", "scikit-learn/scikit-learn", "Python", 291460489, 291464984, 28528483, 28532978], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 317076690, 317080863, 28532993, 28537166], ["tinystories/en", "TinyStories-valid", "en", 4866936, 4867752, 28537181, 28537997], ["github/Ruby", "rails/rails", "Ruby", 459440443, 459445224, 28538012, 28542793], ["github/Rust", "tokio-rs/tokio", "Rust", 344542776, 344543208, 28542808, 28543240], ["github/TypeScript", "angular/angular", "TypeScript", 329332439, 329342024, 28543255, 28552840], ["tinystories/en", "TinyStories-valid", "en", 13306296, 13306723, 28552855, 28553282], ["github/Rust", "rust-lang/cargo", "Rust", 352859162, 352860368, 28553297, 28554503], ["tinystories/en", "TinyStories-valid", "en", 3700298, 3700948, 28554518, 28555168], ["github/Rust", "serde-rs/serde", "Rust", 346867632, 346867837, 28555183, 28555388], ["tinystories/en", "TinyStories-valid", "en", 13144578, 13145337, 28555403, 28556162], ["github/JavaScript", "webpack/webpack", "JavaScript", 300426187, 300426835, 28556177, 28556825], ["github/Java", "apache/commons-lang", "Java", 435636446, 435638516, 28556840, 28558910], ["github/Swift", "vapor/vapor", "Swift", 497424724, 497430720, 28558925, 28564921], ["github/Python", "django/django", "Python", 282396254, 282396976, 28564936, 28565658], ["tinystories/en", "TinyStories-valid", "en", 4521968, 4522810, 28565673, 28566515], ["github/JavaScript", "webpack/webpack", "JavaScript", 300557824, 300557881, 28566530, 28566587], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491692406, 491698072, 28566602, 28572268], ["github/Rust", "alacritty/alacritty", "Rust", 355760483, 355763011, 28572283, 28574811], ["github/Python", "django/django", "Python", 282764094, 282764771, 28574826, 28575503], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315156174, 315157217, 28575518, 28576561], ["github/C#", "dotnet/aspnetcore", "C#", 445999904, 446002329, 28576576, 28579001], ["tinystories/en", "TinyStories-valid", "en", 14687275, 14688009, 28579016, 28579750], ["tinystories/en", "TinyStories-valid", "en", 7878529, 7879345, 28579765, 28580581], ["github/C", "curl/curl", "C", 379507307, 379510086, 28580596, 28583375], ["github/Java", "google/guava", "Java", 413961950, 413966273, 28583390, 28587713], ["tinystories/en", "TinyStories-valid", "en", 7647909, 7648638, 28587728, 28588457], ["github/TypeScript", "nestjs/nest", "TypeScript", 332429084, 332429465, 28588472, 28588853], ["github/Rust", "tokio-rs/tokio", "Rust", 341650666, 341652286, 28588868, 28590488], ["tinystories/en", "TinyStories-valid", "en", 15238581, 15239697, 28590503, 28591619], ["github/Ruby", "rails/rails", "Ruby", 453180047, 453181667, 28591634, 28593254], ["github/C#", "dotnet/aspnetcore", "C#", 445019107, 445021497, 28593269, 28595659], ["github/TypeScript", "nestjs/nest", "TypeScript", 332531267, 332533513, 28595674, 28597920], ["github/Java", "spring-projects/spring-framework", "Java", 420248025, 420250092, 28597935, 28600002], ["github/PHP", "laravel/framework", "PHP", 468067932, 468068447, 28600017, 28600532], ["tinystories/en", "TinyStories-valid", "en", 2492084, 2493138, 28600547, 28601601], ["github/C++", "protocolbuffers/protobuf", "C++", 400856149, 401050312, 28601616, 28795779], ["github/TypeScript", "nestjs/nest", "TypeScript", 333677767, 333678454, 28795794, 28796481], ["tinystories/en", "TinyStories-valid", "en", 8900977, 8901772, 28796496, 28797291], ["github/PHP", "symfony/symfony", "PHP", 474945720, 474947995, 28797306, 28799581], ["tinystories/en", "TinyStories-valid", "en", 15791317, 15792156, 28799596, 28800435], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485981839, 485985253, 28800450, 28803864], ["tinystories/en", "TinyStories-valid", "en", 12775912, 12776790, 28803879, 28804757], ["github/Ruby", "rails/rails", "Ruby", 453245481, 453247236, 28804772, 28806527], ["github/PHP", "symfony/symfony", "PHP", 476003636, 476004568, 28806542, 28807474], ["tinystories/en", "TinyStories-valid", "en", 3551964, 3552528, 28807489, 28808053], ["github/Java", "apache/commons-lang", "Java", 433593222, 433602201, 28808068, 28817047], ["tinystories/en", "TinyStories-valid", "en", 19234568, 19235220, 28817062, 28817714], ["tinystories/en", "TinyStories-valid", "en", 9897011, 9897730, 28817729, 28818448], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 451521262, 451527272, 28818463, 28824473], ["github/Ruby", "rails/rails", "Ruby", 456303569, 456304102, 28824488, 28825021], ["github/PHP", "symfony/symfony", "PHP", 475956454, 475960231, 28825036, 28828813], ["tinystories/en", "TinyStories-valid", "en", 17474939, 17475970, 28828828, 28829859], ["tinystories/en", "TinyStories-valid", "en", 10556401, 10557021, 28829874, 28830494], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492808309, 492812028, 28830509, 28834228], ["github/TypeScript", "nestjs/nest", "TypeScript", 335963487, 335975107, 28834243, 28845863], ["tinystories/en", "TinyStories-valid", "en", 6140973, 6143051, 28845878, 28847956], ["github/PHP", "symfony/symfony", "PHP", 478615807, 478616947, 28847971, 28849111], ["github/PHP", "laravel/framework", "PHP", 465155420, 465155775, 28849126, 28849481], ["github/C#", "dotnet/aspnetcore", "C#", 443940650, 443941197, 28849496, 28850043], ["github/Java", "square/okhttp", "Java", 429455691, 429463595, 28850058, 28857962], ["tinystories/en", "TinyStories-valid", "en", 6310501, 6311408, 28857977, 28858884], ["github/JavaScript", "webpack/webpack", "JavaScript", 302773082, 302797470, 28858899, 28883287], ["tinystories/en", "TinyStories-valid", "en", 14159548, 14160679, 28883302, 28884433], ["github/PHP", "laravel/framework", "PHP", 468428090, 468431047, 28884448, 28887405], ["tinystories/en", "TinyStories-valid", "en", 5043158, 5044272, 28887420, 28888534], ["github/Java", "square/okhttp", "Java", 427856524, 427857690, 28888549, 28889715], ["tinystories/en", "TinyStories-valid", "en", 15599771, 15600424, 28889730, 28890383], ["github/Kotlin", "ktorio/ktor", "Kotlin", 493350313, 493355634, 28890398, 28895719], ["github/Scala", "scala/scala", "Scala", 505480993, 505488106, 28895734, 28902847], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 447365990, 447370957, 28902862, 28907829], ["github/TypeScript", "nestjs/nest", "TypeScript", 335906126, 335906899, 28907844, 28908617], ["github/Java", "spring-projects/spring-framework", "Java", 418096313, 418097257, 28908632, 28909576], ["github/C", "curl/curl", "C", 376351942, 376369924, 28909591, 28927573], ["github/PHP", "guzzle/guzzle", "PHP", 479922422, 479924513, 28927588, 28929679], ["tinystories/en", "TinyStories-valid", "en", 7349557, 7351589, 28929694, 28931726], ["books/en", "PG #222", "en", 138730083, 139143018, 28931741, 29344676], ["github/Java", "google/guava", "Java", 415950836, 415954579, 29344678, 29348421], ["github/TypeScript", "nestjs/nest", "TypeScript", 332826697, 332830353, 29348436, 29352092], ["tinystories/en", "TinyStories-valid", "en", 12874237, 12875033, 29352107, 29352903], ["github/PHP", "symfony/symfony", "PHP", 475905765, 475907481, 29352918, 29354634], ["tinystories/en", "TinyStories-valid", "en", 15342851, 15344314, 29354649, 29356112], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491301395, 491302366, 29356127, 29357098], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449781892, 449783167, 29357113, 29358388], ["github/PHP", "laravel/framework", "PHP", 470792776, 470794557, 29358403, 29360184], ["tinystories/en", "TinyStories-valid", "en", 1611293, 1612001, 29360199, 29360907], ["github/TypeScript", "angular/angular", "TypeScript", 326276752, 326278392, 29360922, 29362562], ["github/Ruby", "rails/rails", "Ruby", 453181682, 453193996, 29362577, 29374891], ["github/PHP", "laravel/framework", "PHP", 466655546, 466655844, 29374906, 29375204], ["github/Scala", "playframework/playframework", "Scala", 508089054, 508093933, 29375219, 29380098], ["tinystories/en", "TinyStories-valid", "en", 10505769, 10506591, 29380113, 29380935], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 482275922, 482277676, 29380950, 29382704], ["github/TypeScript", "nestjs/nest", "TypeScript", 333194872, 333195795, 29382719, 29383642], ["tinystories/en", "TinyStories-valid", "en", 5283496, 5284570, 29383657, 29384731], ["github/TypeScript", "angular/angular", "TypeScript", 324104228, 324104514, 29384746, 29385032], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 448905541, 448909057, 29385047, 29388563], ["tinystories/en", "TinyStories-valid", "en", 18383269, 18383898, 29388578, 29389207], ["github/Python", "scikit-learn/scikit-learn", "Python", 297963502, 298007823, 29389222, 29433543], ["github/PHP", "laravel/framework", "PHP", 469328364, 469332214, 29433558, 29437408], ["github/Scala", "sbt/sbt", "Scala", 519868608, 519868647, 29437423, 29437462], ["github/TypeScript", "angular/angular", "TypeScript", 327318808, 327320613, 29437477, 29439282], ["tinystories/en", "TinyStories-valid", "en", 4130491, 4131199, 29439297, 29440005], ["github/Java", "spring-projects/spring-framework", "Java", 419545143, 419561602, 29440020, 29456479], ["tinystories/en", "TinyStories-valid", "en", 3924095, 3924904, 29456494, 29457303], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481546023, 481549428, 29457318, 29460723], ["tinystories/en", "TinyStories-valid", "en", 9070189, 9071096, 29460738, 29461645], ["github/JavaScript", "axios/axios", "JavaScript", 308838624, 308838698, 29461660, 29461734], ["github/C#", "dotnet/aspnetcore", "C#", 442326923, 442328285, 29461749, 29463111], ["tinystories/en", "TinyStories-valid", "en", 2220180, 2220777, 29463126, 29463723], ["github/PHP", "symfony/symfony", "PHP", 476706134, 476707885, 29463738, 29465489], ["tinystories/en", "TinyStories-valid", "en", 4207413, 4208176, 29465504, 29466267], ["github/TypeScript", "angular/angular", "TypeScript", 326257928, 326263563, 29466282, 29471917], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481505721, 481506550, 29471932, 29472761], ["tinystories/en", "TinyStories-valid", "en", 102387, 103096, 29472776, 29473485], ["github/JavaScript", "webpack/webpack", "JavaScript", 302524039, 302527757, 29473500, 29477218], ["github/Rust", "serde-rs/serde", "Rust", 345985842, 346034690, 29477233, 29526081], ["github/Kotlin", "ktorio/ktor", "Kotlin", 489453878, 489454249, 29526096, 29526467], ["tinystories/en", "TinyStories-valid", "en", 17015774, 17016659, 29526482, 29527367], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491504890, 491505630, 29527382, 29528122], ["tinystories/en", "TinyStories-valid", "en", 3848157, 3849037, 29528137, 29529017], ["github/Scala", "playframework/playframework", "Scala", 511396357, 511408999, 29529032, 29541674], ["github/TypeScript", "nestjs/nest", "TypeScript", 333621610, 333621850, 29541689, 29541929], ["tinystories/en", "TinyStories-valid", "en", 12393541, 12394435, 29541944, 29542838], ["github/TypeScript", "nestjs/nest", "TypeScript", 334333429, 334333631, 29542853, 29543055], ["github/TypeScript", "nestjs/nest", "TypeScript", 332769386, 332769414, 29543070, 29543098], ["github/Java", "spring-projects/spring-framework", "Java", 424110106, 424111457, 29543113, 29544464], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 310105172, 310107042, 29544479, 29546349], ["github/TypeScript", "angular/angular", "TypeScript", 325881698, 325882863, 29546364, 29547529], ["tinystories/en", "TinyStories-valid", "en", 9098991, 9099829, 29547544, 29548382], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 482137878, 482140392, 29548397, 29550911], ["github/Java", "google/guava", "Java", 413481503, 413482827, 29550926, 29552250], ["github/JavaScript", "axios/axios", "JavaScript", 309259926, 309260020, 29552265, 29552359], ["tinystories/en", "TinyStories-valid", "en", 11258437, 11259061, 29552374, 29552998], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315323708, 315324695, 29553013, 29554000], ["github/TypeScript", "microsoft/vscode", "TypeScript", 319190129, 319192201, 29554015, 29556087], ["tinystories/en", "TinyStories-valid", "en", 4483116, 4483929, 29556102, 29556915], ["tinystories/en", "TinyStories-valid", "en", 920143, 920976, 29556930, 29557763], ["github/Java", "square/okhttp", "Java", 426689911, 426695784, 29557778, 29563651], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 487005886, 487007405, 29563666, 29565185], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315050452, 315052977, 29565200, 29567725], ["tinystories/en", "TinyStories-valid", "en", 16192716, 16193382, 29567740, 29568406], ["github/PHP", "symfony/symfony", "PHP", 471918737, 471932454, 29568421, 29582138], ["tinystories/en", "TinyStories-valid", "en", 14341046, 14342625, 29582153, 29583732], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486322957, 486323598, 29583747, 29584388], ["github/Scala", "scala/scala", "Scala", 505659482, 505660077, 29584403, 29584998], ["github/C#", "dotnet/aspnetcore", "C#", 441276829, 441291036, 29585013, 29599220], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 310184346, 310185932, 29599235, 29600821], ["github/Java", "spring-projects/spring-framework", "Java", 417897668, 417899272, 29600836, 29602440], ["tinystories/en", "TinyStories-valid", "en", 1528794, 1529585, 29602455, 29603246], ["tinystories/en", "TinyStories-valid", "en", 4143523, 4144103, 29603261, 29603841], ["github/TypeScript", "angular/angular", "TypeScript", 325498667, 325506814, 29603856, 29612003], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485082545, 485085697, 29612018, 29615170], ["github/Swift", "vapor/vapor", "Swift", 497156457, 497162061, 29615185, 29620789], ["tinystories/en", "TinyStories-valid", "en", 12515389, 12516201, 29620804, 29621616], ["github/Java", "spring-projects/spring-framework", "Java", 421034582, 421039657, 29621631, 29626706], ["tinystories/en", "TinyStories-valid", "en", 11145662, 11146528, 29626721, 29627587], ["tinystories/en", "TinyStories-valid", "en", 6694438, 6694823, 29627602, 29627987], ["github/JavaScript", "webpack/webpack", "JavaScript", 308111088, 308115656, 29628002, 29632570], ["tinystories/en", "TinyStories-valid", "en", 2627149, 2627976, 29632585, 29633412], ["github/Ruby", "rails/rails", "Ruby", 453870065, 453877747, 29633427, 29641109], ["tinystories/en", "TinyStories-valid", "en", 4341391, 4342210, 29641124, 29641943], ["github/Java", "square/okhttp", "Java", 430410415, 430413598, 29641958, 29645141], ["github/TypeScript", "nestjs/nest", "TypeScript", 332749040, 332749293, 29645156, 29645409], ["tinystories/en", "TinyStories-valid", "en", 7681420, 7682142, 29645424, 29646146], ["github/PHP", "symfony/symfony", "PHP", 478575057, 478575597, 29646161, 29646701], ["github/JavaScript", "webpack/webpack", "JavaScript", 300502513, 300502714, 29646716, 29646917], ["tinystories/en", "TinyStories-valid", "en", 6793542, 6794175, 29646932, 29647565], ["github/Java", "apache/commons-lang", "Java", 436134814, 436136115, 29647580, 29648881], ["tinystories/en", "TinyStories-valid", "en", 2034721, 2035607, 29648896, 29649782], ["github/JavaScript", "webpack/webpack", "JavaScript", 303422321, 303425041, 29649797, 29652517], ["tinystories/en", "TinyStories-valid", "en", 17111591, 17112274, 29652532, 29653215], ["github/Java", "spring-projects/spring-framework", "Java", 423642037, 423644038, 29653230, 29655231], ["github/C", "curl/curl", "C", 375812257, 375831093, 29655246, 29674082], ["tinystories/en", "TinyStories-valid", "en", 11097875, 11098681, 29674097, 29674903], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 483637625, 483645136, 29674918, 29682429], ["tinystories/en", "TinyStories-valid", "en", 12451663, 12452266, 29682444, 29683047], ["tinystories/en", "TinyStories-valid", "en", 263768, 264618, 29683062, 29683912], ["tinystories/en", "TinyStories-valid", "en", 3666264, 3667106, 29683927, 29684769], ["tinystories/en", "TinyStories-valid", "en", 17769924, 17772134, 29684784, 29686994], ["github/C#", "dotnet/aspnetcore", "C#", 445581111, 445587360, 29687009, 29693258], ["github/JavaScript", "webpack/webpack", "JavaScript", 302594975, 302603139, 29693273, 29701437], ["github/Java", "google/guava", "Java", 409970221, 409983771, 29701452, 29715002], ["github/Python", "django/django", "Python", 286061273, 286066001, 29715017, 29719745], ["tinystories/en", "TinyStories-valid", "en", 13109922, 13110364, 29719760, 29720202], ["tinystories/en", "TinyStories-valid", "en", 15887532, 15888264, 29720217, 29720949], ["github/Ruby", "sinatra/sinatra", "Ruby", 462665958, 462668292, 29720964, 29723298], ["tinystories/en", "TinyStories-valid", "en", 10514457, 10515098, 29723313, 29723954], ["tinystories/en", "TinyStories-valid", "en", 6761253, 6762089, 29723969, 29724805], ["github/Python", "django/django", "Python", 287435631, 287436638, 29724820, 29725827], ["tinystories/en", "TinyStories-valid", "en", 2355975, 2356782, 29725842, 29726649], ["github/C#", "dotnet/aspnetcore", "C#", 442265365, 442265830, 29726664, 29727129], ["tinystories/en", "TinyStories-valid", "en", 3534857, 3535582, 29727144, 29727869], ["tinystories/en", "TinyStories-valid", "en", 15946890, 15947488, 29727884, 29728482], ["github/JavaScript", "webpack/webpack", "JavaScript", 308521056, 308523320, 29728497, 29730761], ["github/C#", "dotnet/aspnetcore", "C#", 444147323, 444149053, 29730776, 29732506], ["tinystories/en", "TinyStories-valid", "en", 1252594, 1253465, 29732521, 29733392], ["github/Java", "square/okhttp", "Java", 426299472, 426302852, 29733407, 29736787], ["tinystories/en", "TinyStories-valid", "en", 3821107, 3821909, 29736802, 29737604], ["github/Java", "spring-projects/spring-framework", "Java", 419597397, 419598105, 29737619, 29738327], ["github/PHP", "laravel/framework", "PHP", 464488631, 464516127, 29738342, 29765838], ["tinystories/en", "TinyStories-valid", "en", 19334380, 19335336, 29765853, 29766809], ["github/Kotlin", "square/kotlinpoet", "Kotlin", 483462073, 483473355, 29766824, 29778106], ["github/JavaScript", "webpack/webpack", "JavaScript", 300426850, 300429764, 29778121, 29781035], ["github/Java", "spring-projects/spring-framework", "Java", 424446437, 424448975, 29781050, 29783588], ["tinystories/en", "TinyStories-valid", "en", 7240405, 7241980, 29783603, 29785178], ["github/C#", "dotnet/aspnetcore", "C#", 446260349, 446264172, 29785193, 29789016], ["github/Scala", "sbt/sbt", "Scala", 519098783, 519147604, 29789031, 29837852], ["tinystories/en", "TinyStories-valid", "en", 7551991, 7552578, 29837867, 29838454], ["github/JavaScript", "webpack/webpack", "JavaScript", 308466010, 308466166, 29838469, 29838625], ["github/C", "curl/curl", "C", 375104359, 375106035, 29838640, 29840316], ["tinystories/en", "TinyStories-valid", "en", 72646, 73426, 29840331, 29841111], ["github/Java", "google/guava", "Java", 412193529, 412197660, 29841126, 29845257], ["tinystories/en", "TinyStories-valid", "en", 6744241, 6744912, 29845272, 29845943], ["tinystories/en", "TinyStories-valid", "en", 12836500, 12837112, 29845958, 29846570], ["github/C#", "dotnet/aspnetcore", "C#", 439234464, 439235332, 29846585, 29847453], ["books/en", "PG #111", "en", 86272397, 86721962, 29847468, 30297033], ["tinystories/en", "TinyStories-valid", "en", 16716991, 16718439, 30297035, 30298483], ["github/Java", "spring-projects/spring-framework", "Java", 425970253, 425972959, 30298498, 30301204], ["tinystories/en", "TinyStories-valid", "en", 7530972, 7531669, 30301219, 30301916], ["github/Go", "prometheus/prometheus", "Go", 363866893, 364008560, 30301931, 30443598], ["github/Ruby", "rails/rails", "Ruby", 460863987, 460875413, 30443613, 30455039], ["github/Java", "spring-projects/spring-framework", "Java", 425618118, 425621358, 30455054, 30458294], ["tinystories/en", "TinyStories-valid", "en", 6210006, 6211752, 30458309, 30460055], ["github/Java", "google/guava", "Java", 409958554, 409959544, 30460070, 30461060], ["tinystories/en", "TinyStories-valid", "en", 3007801, 3008478, 30461075, 30461752], ["github/Python", "scikit-learn/scikit-learn", "Python", 294614417, 294638581, 30461767, 30485931], ["github/TypeScript", "angular/angular", "TypeScript", 327197393, 327247512, 30485946, 30536065], ["tinystories/en", "TinyStories-valid", "en", 18766094, 18767010, 30536080, 30536996], ["github/Kotlin", "ktorio/ktor", "Kotlin", 488089788, 488093030, 30537011, 30540253], ["tinystories/en", "TinyStories-valid", "en", 9891607, 9892117, 30540268, 30540778], ["github/Java", "spring-projects/spring-framework", "Java", 420590511, 420596033, 30540793, 30546315], ["tinystories/en", "TinyStories-valid", "en", 7131815, 7132589, 30546330, 30547104], ["tinystories/en", "TinyStories-valid", "en", 4034771, 4035515, 30547119, 30547863], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449081692, 449092288, 30547878, 30558474], ["tinystories/en", "TinyStories-valid", "en", 5649089, 5649662, 30558489, 30559062], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485587107, 485587883, 30559077, 30559853], ["tinystories/en", "TinyStories-valid", "en", 19455485, 19456040, 30559868, 30560423], ["github/Java", "spring-projects/spring-framework", "Java", 419585296, 419586461, 30560438, 30561603], ["tinystories/en", "TinyStories-valid", "en", 7692406, 7692947, 30561618, 30562159], ["github/Java", "square/okhttp", "Java", 427804432, 427805559, 30562174, 30563301], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486503579, 486505334, 30563316, 30565071], ["tinystories/en", "TinyStories-valid", "en", 19459445, 19460080, 30565086, 30565721], ["github/PHP", "symfony/symfony", "PHP", 472270956, 472271416, 30565736, 30566196], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315687924, 315710765, 30566211, 30589052], ["github/C", "libuv/libuv", "C", 381414423, 381428472, 30589067, 30603116], ["tinystories/en", "TinyStories-valid", "en", 2692291, 2693200, 30603131, 30604040], ["github/Java", "square/okhttp", "Java", 426609639, 426612957, 30604055, 30607373], ["tinystories/en", "TinyStories-valid", "en", 4312385, 4313010, 30607388, 30608013], ["tinystories/en", "TinyStories-valid", "en", 1467589, 1468408, 30608028, 30608847], ["github/Java", "spring-projects/spring-framework", "Java", 417935000, 417935911, 30608862, 30609773], ["tinystories/en", "TinyStories-valid", "en", 7025580, 7026514, 30609788, 30610722], ["github/Java", "spring-projects/spring-framework", "Java", 420931818, 420933453, 30610737, 30612372], ["tinystories/en", "TinyStories-valid", "en", 19462994, 19464181, 30612387, 30613574], ["github/Java", "square/okhttp", "Java", 426378932, 426379700, 30613589, 30614357], ["github/PHP", "laravel/framework", "PHP", 467023797, 467032138, 30614372, 30622713], ["github/Ruby", "rails/rails", "Ruby", 453243046, 453243325, 30622728, 30623007], ["github/C#", "dotnet/aspnetcore", "C#", 444816372, 444816874, 30623022, 30623524], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492168513, 492174825, 30623539, 30629851], ["github/Java", "square/okhttp", "Java", 427131318, 427132967, 30629866, 30631515], ["github/Ruby", "rails/rails", "Ruby", 456157671, 456157990, 30631530, 30631849], ["tinystories/en", "TinyStories-valid", "en", 14282001, 14283054, 30631864, 30632917], ["github/Java", "spring-projects/spring-framework", "Java", 418106621, 418107395, 30632932, 30633706], ["tinystories/en", "TinyStories-valid", "en", 280994, 281428, 30633721, 30634155], ["tinystories/en", "TinyStories-valid", "en", 11090387, 11091177, 30634170, 30634960], ["github/Java", "spring-projects/spring-framework", "Java", 422643896, 422646840, 30634975, 30637919], ["tinystories/en", "TinyStories-valid", "en", 10528116, 10529023, 30637934, 30638841], ["github/C#", "dotnet/aspnetcore", "C#", 438559885, 438564273, 30638856, 30643244], ["github/Python", "django/django", "Python", 282401533, 282402853, 30643259, 30644579], ["tinystories/en", "TinyStories-valid", "en", 8324053, 8324772, 30644594, 30645313], ["tinystories/en", "TinyStories-valid", "en", 3268163, 3269241, 30645328, 30646406], ["tinystories/en", "TinyStories-valid", "en", 3647437, 3648118, 30646421, 30647102], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492164641, 492166445, 30647117, 30648921], ["github/Java", "google/guava", "Java", 414343310, 414350173, 30648936, 30655799], ["tinystories/en", "TinyStories-valid", "en", 15098543, 15099058, 30655814, 30656329], ["github/Scala", "playframework/playframework", "Scala", 507578327, 507579512, 30656344, 30657529], ["tinystories/en", "TinyStories-valid", "en", 4935563, 4936341, 30657544, 30658322], ["github/C++", "nlohmann/json", "C++", 385373793, 385374786, 30658337, 30659330], ["tinystories/en", "TinyStories-valid", "en", 571240, 572096, 30659345, 30660201], ["github/C++", "opencv/opencv", "C++", 398209723, 398210858, 30660216, 30661351], ["github/JavaScript", "webpack/webpack", "JavaScript", 300461858, 300462981, 30661366, 30662489], ["tinystories/en", "TinyStories-valid", "en", 2225780, 2226521, 30662504, 30663245], ["github/JavaScript", "webpack/webpack", "JavaScript", 300467398, 300467453, 30663260, 30663315], ["github/JavaScript", "axios/axios", "JavaScript", 309442255, 309442575, 30663330, 30663650], ["tinystories/en", "TinyStories-valid", "en", 10844794, 10845458, 30663665, 30664329], ["github/PHP", "laravel/framework", "PHP", 468945834, 468955201, 30664344, 30673711], ["github/Java", "spring-projects/spring-framework", "Java", 421277277, 421280103, 30673726, 30676552], ["tinystories/en", "TinyStories-valid", "en", 8978442, 8979060, 30676567, 30677185], ["github/C#", "dotnet/aspnetcore", "C#", 443860679, 443866957, 30677200, 30683478], ["tinystories/en", "TinyStories-valid", "en", 12694757, 12695704, 30683493, 30684440], ["github/Java", "square/okhttp", "Java", 426108935, 426110191, 30684455, 30685711], ["github/JavaScript", "expressjs/express", "JavaScript", 299659201, 299663010, 30685726, 30689535], ["tinystories/en", "TinyStories-valid", "en", 17438558, 17439078, 30689550, 30690070], ["github/Java", "spring-projects/spring-framework", "Java", 417759137, 417760421, 30690085, 30691369], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492492256, 492499440, 30691384, 30698568], ["github/Java", "spring-projects/spring-framework", "Java", 417915555, 417916488, 30698583, 30699516], ["books/fr", "PG #10953", "fr", 277929305, 278505998, 30699531, 31276224], ["tinystories/en", "TinyStories-valid", "en", 230628, 232319, 31276226, 31277917], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515346887, 515347349, 31277932, 31278394], ["tinystories/en", "TinyStories-valid", "en", 456244, 457184, 31278409, 31279349], ["tinystories/en", "TinyStories-valid", "en", 6737622, 6738312, 31279364, 31280054], ["github/TypeScript", "nestjs/nest", "TypeScript", 337943047, 337943143, 31280069, 31280165], ["github/Python", "scikit-learn/scikit-learn", "Python", 298031416, 298051840, 31280180, 31300604], ["tinystories/en", "TinyStories-valid", "en", 4501396, 4502445, 31300619, 31301668], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 447526903, 447529007, 31301683, 31303787], ["github/PHP", "symfony/symfony", "PHP", 478684153, 478687795, 31303802, 31307444], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 313298583, 313304024, 31307459, 31312900], ["tinystories/en", "TinyStories-valid", "en", 4459524, 4460685, 31312915, 31314076], ["github/C", "curl/curl", "C", 373730921, 373744946, 31314091, 31328116], ["tinystories/en", "TinyStories-valid", "en", 10732468, 10733750, 31328131, 31329413], ["github/Ruby", "jekyll/jekyll", "Ruby", 461696186, 461713987, 31329428, 31347229], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492091884, 492095108, 31347244, 31350468], ["github/Rust", "rust-lang/cargo", "Rust", 353966368, 354043461, 31350483, 31427576], ["tinystories/en", "TinyStories-valid", "en", 15872369, 15873213, 31427591, 31428435], ["github/Java", "google/guava", "Java", 411655092, 411674760, 31428450, 31448118], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315165870, 315166842, 31448133, 31449105], ["github/PHP", "symfony/symfony", "PHP", 477709859, 477712913, 31449120, 31452174], ["tinystories/en", "TinyStories-valid", "en", 15802518, 15803065, 31452189, 31452736], ["github/JavaScript", "axios/axios", "JavaScript", 309068399, 309068703, 31452751, 31453055], ["github/JavaScript", "webpack/webpack", "JavaScript", 300435190, 300435562, 31453070, 31453442], ["tinystories/en", "TinyStories-valid", "en", 2416123, 2417245, 31453457, 31454579], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486327281, 486327752, 31454594, 31455065], ["tinystories/en", "TinyStories-valid", "en", 2668340, 2669100, 31455080, 31455840], ["github/C#", "dotnet/aspnetcore", "C#", 445497892, 445505919, 31455855, 31463882], ["tinystories/en", "TinyStories-valid", "en", 16854910, 16855630, 31463897, 31464617], ["github/PHP", "laravel/framework", "PHP", 470789833, 470792761, 31464632, 31467560], ["tinystories/en", "TinyStories-valid", "en", 15135478, 15136242, 31467575, 31468339], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 482011636, 482014325, 31468354, 31471043], ["tinystories/en", "TinyStories-valid", "en", 2898027, 2899096, 31471058, 31472127], ["github/JavaScript", "axios/axios", "JavaScript", 308919914, 308927469, 31472142, 31479697], ["tinystories/en", "TinyStories-valid", "en", 3284931, 3285592, 31479712, 31480373], ["tinystories/en", "TinyStories-valid", "en", 18077299, 18078465, 31480388, 31481554], ["github/Kotlin", "JetBrains/kotlin-web-site", "Kotlin", 481428391, 481429593, 31481569, 31482771], ["github/Python", "django/django", "Python", 287195474, 287195732, 31482786, 31483044], ["tinystories/en", "TinyStories-valid", "en", 16075296, 16076079, 31483059, 31483842], ["github/TypeScript", "nestjs/nest", "TypeScript", 336797398, 336822431, 31483857, 31508890], ["github/Python", "django/django", "Python", 288296813, 288298312, 31508905, 31510404], ["tinystories/en", "TinyStories-valid", "en", 6050266, 6051646, 31510419, 31511799], ["stdlib/python", "python3.13 stdlib", "Python", 30995747, 31025492, 31511814, 31541559], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 483977674, 483980038, 31541561, 31543925], ["github/PHP", "laravel/framework", "PHP", 466910484, 466917942, 31543940, 31551398], ["github/Python", "scikit-learn/scikit-learn", "Python", 294920544, 294920790, 31551413, 31551659], ["github/Java", "google/guava", "Java", 412429810, 412437684, 31551674, 31559548], ["tinystories/en", "TinyStories-valid", "en", 2658965, 2659865, 31559563, 31560463], ["github/Python", "pallets/flask", "Python", 281809201, 281811704, 31560478, 31562981], ["tinystories/en", "TinyStories-valid", "en", 6958313, 6959241, 31562996, 31563924], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491882583, 491883023, 31563939, 31564379], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515422658, 515424239, 31564394, 31565975], ["tinystories/en", "TinyStories-valid", "en", 19467520, 19468175, 31565990, 31566645], ["github/JavaScript", "webpack/webpack", "JavaScript", 308065296, 308069877, 31566660, 31571241], ["tinystories/en", "TinyStories-valid", "en", 16868759, 16869601, 31571256, 31572098], ["tinystories/en", "TinyStories-valid", "en", 9063550, 9064253, 31572113, 31572816], ["github/Java", "spring-projects/spring-framework", "Java", 424368065, 424371090, 31572831, 31575856], ["github/PHP", "symfony/symfony", "PHP", 479311945, 479313095, 31575871, 31577021], ["tinystories/en", "TinyStories-valid", "en", 1423257, 1423984, 31577036, 31577763], ["tinystories/en", "TinyStories-valid", "en", 10053211, 10053860, 31577778, 31578427], ["github/PHP", "laravel/framework", "PHP", 465818340, 465819583, 31578442, 31579685], ["github/Java", "google/guava", "Java", 412451841, 412453786, 31579700, 31581645], ["tinystories/en", "TinyStories-valid", "en", 7138753, 7139501, 31581660, 31582408], ["github/C", "curl/curl", "C", 377750299, 377759204, 31582423, 31591328], ["tinystories/en", "TinyStories-valid", "en", 4248018, 4248671, 31591343, 31591996], ["github/Java", "apache/commons-lang", "Java", 435398139, 435400542, 31592011, 31594414], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 315046250, 315050437, 31594429, 31598616], ["tinystories/en", "TinyStories-valid", "en", 12448651, 12449355, 31598631, 31599335], ["tinystories/en", "TinyStories-valid", "en", 3276658, 3277486, 31599350, 31600178], ["github/PHP", "laravel/framework", "PHP", 470805331, 470809931, 31600193, 31604793], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 484182718, 484193251, 31604808, 31615341], ["tinystories/en", "TinyStories-valid", "en", 9965610, 9966486, 31615356, 31616232], ["github/Java", "square/okhttp", "Java", 427940707, 427944101, 31616247, 31619641], ["github/Python", "django/django", "Python", 284676833, 284689550, 31619656, 31632373], ["github/Scala", "scala/scala", "Scala", 500382213, 500448479, 31632388, 31698654], ["github/JavaScript", "webpack/webpack", "JavaScript", 300513032, 300513178, 31698669, 31698815], ["tinystories/en", "TinyStories-valid", "en", 11520688, 11521687, 31698830, 31699829], ["tinystories/en", "TinyStories-valid", "en", 14946647, 14947365, 31699844, 31700562], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 317927535, 317930550, 31700577, 31703592], ["github/PHP", "symfony/symfony", "PHP", 476378306, 476379477, 31703607, 31704778], ["tinystories/en", "TinyStories-valid", "en", 3801437, 3802254, 31704793, 31705610], ["github/C++", "nlohmann/json", "C++", 387839823, 387918508, 31705625, 31784310], ["github/PHP", "symfony/symfony", "PHP", 471229023, 471229693, 31784325, 31784995], ["tinystories/en", "TinyStories-valid", "en", 1585667, 1586931, 31785010, 31786274], ["tinystories/en", "TinyStories-valid", "en", 11004626, 11005599, 31786289, 31787262], ["github/Swift", "vapor/vapor", "Swift", 497785479, 497803673, 31787277, 31805471], ["tinystories/en", "TinyStories-valid", "en", 6860106, 6860532, 31805486, 31805912], ["github/PHP", "symfony/symfony", "PHP", 471743280, 471746734, 31805927, 31809381], ["tinystories/en", "TinyStories-valid", "en", 13193091, 13194335, 31809396, 31810640], ["github/Java", "google/guava", "Java", 411480789, 411497993, 31810655, 31827859], ["github/Kotlin", "ktorio/ktor", "Kotlin", 493117776, 493118498, 31827874, 31828596], ["tinystories/en", "TinyStories-valid", "en", 7057786, 7058588, 31828611, 31829413], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515066887, 515067144, 31829428, 31829685], ["tinystories/en", "TinyStories-valid", "en", 3128099, 3128812, 31829700, 31830413], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491630856, 491631857, 31830428, 31831429], ["github/PHP", "symfony/symfony", "PHP", 474635092, 474637495, 31831444, 31833847], ["github/Ruby", "rails/rails", "Ruby", 458065549, 458075558, 31833862, 31843871], ["github/Python", "django/django", "Python", 284484995, 284488042, 31843886, 31846933], ["tinystories/en", "TinyStories-valid", "en", 3675927, 3676616, 31846948, 31847637], ["github/C", "libuv/libuv", "C", 381352250, 381358964, 31847652, 31854366], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486823212, 486823754, 31854381, 31854923], ["tinystories/en", "TinyStories-valid", "en", 7875498, 7876384, 31854938, 31855824], ["github/JavaScript", "axios/axios", "JavaScript", 308714119, 308725306, 31855839, 31867026], ["tinystories/en", "TinyStories-valid", "en", 11810070, 11811294, 31867041, 31868265], ["github/Kotlin", "ktorio/ktor", "Kotlin", 488893618, 488895346, 31868280, 31870008], ["tinystories/en", "TinyStories-valid", "en", 8693889, 8694666, 31870023, 31870800], ["tinystories/en", "TinyStories-valid", "en", 100014, 100737, 31870815, 31871538], ["tinystories/en", "TinyStories-valid", "en", 6249381, 6250324, 31871553, 31872496], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 483620768, 483623087, 31872511, 31874830], ["github/PHP", "symfony/symfony", "PHP", 473450586, 473458048, 31874845, 31882307], ["github/Java", "google/guava", "Java", 412060631, 412063686, 31882322, 31885377], ["tinystories/en", "TinyStories-valid", "en", 11171105, 11172080, 31885392, 31886367], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487635360, 487635788, 31886382, 31886810], ["tinystories/en", "TinyStories-valid", "en", 5710567, 5711353, 31886825, 31887611], ["github/C", "curl/curl", "C", 379970461, 379972507, 31887626, 31889672], ["tinystories/en", "TinyStories-valid", "en", 8958933, 8959624, 31889687, 31890378], ["github/Java", "google/guava", "Java", 412134179, 412138402, 31890393, 31894616], ["tinystories/en", "TinyStories-valid", "en", 1441452, 1442451, 31894631, 31895630], ["tinystories/en", "TinyStories-valid", "en", 11051653, 11052529, 31895645, 31896521], ["github/JavaScript", "webpack/webpack", "JavaScript", 307849975, 307854444, 31896536, 31901005], ["github/Kotlin", "ktorio/ktor", "Kotlin", 491201338, 491205480, 31901020, 31905162], ["github/Java", "spring-projects/spring-framework", "Java", 419015450, 419017954, 31905177, 31907681], ["tinystories/en", "TinyStories-valid", "en", 13293065, 13293984, 31907696, 31908615], ["tinystories/en", "TinyStories-valid", "en", 9198943, 9199429, 31908630, 31909116], ["github/Ruby", "rails/rails", "Ruby", 460841498, 460842303, 31909131, 31909936], ["tinystories/en", "TinyStories-valid", "en", 4504840, 4505580, 31909951, 31910691], ["tinystories/en", "TinyStories-valid", "en", 18755320, 18756102, 31910706, 31911488], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486680772, 486681169, 31911503, 31911900], ["github/PHP", "laravel/framework", "PHP", 469947125, 469953814, 31911915, 31918604], ["github/Ruby", "rails/rails", "Ruby", 456241695, 456242832, 31918619, 31919756], ["tinystories/en", "TinyStories-valid", "en", 8677637, 8678185, 31919771, 31920319], ["tinystories/en", "TinyStories-valid", "en", 4911873, 4912624, 31920334, 31921085], ["github/Rust", "serde-rs/serde", "Rust", 346162137, 346162409, 31921100, 31921372], ["tinystories/en", "TinyStories-valid", "en", 14910561, 14911438, 31921387, 31922264], ["tinystories/en", "TinyStories-valid", "en", 16881706, 16882284, 31922279, 31922857], ["github/Ruby", "sinatra/sinatra", "Ruby", 462223790, 462225245, 31922872, 31924327], ["tinystories/en", "TinyStories-valid", "en", 2043366, 2044120, 31924342, 31925096], ["github/Java", "apache/commons-lang", "Java", 436665236, 436679712, 31925111, 31939587], ["github/C", "libuv/libuv", "C", 383090452, 383100326, 31939602, 31949476], ["github/PHP", "symfony/symfony", "PHP", 478612689, 478613023, 31949491, 31949825], ["tinystories/en", "TinyStories-valid", "en", 4010396, 4011056, 31949840, 31950500], ["books/en", "PG #203", "en", 132393961, 133432163, 31950515, 32988717], ["tinystories/en", "TinyStories-valid", "en", 10653704, 10655536, 32988719, 32990551], ["github/Python", "scikit-learn/scikit-learn", "Python", 297933387, 297963487, 32990566, 33020666], ["github/Rust", "tokio-rs/tokio", "Rust", 343489021, 343497093, 33020681, 33028753], ["github/PHP", "symfony/symfony", "PHP", 473031692, 473035061, 33028768, 33032137], ["github/Kotlin", "ktorio/ktor", "Kotlin", 494100203, 494109388, 33032152, 33041337], ["tinystories/en", "TinyStories-valid", "en", 13530306, 13531061, 33041352, 33042107], ["github/Ruby", "rails/rails", "Ruby", 456108827, 456111330, 33042122, 33044625], ["github/JavaScript", "webpack/webpack", "JavaScript", 306874146, 306889121, 33044640, 33059615], ["tinystories/en", "TinyStories-valid", "en", 15288701, 15290068, 33059630, 33060997], ["github/PHP", "guzzle/guzzle", "PHP", 480069479, 480070302, 33061012, 33061835], ["github/PHP", "laravel/framework", "PHP", 464376763, 464377064, 33061850, 33062151], ["tinystories/en", "TinyStories-valid", "en", 6429791, 6431000, 33062166, 33063375], ["tinystories/en", "TinyStories-valid", "en", 4469629, 4470546, 33063390, 33064307], ["tinystories/en", "TinyStories-valid", "en", 7513151, 7513846, 33064322, 33065017], ["github/TypeScript", "angular/angular", "TypeScript", 331795004, 331857610, 33065032, 33127638], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515545886, 515548567, 33127653, 33130334], ["tinystories/en", "TinyStories-valid", "en", 318637, 319412, 33130349, 33131124], ["github/PHP", "symfony/symfony", "PHP", 477193100, 477199539, 33131139, 33137578], ["github/Rust", "rust-lang/cargo", "Rust", 347533414, 347538102, 33137593, 33142281], ["tinystories/en", "TinyStories-valid", "en", 2854200, 2855340, 33142296, 33143436], ["tinystories/en", "TinyStories-valid", "en", 5883641, 5884209, 33143451, 33144019], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 448227948, 448297867, 33144034, 33213953], ["github/C", "curl/curl", "C", 373008186, 373011698, 33213968, 33217480], ["tinystories/en", "TinyStories-valid", "en", 15976026, 15976426, 33217495, 33217895], ["github/Scala", "scala/scala", "Scala", 503741232, 503749898, 33217910, 33226576], ["github/Java", "square/okhttp", "Java", 427501963, 427520491, 33226591, 33245119], ["tinystories/en", "TinyStories-valid", "en", 8994375, 8995239, 33245134, 33245998], ["tinystories/en", "TinyStories-valid", "en", 10992364, 10993166, 33246013, 33246815], ["github/JavaScript", "webpack/webpack", "JavaScript", 307064880, 307066254, 33246830, 33248204], ["github/PHP", "symfony/symfony", "PHP", 475305770, 475307329, 33248219, 33249778], ["tinystories/en", "TinyStories-valid", "en", 2866486, 2867357, 33249793, 33250664], ["github/Kotlin", "ktorio/ktor", "Kotlin", 495644211, 495650042, 33250679, 33256510], ["github/Go", "gohugoio/hugo", "Go", 372166203, 372170131, 33256525, 33260453], ["tinystories/en", "TinyStories-valid", "en", 6322929, 6323806, 33260468, 33261345], ["github/PHP", "laravel/framework", "PHP", 469578717, 469580193, 33261360, 33262836], ["tinystories/en", "TinyStories-valid", "en", 11266970, 11267548, 33262851, 33263429], ["github/Rust", "tokio-rs/tokio", "Rust", 340257730, 340263984, 33263444, 33269698], ["github/Scala", "sbt/sbt", "Scala", 519875925, 519875950, 33269713, 33269738], ["tinystories/en", "TinyStories-valid", "en", 5072510, 5073319, 33269753, 33270562], ["github/C", "curl/curl", "C", 379570928, 379573700, 33270577, 33273349], ["github/Scala", "playframework/playframework", "Scala", 511669106, 511669992, 33273364, 33274250], ["github/C++", "protocolbuffers/protobuf", "C++", 404273443, 404286696, 33274265, 33287518], ["tinystories/en", "TinyStories-valid", "en", 15993033, 15993868, 33287533, 33288368], ["github/Go", "gohugoio/hugo", "Go", 370883570, 370884241, 33288383, 33289054], ["github/Scala", "scala/scala", "Scala", 506180356, 506182143, 33289069, 33290856], ["tinystories/en", "TinyStories-valid", "en", 11036152, 11036974, 33290871, 33291693], ["github/PHP", "laravel/framework", "PHP", 467312948, 467316447, 33291708, 33295207], ["tinystories/en", "TinyStories-valid", "en", 1435643, 1436573, 33295222, 33296152], ["github/Rust", "serde-rs/serde", "Rust", 346863443, 346863568, 33296167, 33296292], ["github/Java", "spring-projects/spring-framework", "Java", 424899364, 424901190, 33296307, 33298133], ["github/C", "madler/zlib", "C", 383751416, 383752906, 33298148, 33299638], ["tinystories/en", "TinyStories-valid", "en", 9005501, 9006545, 33299653, 33300697], ["github/Java", "square/okhttp", "Java", 426113050, 426113484, 33300712, 33301146], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 487315205, 487318361, 33301161, 33304317], ["github/Scala", "sbt/sbt", "Scala", 517440309, 517444794, 33304332, 33308817], ["tinystories/en", "TinyStories-valid", "en", 1113198, 1114033, 33308832, 33309667], ["tinystories/en", "TinyStories-valid", "en", 16162236, 16163054, 33309682, 33310500], ["github/Java", "google/guava", "Java", 409697227, 409702808, 33310515, 33316096], ["github/Go", "gohugoio/hugo", "Go", 370672345, 370679582, 33316111, 33323348], ["github/C", "curl/curl", "C", 375025616, 375027394, 33323363, 33325141], ["github/C++", "nlohmann/json", "C++", 385493949, 385494523, 33325156, 33325730], ["tinystories/en", "TinyStories-valid", "en", 14069545, 14070310, 33325745, 33326510], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485922073, 485923668, 33326525, 33328120], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 314296574, 314313467, 33328135, 33345028], ["tinystories/en", "TinyStories-valid", "en", 11042658, 11043390, 33345043, 33345775], ["tinystories/en", "TinyStories-valid", "en", 9686012, 9686969, 33345790, 33346747], ["github/Python", "encode/httpx", "Python", 299354855, 299364504, 33346762, 33356411], ["github/C++", "opencv/opencv", "C++", 398666345, 398670798, 33356426, 33360879], ["github/Scala", "playframework/playframework", "Scala", 512682553, 512686937, 33360894, 33365278], ["github/Java", "spring-projects/spring-framework", "Java", 419827270, 419830475, 33365293, 33368498], ["github/C", "curl/curl", "C", 372994553, 372996434, 33368513, 33370394], ["tinystories/en", "TinyStories-valid", "en", 13247124, 13247885, 33370409, 33371170], ["github/Rust", "rust-lang/cargo", "Rust", 350730696, 350741635, 33371185, 33382124], ["tinystories/en", "TinyStories-valid", "en", 2594542, 2595139, 33382139, 33382736], ["github/Kotlin", "ktorio/ktor", "Kotlin", 490988145, 490991028, 33382751, 33385634], ["github/Java", "spring-projects/spring-framework", "Java", 417927233, 417927969, 33385649, 33386385], ["github/PHP", "symfony/symfony", "PHP", 471555302, 471567360, 33386400, 33398458], ["tinystories/en", "TinyStories-valid", "en", 9108577, 9109258, 33398473, 33399154], ["github/C++", "protocolbuffers/protobuf", "C++", 401533462, 401534374, 33399169, 33400081], ["tinystories/en", "TinyStories-valid", "en", 9197569, 9198245, 33400096, 33400772], ["github/Scala", "sbt/sbt", "Scala", 519888632, 519888882, 33400787, 33401037], ["tinystories/en", "TinyStories-valid", "en", 8280843, 8281654, 33401052, 33401863], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487984355, 487984598, 33401878, 33402121], ["github/Java", "spring-projects/spring-framework", "Java", 424410132, 424415878, 33402136, 33407882], ["github/Kotlin", "ktorio/ktor", "Kotlin", 495277517, 495277936, 33407897, 33408316], ["github/C", "curl/curl", "C", 380324516, 380327617, 33408331, 33411432], ["tinystories/en", "TinyStories-valid", "en", 8581024, 8583111, 33411447, 33413534], ["tinystories/en", "TinyStories-valid", "en", 8631757, 8632368, 33413549, 33414160], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485019662, 485022688, 33414175, 33417201], ["github/Java", "google/guava", "Java", 413331678, 413333271, 33417216, 33418809], ["tinystories/en", "TinyStories-valid", "en", 16793600, 16794162, 33418824, 33419386], ["tinystories/en", "TinyStories-valid", "en", 15584157, 15585040, 33419401, 33420284], ["github/Go", "gohugoio/hugo", "Go", 371980535, 371990555, 33420299, 33430319], ["tinystories/en", "TinyStories-valid", "en", 9336015, 9336744, 33430334, 33431063], ["github/Java", "spring-projects/spring-framework", "Java", 424415893, 424419767, 33431078, 33434952], ["github/C", "curl/curl", "C", 380275636, 380278359, 33434967, 33437690], ["tinystories/en", "TinyStories-valid", "en", 5005196, 5006042, 33437705, 33438551], ["github/PHP", "symfony/symfony", "PHP", 476254710, 476256628, 33438566, 33440484], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 485541259, 485543515, 33440499, 33442755], ["tinystories/en", "TinyStories-valid", "en", 10427924, 10428752, 33442770, 33443598], ["github/PHP", "laravel/framework", "PHP", 467718618, 467719232, 33443613, 33444227], ["tinystories/en", "TinyStories-valid", "en", 11179221, 11180156, 33444242, 33445177], ["github/C++", "nlohmann/json", "C++", 386295450, 386316295, 33445192, 33466037], ["github/Java", "square/okhttp", "Java", 426173110, 426177327, 33466052, 33470269], ["tinystories/en", "TinyStories-valid", "en", 3143154, 3143814, 33470284, 33470944], ["tinystories/en", "TinyStories-valid", "en", 13484411, 13485132, 33470959, 33471680], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316356521, 316365698, 33471695, 33480872], ["github/Java", "google/guava", "Java", 410739981, 410741122, 33480887, 33482028], ["github/C", "curl/curl", "C", 374170291, 374173132, 33482043, 33484884], ["github/Kotlin", "ktorio/ktor", "Kotlin", 488847500, 488850733, 33484899, 33488132], ["tinystories/en", "TinyStories-valid", "en", 1818367, 1819986, 33488147, 33489766], ["tinystories/en", "TinyStories-valid", "en", 6762809, 6763862, 33489781, 33490834], ["github/TypeScript", "nestjs/nest", "TypeScript", 333945146, 333946321, 33490849, 33492024], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486307160, 486307745, 33492039, 33492624], ["tinystories/en", "TinyStories-valid", "en", 10741488, 10743089, 33492639, 33494240], ["github/Java", "google/guava", "Java", 417423502, 417432187, 33494255, 33502940], ["github/Go", "gohugoio/hugo", "Go", 369725511, 369729798, 33502955, 33507242], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486080301, 486080937, 33507257, 33507893], ["github/TypeScript", "angular/angular", "TypeScript", 326401629, 326402825, 33507908, 33509104], ["github/C", "curl/curl", "C", 372854464, 372857006, 33509119, 33511661], ["tinystories/en", "TinyStories-valid", "en", 7080744, 7081298, 33511676, 33512230], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 486305507, 486306405, 33512245, 33513143], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515337529, 515338866, 33513158, 33514495], ["tinystories/en", "TinyStories-valid", "en", 11279282, 11279831, 33514510, 33515059], ["github/JavaScript", "axios/axios", "JavaScript", 309047207, 309048588, 33515074, 33516455], ["github/Ruby", "rails/rails", "Ruby", 460071836, 460108019, 33516470, 33552653], ["github/Rust", "BurntSushi/ripgrep", "Rust", 339603932, 339627055, 33552668, 33575791], ["tinystories/en", "TinyStories-valid", "en", 1161451, 1162368, 33575806, 33576723], ["github/Kotlin", "ktorio/ktor", "Kotlin", 487676949, 487677723, 33576738, 33577512], ["github/Scala", "scala/scala", "Scala", 503254369, 503290031, 33577527, 33613189], ["tinystories/en", "TinyStories-valid", "en", 9399559, 9401059, 33613204, 33614704], ["github/Go", "gohugoio/hugo", "Go", 366541473, 366542818, 33614719, 33616064], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 317011823, 317014241, 33616079, 33618497], ["github/Java", "spring-projects/spring-framework", "Java", 425226189, 425228587, 33618512, 33620910], ["github/Kotlin", "ktorio/ktor", "Kotlin", 492969785, 492972005, 33620925, 33623145], ["github/Java", "square/okhttp", "Java", 426393963, 426394973, 33623160, 33624170], ["github/C", "libuv/libuv", "C", 383062883, 383066019, 33624185, 33627321], ["tinystories/en", "TinyStories-valid", "en", 4635372, 4636958, 33627336, 33628922], ["github/Java", "spring-projects/spring-framework", "Java", 418052168, 418052897, 33628937, 33629666], ["stdlib/python", "python3.13 stdlib", "Python", 22812232, 22831689, 33629681, 33649138], ["tinystories/en", "TinyStories-valid", "en", 7750443, 7751374, 33649140, 33650071], ["github/Go", "prometheus/prometheus", "Go", 359339918, 359343455, 33650086, 33653623], ["github/Java", "apache/commons-lang", "Java", 437722792, 437726850, 33653638, 33657696], ["tinystories/en", "TinyStories-valid", "en", 17949931, 17950616, 33657711, 33658396], ["tinystories/en", "TinyStories-valid", "en", 18417936, 18418899, 33658411, 33659374], ["github/Swift", "vapor/vapor", "Swift", 497845941, 497847509, 33659389, 33660957], ["github/Kotlin", "Kotlin/kotlinx.coroutines", "Kotlin", 487121105, 487124916, 33660972, 33664783], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 309612277, 309619003, 33664798, 33671524], ["github/PHP", "symfony/symfony", "PHP", 473044728, 473072006, 33671539, 33698817], ["tinystories/en", "TinyStories-valid", "en", 3054663, 3055288, 33698832, 33699457], ["github/Go", "gohugoio/hugo", "Go", 369832960, 369834467, 33699472, 33700979], ["tinystories/en", "TinyStories-valid", "en", 6585477, 6586390, 33700994, 33701907], ["github/Python", "scikit-learn/scikit-learn", "Python", 293565433, 293606057, 33701922, 33742546], ["github/C", "jqlang/jq", "C", 384760047, 384764787, 33742561, 33747301], ["tinystories/en", "TinyStories-valid", "en", 1763637, 1765658, 33747316, 33749337], ["github/Java", "square/okhttp", "Java", 429789540, 429797960, 33749352, 33757772], ["tinystories/en", "TinyStories-valid", "en", 653595, 654388, 33757787, 33758580], ["github/Go", "gin-gonic/gin", "Go", 356366409, 356370247, 33758595, 33762433], ["tinystories/en", "TinyStories-valid", "en", 3888416, 3888969, 33762448, 33763001], ["tinystories/en", "TinyStories-valid", "en", 6599645, 6600278, 33763016, 33763649], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 314800957, 314805262, 33763664, 33767969], ["tinystories/en", "TinyStories-valid", "en", 4368847, 4369525, 33767984, 33768662], ["github/Java", "square/okhttp", "Java", 426356480, 426358335, 33768677, 33770532], ["tinystories/en", "TinyStories-valid", "en", 16098851, 16099517, 33770547, 33771213], ["tinystories/en", "TinyStories-valid", "en", 11981572, 11982289, 33771228, 33771945], ["github/Rust", "tokio-rs/tokio", "Rust", 341307406, 341310623, 33771960, 33775177], ["tinystories/en", "TinyStories-valid", "en", 503537, 504205, 33775192, 33775860], ["github/C", "curl/curl", "C", 380359674, 380362577, 33775875, 33778778], ["github/Java", "spring-projects/spring-framework", "Java", 422180983, 422185552, 33778793, 33783362], ["tinystories/en", "TinyStories-valid", "en", 19376204, 19377177, 33783377, 33784350], ["github/TypeScript", "vuejs/core", "TypeScript", 322424437, 322459580, 33784365, 33819508], ["books/en", "PG #264", "en", 150823594, 150863780, 33819523, 33859709], ["tinystories/en", "TinyStories-valid", "en", 15619946, 15620706, 33859711, 33860471], ["github/C#", "dotnet/aspnetcore", "C#", 443959990, 443964875, 33860486, 33865371], ["tinystories/en", "TinyStories-valid", "en", 7138075, 7138738, 33865386, 33866049], ["tinystories/en", "TinyStories-valid", "en", 12153898, 12154609, 33866064, 33866775], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316986631, 316992564, 33866790, 33872723], ["github/Go", "prometheus/prometheus", "Go", 358777536, 358786344, 33872738, 33881546], ["tinystories/en", "TinyStories-valid", "en", 8228603, 8229195, 33881561, 33882153], ["github/Java", "spring-projects/spring-framework", "Java", 422896745, 422902235, 33882168, 33887658], ["github/Scala", "scala/scala", "Scala", 505933756, 505935469, 33887673, 33889386], ["tinystories/en", "TinyStories-valid", "en", 6276668, 6277719, 33889401, 33890452], ["github/C++", "opencv/opencv", "C++", 393573800, 393619143, 33890467, 33935810], ["github/Scala", "sbt/sbt", "Scala", 519773043, 519774022, 33935825, 33936804], ["tinystories/en", "TinyStories-valid", "en", 4277241, 4277992, 33936819, 33937570], ["github/Swift", "vapor/vapor", "Swift", 498003972, 498006640, 33937585, 33940253], ["github/Scala", "playframework/playframework", "Scala", 508590864, 508591914, 33940268, 33941318], ["github/Java", "google/guava", "Java", 416795772, 416797566, 33941333, 33943127], ["tinystories/en", "TinyStories-valid", "en", 10056759, 10057667, 33943142, 33944050], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449943687, 449945370, 33944065, 33945748], ["github/JavaScript", "webpack/webpack", "JavaScript", 300473651, 300474405, 33945763, 33946517], ["github/Scala", "playframework/playframework", "Scala", 510807058, 510808093, 33946532, 33947567], ["tinystories/en", "TinyStories-valid", "en", 14982017, 14982717, 33947582, 33948282], ["github/Java", "spring-projects/spring-framework", "Java", 425694278, 425696709, 33948297, 33950728], ["tinystories/en", "TinyStories-valid", "en", 3174002, 3174707, 33950743, 33951448], ["github/Scala", "scala/scala", "Scala", 505657656, 505658247, 33951463, 33952054], ["github/Java", "spring-projects/spring-framework", "Java", 419604248, 419604390, 33952069, 33952211], ["tinystories/en", "TinyStories-valid", "en", 6271612, 6272564, 33952226, 33953178], ["github/JavaScript", "axios/axios", "JavaScript", 309429187, 309432435, 33953193, 33956441], ["github/Java", "spring-projects/spring-framework", "Java", 417963613, 417964705, 33956456, 33957548], ["github/PHP", "symfony/symfony", "PHP", 478848462, 478853621, 33957563, 33962722], ["tinystories/en", "TinyStories-valid", "en", 18794372, 18795511, 33962737, 33963876], ["books/fr", "PG #10774", "fr", 276811215, 277073371, 33963891, 34226047], ["tinystories/en", "TinyStories-valid", "en", 17457917, 17458607, 34226049, 34226739], ["github/C", "curl/curl", "C", 380533078, 380544528, 34226754, 34238204], ["github/Go", "gohugoio/hugo", "Go", 366851680, 366855564, 34238219, 34242103], ["github/Scala", "scala/scala", "Scala", 506157120, 506164082, 34242118, 34249080], ["tinystories/en", "TinyStories-valid", "en", 4798977, 4799839, 34249095, 34249957], ["github/Rust", "rust-lang/cargo", "Rust", 353212253, 353234328, 34249972, 34272047], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515353916, 515355985, 34272062, 34274131], ["github/PHP", "symfony/symfony", "PHP", 477717716, 477720535, 34274146, 34276965], ["tinystories/en", "TinyStories-valid", "en", 6193497, 6196756, 34276980, 34280239], ["github/C#", "dotnet/aspnetcore", "C#", 443337126, 443346794, 34280254, 34289922], ["github/Go", "gohugoio/hugo", "Go", 371218200, 371219454, 34289937, 34291191], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 314266316, 314274407, 34291206, 34299297], ["github/Scala", "sbt/sbt", "Scala", 519864690, 519864976, 34299312, 34299598], ["github/PHP", "laravel/framework", "PHP", 467967507, 467968630, 34299613, 34300736], ["github/Go", "gin-gonic/gin", "Go", 356512555, 356513115, 34300751, 34301311], ["github/Python", "django/django", "Python", 283921830, 283922452, 34301326, 34301948], ["tinystories/en", "TinyStories-valid", "en", 18500390, 18501362, 34301963, 34302935], ["github/Scala", "playframework/playframework", "Scala", 511572152, 511574435, 34302950, 34305233], ["github/PHP", "laravel/framework", "PHP", 468634919, 468635540, 34305248, 34305869], ["tinystories/en", "TinyStories-valid", "en", 18221294, 18222024, 34305884, 34306614], ["github/Swift", "vapor/vapor", "Swift", 497991922, 497992412, 34306629, 34307119], ["tinystories/en", "TinyStories-valid", "en", 2200942, 2201829, 34307134, 34308021], ["github/Scala", "playframework/playframework", "Scala", 511917331, 511918650, 34308036, 34309355], ["tinystories/en", "TinyStories-valid", "en", 9584603, 9585341, 34309370, 34310108], ["github/Scala", "playframework/playframework", "Scala", 508593470, 508594362, 34310123, 34311015], ["tinystories/en", "TinyStories-valid", "en", 4859454, 4860139, 34311030, 34311715], ["github/TypeScript", "angular/angular", "TypeScript", 324090413, 324091394, 34311730, 34312711], ["github/Go", "prometheus/prometheus", "Go", 364295272, 364301644, 34312726, 34319098], ["github/Scala", "playframework/playframework", "Scala", 511332675, 511333848, 34319113, 34320286], ["github/TypeScript", "angular/angular", "TypeScript", 324794661, 324795222, 34320301, 34320862], ["tinystories/en", "TinyStories-valid", "en", 14095404, 14097128, 34320877, 34322601], ["github/C#", "dotnet/aspnetcore", "C#", 439231423, 439231711, 34322616, 34322904], ["github/Kotlin", "ktorio/ktor", "Kotlin", 493568643, 493608439, 34322919, 34362715], ["github/Scala", "sbt/sbt", "Scala", 516355913, 516356714, 34362730, 34363531], ["github/TypeScript", "angular/angular", "TypeScript", 324337744, 324339115, 34363546, 34364917], ["github/Scala", "playframework/playframework", "Scala", 512254998, 512255555, 34364932, 34365489], ["stdlib/python", "python3.13 stdlib", "Python", 20232415, 20232683, 34365504, 34365772], ["github/Ruby", "rails/rails", "Ruby", 454198526, 454198713, 34365774, 34365961], ["github/Java", "square/okhttp", "Java", 428292754, 428329038, 34365976, 34402260], ["tinystories/en", "TinyStories-valid", "en", 14897934, 14900689, 34402275, 34405030], ["github/TypeScript", "angular/angular", "TypeScript", 325160982, 325163105, 34405045, 34407168], ["github/Ruby", "rails/rails", "Ruby", 456258913, 456260382, 34407183, 34408652], ["books/en", "PG #347", "en", 174556053, 174935924, 34408667, 34788538], ["github/Swift", "vapor/vapor", "Swift", 497215171, 497216667, 34788540, 34790036], ["github/C", "curl/curl", "C", 377143581, 377148579, 34790051, 34795049], ["github/Go", "gin-gonic/gin", "Go", 356887836, 356888626, 34795064, 34795854], ["github/Scala", "sbt/sbt", "Scala", 520369454, 520375007, 34795869, 34801422], ["github/C++", "opencv/opencv", "C++", 393807987, 393809952, 34801437, 34803402], ["tinystories/en", "TinyStories-valid", "en", 3978971, 3979721, 34803417, 34804167], ["github/C#", "dotnet/aspnetcore", "C#", 439371094, 439377322, 34804182, 34810410], ["stdlib/python", "python3.13 stdlib", "Python", 20415527, 20417110, 34810425, 34812008], ["github/C++", "nlohmann/json", "C++", 385376598, 385377364, 34812010, 34812776], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 316890653, 316903111, 34812791, 34825249], ["tinystories/en", "TinyStories-valid", "en", 8507376, 8509722, 34825264, 34827610], ["github/TypeScript", "vuejs/core", "TypeScript", 320708102, 320713727, 34827625, 34833250], ["github/Ruby", "rails/rails", "Ruby", 455686651, 455688341, 34833265, 34834955], ["github/C++", "protocolbuffers/protobuf", "C++", 403236414, 403239711, 34834970, 34838267], ["github/Scala", "playframework/playframework", "Scala", 511091979, 511092475, 34838282, 34838778], ["github/PHP", "laravel/framework", "PHP", 468234610, 468254942, 34838793, 34859125], ["github/Go", "gohugoio/hugo", "Go", 369483110, 369488453, 34859140, 34864483], ["tinystories/en", "TinyStories-valid", "en", 6457133, 6458176, 34864498, 34865541], ["github/C", "madler/zlib", "C", 383742540, 383743066, 34865556, 34866082], ["github/Rust", "tokio-rs/tokio", "Rust", 345471552, 345477985, 34866097, 34872530], ["tinystories/en", "TinyStories-valid", "en", 10669727, 10670259, 34872545, 34873077], ["github/Scala", "scala/scala", "Scala", 501824199, 501828076, 34873092, 34876969], ["tinystories/en", "TinyStories-valid", "en", 1937089, 1937874, 34876984, 34877769], ["github/TypeScript", "angular/angular", "TypeScript", 326683734, 326684021, 34877784, 34878071], ["github/TypeScript", "angular/angular", "TypeScript", 325208248, 325208714, 34878086, 34878552], ["github/C#", "dotnet/aspnetcore", "C#", 443689653, 443691584, 34878567, 34880498], ["tinystories/en", "TinyStories-valid", "en", 3157493, 3158254, 34880513, 34881274], ["github/C", "curl/curl", "C", 379910457, 379912619, 34881289, 34883451], ["tinystories/en", "TinyStories-valid", "en", 6251189, 6252051, 34883466, 34884328], ["github/Python", "django/django", "Python", 284594388, 284623041, 34884343, 34912996], ["github/C#", "dotnet/aspnetcore", "C#", 445735725, 445736777, 34913011, 34914063], ["tinystories/en", "TinyStories-valid", "en", 2951803, 2952949, 34914078, 34915224], ["github/TypeScript", "nestjs/nest", "TypeScript", 334952657, 334956520, 34915239, 34919102], ["github/C++", "opencv/opencv", "C++", 396241115, 396249696, 34919117, 34927698], ["github/Rust", "tokio-rs/tokio", "Rust", 341698320, 341700457, 34927713, 34929850], ["tinystories/en", "TinyStories-valid", "en", 13548397, 13549033, 34929865, 34930501], ["github/Scala", "sbt/sbt", "Scala", 516624138, 516628755, 34930516, 34935133], ["github/C#", "dotnet/aspnetcore", "C#", 444998494, 444999886, 34935148, 34936540], ["tinystories/en", "TinyStories-valid", "en", 15589090, 15589839, 34936555, 34937304], ["github/TypeScript", "vuejs/core", "TypeScript", 323437938, 323438390, 34937319, 34937771], ["tinystories/en", "TinyStories-valid", "en", 14442035, 14442679, 34937786, 34938430], ["github/Go", "prometheus/prometheus", "Go", 362396370, 362402036, 34938445, 34944111], ["github/Rust", "BurntSushi/ripgrep", "Rust", 338297268, 338298523, 34944126, 34945381], ["github/JavaScript", "webpack/webpack", "JavaScript", 306530128, 306534163, 34945396, 34949431], ["tinystories/en", "TinyStories-valid", "en", 13028036, 13029020, 34949446, 34950430], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515058749, 515059293, 34950445, 34950989], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 449652308, 449653676, 34951004, 34952372], ["github/TypeScript", "angular/angular", "TypeScript", 325957025, 325959058, 34952387, 34954420], ["github/Rust", "tokio-rs/tokio", "Rust", 340851285, 340851784, 34954435, 34954934], ["github/Ruby", "rails/rails", "Ruby", 454668500, 454675821, 34954949, 34962270], ["github/Scala", "sbt/sbt", "Scala", 516497002, 516497883, 34962285, 34963166], ["tinystories/en", "TinyStories-valid", "en", 17173756, 17174724, 34963181, 34964149], ["github/C++", "nlohmann/json", "C++", 385405304, 385406892, 34964164, 34965752], ["github/Rust", "rust-lang/cargo", "Rust", 347671627, 347672428, 34965767, 34966568], ["github/Java", "spring-projects/spring-framework", "Java", 419674427, 419681350, 34966583, 34973506], ["github/TypeScript", "angular/angular", "TypeScript", 324766049, 324766881, 34973521, 34974353], ["github/Rust", "serde-rs/serde", "Rust", 346853684, 346854029, 34974368, 34974713], ["github/Scala", "playframework/playframework", "Scala", 511737271, 511738836, 34974728, 34976293], ["tinystories/en", "TinyStories-valid", "en", 18799948, 18801029, 34976308, 34977389], ["stdlib/python", "python3.13 stdlib", "Python", 29089815, 29095877, 34977404, 34983466], ["github/Rust", "serde-rs/serde", "Rust", 346484860, 346485375, 34983468, 34983983], ["github/Scala", "sbt/sbt", "Scala", 519866341, 519866425, 34983998, 34984082], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 317041630, 317043585, 34984097, 34986052], ["github/Swift", "vapor/vapor", "Swift", 497270988, 497273642, 34986067, 34988721], ["github/Scala", "playframework/playframework", "Scala", 511787156, 511787509, 34988736, 34989089], ["github/Rust", "rust-lang/cargo", "Rust", 352826039, 352827010, 34989104, 34990075], ["tinystories/en", "TinyStories-valid", "en", 19032443, 19033265, 34990090, 34990912], ["github/TypeScript", "nestjs/nest", "TypeScript", 333598474, 333600643, 34990927, 34993096], ["github/Scala", "playframework/playframework", "Scala", 512935539, 512935852, 34993111, 34993424], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 452930161, 452933552, 34993439, 34996830], ["github/Scala", "sbt/sbt", "Scala", 519874773, 519874925, 34996845, 34996997], ["github/Rust", "rust-lang/cargo", "Rust", 347695787, 347696065, 34997012, 34997290], ["github/Go", "gohugoio/hugo", "Go", 369804443, 369806053, 34997305, 34998915], ["tinystories/en", "TinyStories-valid", "en", 18911419, 18912517, 34998930, 35000028], ["github/C", "curl/curl", "C", 379401257, 379411191, 35000043, 35009977], ["github/JavaScript", "webpack/webpack", "JavaScript", 305820706, 305821937, 35009992, 35011223], ["github/TypeScript", "nestjs/nest", "TypeScript", 336488469, 336489363, 35011238, 35012132], ["github/Scala", "scala/scala", "Scala", 500728878, 500731552, 35012147, 35014821], ["tinystories/en", "TinyStories-valid", "en", 17210015, 17210829, 35014836, 35015650], ["github/Java", "square/okhttp", "Java", 426140273, 426143336, 35015665, 35018728], ["tinystories/en", "TinyStories-valid", "en", 15783900, 15784494, 35018743, 35019337], ["github/Rust", "rust-lang/cargo", "Rust", 350421009, 350425415, 35019352, 35023758], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515685597, 515685799, 35023773, 35023975], ["tinystories/en", "TinyStories-valid", "en", 13678959, 13679827, 35023990, 35024858], ["github/TypeScript", "nestjs/nest", "TypeScript", 332684346, 332687326, 35024873, 35027853], ["github/C++", "protocolbuffers/protobuf", "C++", 400840380, 400852852, 35027868, 35040340], ["github/C#", "dotnet/aspnetcore", "C#", 438532223, 438534635, 35040355, 35042767], ["github/Go", "gohugoio/hugo", "Go", 369872422, 369876380, 35042782, 35046740], ["tinystories/en", "TinyStories-valid", "en", 5157315, 5158058, 35046755, 35047498], ["github/Java", "google/guava", "Java", 417415273, 417419169, 35047513, 35051409], ["github/PHP", "laravel/framework", "PHP", 466157532, 466165681, 35051424, 35059573], ["tinystories/en", "TinyStories-valid", "en", 12831140, 12832010, 35059588, 35060458], ["github/Scala", "scala/scala", "Scala", 502795371, 502799967, 35060473, 35065069], ["github/JavaScript", "mrdoob/three.js", "JavaScript", 314929504, 314935991, 35065084, 35071571], ["tinystories/en", "TinyStories-valid", "en", 12984181, 12984813, 35071586, 35072218], ["github/Rust", "tokio-rs/tokio", "Rust", 344829110, 344831359, 35072233, 35074482], ["github/Java", "google/guava", "Java", 411176649, 411179525, 35074497, 35077373], ["tinystories/en", "TinyStories-valid", "en", 12804811, 12805782, 35077388, 35078359], ["github/Ruby", "rails/rails", "Ruby", 453418946, 453420966, 35078374, 35080394], ["github/Shell", "ohmyzsh/ohmyzsh", "Shell", 515476671, 515476912, 35080409, 35080650], ["github/TypeScript", "nestjs/nest", "TypeScript", 332830368, 332834442, 35080665, 35084739], ["books/en", "PG #1952 (yellow_wallpaper)", "en", 29165720, 29198477, 35084754, 35117511], ["github/C#", "JamesNK/Newtonsoft.Json", "C#", 452675057, 452677638, 35117513, 35120094], ["github/Go", "gohugoio/hugo", "Go", 370387593, 370389631, 35120109, 35122147], ["github/Scala", "sbt/sbt", "Scala", 520197516, 520198764, 35122162, 35123410], ["tinystories/en", "TinyStories-valid", "en", 16477488, 16479210, 35123425, 35125147], ["github/Java", "google/guava", "Java", 409668695, 409670301, 35125162, 35126768], ["github/Rust", "tokio-rs/tokio", "Rust", 343391503, 343392518, 35126783, 35127798], ["github/Scala", "sbt/sbt", "Scala", 519762897, 519762968, 35127813, 35127884], ["github/Scala", "sbt/sbt", "Scala", 519775050, 519775118, 35127899, 35127967], ["github/Scala", "sbt/sbt", "Scala", 517011836, 517012008, 35127982, 35128154], ["github/PHP", "laravel/framework", "PHP", 463488472, 463488590, 35128169, 35128287], ["github/Scala", "sbt/sbt", "Scala", 519875414, 519875455, 35128302, 35128343], ["github/PHP", "laravel/framework", "PHP", 465544891, 465545020, 35128358, 35128487], ["github/Java", "spring-projects/spring-framework", "Java", 421360279, 421360547, 35128502, 35128770], ["github/Scala", "sbt/sbt", "Scala", 519762037, 519762081, 35128785, 35128829], ["github/Scala", "sbt/sbt", "Scala", 519883205, 519883273, 35128844, 35128912], ["github/PHP", "laravel/framework", "PHP", 467688607, 467688631, 35128927, 35128951]]
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/sample/v1b_sample_manifest.json b/results/hashing/m8_v1b/sample/v1b_sample_manifest.json
new file mode 100644
index 0000000000000000000000000000000000000000..d88c4fe7bcd608f28e4afe540aa29d34a7b0362e
--- /dev/null
+++ b/results/hashing/m8_v1b/sample/v1b_sample_manifest.json
@@ -0,0 +1,323 @@
+{
+ "author": "SPIRA Hashing",
+ "script": "/workspace/spira_shared/hashing_gen/m8_v1b/code/make_sample_v1b.py",
+ "script_sha256": "b9a72c14958e82db7585d50aa7e1c0de5e927e9171b3bc64482157fe003db595",
+ "source": {
+ "path": "/workspace/spira_shared/hashing_gen/corpus_v1b/train.bin",
+ "bytes": 520785883,
+ "sha256_expected": "ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3",
+ "manifest_sha256": "cb6398ca62f8f0003afd4d5505d59ecea7a8a13814091b358d93368c14f2494f"
+ },
+ "seed": 20261024,
+ "target_bytes": 35000000,
+ "sample": {
+ "path": "/workspace/spira_shared/hashing_gen/m8_v1b/sample/v1b_sample.bin",
+ "bytes": 35128951,
+ "sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "n_docs": 4111
+ },
+ "doc_index_counts": {
+ "tinystories": 21990,
+ "stdlib_gap_bytes": 5963768,
+ "stdlib_py_starts_matched": 256,
+ "stdlib_units": 257,
+ "github_files": 36910,
+ "books": 555
+ },
+ "v1b_doc_bytes_total": 519900789,
+ "strata": {
+ "books/en": {
+ "v1b_doc_bytes": 186460758,
+ "v1b_docs": 385,
+ "target_bytes": 12552638,
+ "taken_bytes": 12544478,
+ "taken_docs": 31,
+ "share_v1b": 0.3586468071315045,
+ "stratum_seed": 14364082646483397524
+ },
+ "books/fr": {
+ "v1b_doc_bytes": 69585788,
+ "v1b_docs": 170,
+ "target_bytes": 4684553,
+ "taken_bytes": 4717654,
+ "taken_docs": 12,
+ "share_v1b": 0.13384435929371133,
+ "stratum_seed": 1583969670694299524
+ },
+ "github/C": {
+ "v1b_doc_bytes": 12733317,
+ "v1b_docs": 1440,
+ "target_bytes": 857214,
+ "taken_bytes": 859470,
+ "taken_docs": 89,
+ "share_v1b": 0.024491820880848864,
+ "stratum_seed": 14283510491181467334
+ },
+ "github/C#": {
+ "v1b_doc_bytes": 15067399,
+ "v1b_docs": 2346,
+ "target_bytes": 1014345,
+ "taken_bytes": 1015112,
+ "taken_docs": 167,
+ "share_v1b": 0.028981296660428802,
+ "stratum_seed": 7737383756452390325
+ },
+ "github/C++": {
+ "v1b_doc_bytes": 23817694,
+ "v1b_docs": 2142,
+ "target_bytes": 1603420,
+ "taken_bytes": 1609289,
+ "taken_docs": 126,
+ "share_v1b": 0.04581199818106066,
+ "stratum_seed": 7608485171363292603
+ },
+ "github/Go": {
+ "v1b_doc_bytes": 16196854,
+ "v1b_docs": 1619,
+ "target_bytes": 1090381,
+ "taken_bytes": 1091284,
+ "taken_docs": 106,
+ "share_v1b": 0.03115373998788065,
+ "stratum_seed": 17824132401647747497
+ },
+ "github/Java": {
+ "v1b_doc_bytes": 28602620,
+ "v1b_docs": 4320,
+ "target_bytes": 1925544,
+ "taken_bytes": 1925613,
+ "taken_docs": 300,
+ "share_v1b": 0.05501553489660121,
+ "stratum_seed": 12360241391214572767
+ },
+ "github/JavaScript": {
+ "v1b_doc_bytes": 18386958,
+ "v1b_docs": 2514,
+ "target_bytes": 1237820,
+ "taken_bytes": 1238384,
+ "taken_docs": 186,
+ "share_v1b": 0.035366282161960715,
+ "stratum_seed": 572986652431508505
+ },
+ "github/Kotlin": {
+ "v1b_doc_bytes": 14474338,
+ "v1b_docs": 3571,
+ "target_bytes": 974420,
+ "taken_bytes": 993979,
+ "taken_docs": 233,
+ "share_v1b": 0.027840577099028024,
+ "stratum_seed": 2144189299031221718
+ },
+ "github/PHP": {
+ "v1b_doc_bytes": 18564115,
+ "v1b_docs": 3599,
+ "target_bytes": 1249746,
+ "taken_bytes": 1249744,
+ "taken_docs": 280,
+ "share_v1b": 0.03570703371254164,
+ "stratum_seed": 7404096481332877269
+ },
+ "github/Python": {
+ "v1b_doc_bytes": 18063016,
+ "v1b_docs": 2186,
+ "target_bytes": 1216012,
+ "taken_bytes": 1225317,
+ "taken_docs": 183,
+ "share_v1b": 0.03474319789885912,
+ "stratum_seed": 7560286162629868552
+ },
+ "github/Ruby": {
+ "v1b_doc_bytes": 9780569,
+ "v1b_docs": 1727,
+ "target_bytes": 658433,
+ "taken_bytes": 658678,
+ "taken_docs": 132,
+ "share_v1b": 0.018812375758868103,
+ "stratum_seed": 13915400743702225250
+ },
+ "github/Rust": {
+ "v1b_doc_bytes": 18371402,
+ "v1b_docs": 2013,
+ "target_bytes": 1236773,
+ "taken_bytes": 1236850,
+ "taken_docs": 141,
+ "share_v1b": 0.035336361068688434,
+ "stratum_seed": 11215015281825474505
+ },
+ "github/Scala": {
+ "v1b_doc_bytes": 20768508,
+ "v1b_docs": 4326,
+ "target_bytes": 1398147,
+ "taken_bytes": 1398174,
+ "taken_docs": 241,
+ "share_v1b": 0.03994705997647563,
+ "stratum_seed": 9435559635142962257
+ },
+ "github/Shell": {
+ "v1b_doc_bytes": 1170475,
+ "v1b_docs": 381,
+ "target_bytes": 78797,
+ "taken_bytes": 78880,
+ "taken_docs": 35,
+ "share_v1b": 0.0022513429961345953,
+ "stratum_seed": 8982329160359006428
+ },
+ "github/Swift": {
+ "v1b_doc_bytes": 2856150,
+ "v1b_docs": 359,
+ "target_bytes": 192278,
+ "taken_bytes": 192573,
+ "taken_docs": 31,
+ "share_v1b": 0.005493644288352869,
+ "stratum_seed": 16332281041098519257
+ },
+ "github/TypeScript": {
+ "v1b_doc_bytes": 19920149,
+ "v1b_docs": 4367,
+ "target_bytes": 1341035,
+ "taken_bytes": 1341428,
+ "taken_docs": 293,
+ "share_v1b": 0.038315289034885465,
+ "stratum_seed": 15714588800719988091
+ },
+ "stdlib/python": {
+ "v1b_doc_bytes": 5963232,
+ "v1b_docs": 257,
+ "target_bytes": 401448,
+ "taken_bytes": 403578,
+ "taken_docs": 19,
+ "share_v1b": 0.01146994220083786,
+ "stratum_seed": 10264616863029887287
+ },
+ "tinystories/en": {
+ "v1b_doc_bytes": 19117447,
+ "v1b_docs": 21990,
+ "target_bytes": 1286997,
+ "taken_bytes": 1287622,
+ "taken_docs": 1506,
+ "share_v1b": 0.03677133677133158,
+ "stratum_seed": 15186169854288305019
+ }
+ },
+ "prefix_composition": {
+ "60000": {
+ "github/C": 0.0653,
+ "github/C#": 0.0566,
+ "github/C++": 0.0761,
+ "github/Go": 0.1088,
+ "github/Java": 0.1516,
+ "github/JavaScript": 0.0344,
+ "github/Kotlin": 0.023,
+ "github/PHP": 0.0733,
+ "github/Python": 0.1093,
+ "github/Ruby": 0.0029,
+ "github/Rust": 0.0047,
+ "github/Scala": 0.0998,
+ "github/TypeScript": 0.0985,
+ "tinystories/en": 0.0957
+ },
+ "200000": {
+ "github/C": 0.0522,
+ "github/C#": 0.0811,
+ "github/C++": 0.0665,
+ "github/Go": 0.0578,
+ "github/Java": 0.1786,
+ "github/JavaScript": 0.0725,
+ "github/Kotlin": 0.0673,
+ "github/PHP": 0.0652,
+ "github/Python": 0.0327,
+ "github/Ruby": 0.0389,
+ "github/Rust": 0.0801,
+ "github/Scala": 0.0332,
+ "github/TypeScript": 0.0592,
+ "stdlib/python": 0.0347,
+ "tinystories/en": 0.08
+ },
+ "2000000": {
+ "books/en": 0.445,
+ "books/fr": 0.1675,
+ "github/C": 0.0221,
+ "github/C#": 0.0211,
+ "github/C++": 0.0368,
+ "github/Go": 0.0247,
+ "github/Java": 0.0493,
+ "github/JavaScript": 0.0177,
+ "github/Kotlin": 0.0219,
+ "github/PHP": 0.0249,
+ "github/Python": 0.0258,
+ "github/Ruby": 0.0137,
+ "github/Rust": 0.0321,
+ "github/Scala": 0.027,
+ "github/Shell": 0.0022,
+ "github/Swift": 0.0044,
+ "github/TypeScript": 0.0276,
+ "stdlib/python": 0.009,
+ "tinystories/en": 0.0272
+ },
+ "2400000": {
+ "books/en": 0.371,
+ "books/fr": 0.167,
+ "github/C": 0.0226,
+ "github/C#": 0.0279,
+ "github/C++": 0.0435,
+ "github/Go": 0.0303,
+ "github/Java": 0.0479,
+ "github/JavaScript": 0.0385,
+ "github/Kotlin": 0.0187,
+ "github/PHP": 0.0325,
+ "github/Python": 0.0325,
+ "github/Ruby": 0.0178,
+ "github/Rust": 0.031,
+ "github/Scala": 0.037,
+ "github/Shell": 0.0018,
+ "github/Swift": 0.0037,
+ "github/TypeScript": 0.0299,
+ "stdlib/python": 0.0112,
+ "tinystories/en": 0.0351
+ },
+ "4800000": {
+ "books/en": 0.3315,
+ "books/fr": 0.1513,
+ "github/C": 0.0246,
+ "github/C#": 0.0289,
+ "github/C++": 0.0453,
+ "github/Go": 0.0247,
+ "github/Java": 0.0545,
+ "github/JavaScript": 0.0276,
+ "github/Kotlin": 0.0375,
+ "github/PHP": 0.0361,
+ "github/Python": 0.0303,
+ "github/Ruby": 0.0221,
+ "github/Rust": 0.0335,
+ "github/Scala": 0.0421,
+ "github/Shell": 0.0022,
+ "github/Swift": 0.0054,
+ "github/TypeScript": 0.0532,
+ "stdlib/python": 0.0124,
+ "tinystories/en": 0.0369
+ },
+ "10000000": {
+ "books/en": 0.3445,
+ "books/fr": 0.1554,
+ "github/C": 0.0242,
+ "github/C#": 0.0303,
+ "github/C++": 0.0448,
+ "github/Go": 0.0321,
+ "github/Java": 0.0526,
+ "github/JavaScript": 0.0343,
+ "github/Kotlin": 0.0276,
+ "github/PHP": 0.0351,
+ "github/Python": 0.0345,
+ "github/Ruby": 0.0186,
+ "github/Rust": 0.0342,
+ "github/Scala": 0.0398,
+ "github/Shell": 0.002,
+ "github/Swift": 0.0053,
+ "github/TypeScript": 0.0384,
+ "stdlib/python": 0.0102,
+ "tinystories/en": 0.036
+ }
+ },
+ "docs_file": "/workspace/spira_shared/hashing_gen/m8_v1b/sample/v1b_sample_docs.json",
+ "peak_rss_MB": 80,
+ "elapsed_s": 0.4
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/smoke/equiv/done b/results/hashing/m8_v1b/smoke/equiv/done
new file mode 100644
index 0000000000000000000000000000000000000000..24a95213584794ee3a01d08f00e511073159f613
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/equiv/done
@@ -0,0 +1 @@
+EQUIV_DONE
diff --git a/results/hashing/m8_v1b/smoke/equiv/run_cm/rss_cm.tsv b/results/hashing/m8_v1b/smoke/equiv/run_cm/rss_cm.tsv
new file mode 100644
index 0000000000000000000000000000000000000000..383465b9096e5a6db9a7e073408476df26ee80c3
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/equiv/run_cm/rss_cm.tsv
@@ -0,0 +1,25 @@
+1792856788 0.0 33620 load 0
+1792856798 10.0 525168 snn_ep1 0
+1792856808 20.0 525172 snn_ep1 0
+1792856818 30.0 525172 snn_ep1 0
+1792856828 40.0 525172 snn_ep1 0
+1792856838 50.0 525172 snn_ep1 0
+1792856848 60.0 525172 snn_ep1 0
+1792856859 0.0 33652 load 0
+1792856869 10.0 854516 prepare 0
+1792856879 20.0 540728 snn_ep2 0
+1792856889 30.0 540728 snn_ep2 0
+1792856899 40.0 540728 snn_ep2 0
+1792856909 50.0 540728 snn_ep2 0
+1792856919 60.0 540728 snn_ep2 0
+1792856929 70.0 741676 am_write 0
+1792856939 80.0 766860 calibrate_save 0
+1792856949 90.0 766860 calibrate_save 0
+1792856959 100.0 766860 calibrate_save 0
+1792856969 110.0 766860 calibrate_save 0
+1792856979 120.0 766860 calibrate_save 0
+1792856989 130.0 766860 calibrate_save 0
+1792856999 140.0 766860 calibrate_save 0
+1792857009 150.0 766860 calibrate_save 0
+1792857019 160.0 766860 calibrate_save 0
+1792857029 170.0 766860 calibrate_save 0
diff --git a/results/hashing/m8_v1b/smoke/equiv/run_ctl/rss_ctl.tsv b/results/hashing/m8_v1b/smoke/equiv/run_ctl/rss_ctl.tsv
new file mode 100644
index 0000000000000000000000000000000000000000..cead7f65fc425d05b0c5ab4b189dd1d1836b8e09
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/equiv/run_ctl/rss_ctl.tsv
@@ -0,0 +1,10 @@
+1792857080 0.0 33552 load 0
+1792857090 10.0 265612 snn_ep1 0
+1792857100 20.0 265612 snn_ep1 0
+1792857111 0.0 33696 load 0
+1792857121 10.0 270120 snn_ep2 0
+1792857131 20.0 270120 snn_ep2 0
+1792857141 30.0 499384 calibrate_save 0
+1792857151 40.0 499384 calibrate_save 0
+1792857161 50.0 499384 calibrate_save 0
+1792857171 60.0 499384 calibrate_save 0
diff --git a/results/hashing/m8_v1b/smoke/full_cm/results.jsonl b/results/hashing/m8_v1b/smoke/full_cm/results.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..99f8530bd71a8b2d7d238a2aa18912f87a6da8cb
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/full_cm/results.jsonl
@@ -0,0 +1 @@
+{"arm": "cm", "window": "seen", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 500, "fused_invocab_pct": 99.638, "fused_all_pct": 99.2, "snn_invocab_pct": 55.435, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [26.00268105191694], "eval_s": 17.9, "peak_rss_mb": 2040.6, "ckpt_sha256": "ffb7d275cfdbe8a8c8bfcb28d5581ef8ae0836fa8330772d58e14fe48baa6315", "wall_s": 363.1}
diff --git a/results/hashing/m8_v1b/smoke/full_cm/rss_cm.tsv b/results/hashing/m8_v1b/smoke/full_cm/rss_cm.tsv
new file mode 100644
index 0000000000000000000000000000000000000000..03c72940e02f9c3d2fb8448e38d354e5265a0708
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/full_cm/rss_cm.tsv
@@ -0,0 +1,37 @@
+1792857355 0.0 33536 load 0
+1792857365 10.0 706084 build 0
+1792857375 20.1 759364 build 0
+1792857385 30.1 345296 prepare 0
+1792857396 40.4 952120 snn_ep1 0
+1792857406 50.4 952124 snn_ep1 0
+1792857416 60.4 952124 snn_ep1 500
+1792857426 70.4 952124 snn_ep1 500
+1792857436 80.4 952124 snn_ep1 1000
+1792857446 90.4 952128 snn_ep1 1000
+1792857456 100.4 952128 snn_ep1 1500
+1792857466 110.4 952128 snn_ep1 1500
+1792857476 120.4 952128 snn_ep1 2000
+1792857486 130.4 952128 snn_ep1 2000
+1792857496 140.4 952128 snn_ep1 2500
+1792857506 150.4 1034540 am_write 3000
+1792857516 160.4 1165568 am_write 3000
+1792857526 170.5 1165576 calibrate_save 3000
+1792857536 180.5 1165576 calibrate_save 3000
+1792857546 190.5 1165576 calibrate_save 3000
+1792857556 200.5 1165576 calibrate_save 3000
+1792857566 210.5 1165576 calibrate_save 3000
+1792857576 220.5 1165576 calibrate_save 3000
+1792857586 230.5 1165576 calibrate_save 3000
+1792857596 240.5 1165576 calibrate_save 3000
+1792857606 250.5 1165576 calibrate_save 3000
+1792857616 260.5 1165576 calibrate_save 3000
+1792857626 270.5 1193884 calibrate_save 3000
+1792857636 280.5 1199120 calibrate_save 3000
+1792857646 290.5 1239336 calibrate_save 3000
+1792857656 300.5 1251812 calibrate_save 3000
+1792857666 310.5 1634572 calibrate_save 3000
+1792857676 320.5 1651596 calibrate_save 3000
+1792857686 330.5 1237912 calibrate_save 3000
+1792857696 340.5 1840924 calibrate_save 3000
+1792857706 350.5 1218424 eval_seen 3000
+1792857716 360.5 1218424 eval_seen 3000
diff --git a/results/hashing/m8_v1b/smoke/full_ctl/results.jsonl b/results/hashing/m8_v1b/smoke/full_ctl/results.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..b37448e47dac93e288c169dd355a4cb70daec6fd
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/full_ctl/results.jsonl
@@ -0,0 +1 @@
+{"arm": "ctl", "window": "seen", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 500, "fused_invocab_pct": 100.0, "fused_all_pct": 99.4, "snn_invocab_pct": 92.754, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [72.32949078360733], "eval_s": 6.0, "peak_rss_mb": 1202.6, "ckpt_sha256": "a8abab04085576783c6a0bcb557a9aefa7cbe7b41ec9e316a91cb8e1ad4e47a7", "wall_s": 170.1}
diff --git a/results/hashing/m8_v1b/smoke/full_ctl/rss_ctl.tsv b/results/hashing/m8_v1b/smoke/full_ctl/rss_ctl.tsv
new file mode 100644
index 0000000000000000000000000000000000000000..6dc9dc6f5534d9af93d8e3f794a54be282032440
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/full_ctl/rss_ctl.tsv
@@ -0,0 +1,17 @@
+1792857184 0.0 33560 load 0
+1792857194 10.0 694092 build 0
+1792857204 20.0 678068 build 0
+1792857214 30.0 601212 snn_ep1 0
+1792857224 40.0 601216 snn_ep1 500
+1792857234 50.0 601216 snn_ep1 1000
+1792857244 60.0 601216 snn_ep1 2000
+1792857254 70.0 601216 snn_ep1 2500
+1792857264 80.0 814648 am_write 3000
+1792857274 90.1 814648 am_write 3000
+1792857284 100.1 831040 calibrate_save 3000
+1792857294 110.1 831040 calibrate_save 3000
+1792857304 120.1 831040 calibrate_save 3000
+1792857314 130.1 859352 calibrate_save 3000
+1792857324 140.1 884128 calibrate_save 3000
+1792857334 150.1 835480 calibrate_save 3000
+1792857344 160.1 1231532 calibrate_save 3000
diff --git a/results/hashing/m8_v1b/smoke/prefix_composition.txt b/results/hashing/m8_v1b/smoke/prefix_composition.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1b6ef1877ed47a53c91224d391ad139c28aea7b6
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/prefix_composition.txt
@@ -0,0 +1,4 @@
+seen window 200000 doc bytes 198903 {'github': 88.5, 'stdlib/python': 3.5, 'tinystories/en': 8.0}
+SNN 600k patches 2791343 doc bytes 2785708 {'books/en': 31.9, 'books/fr': 14.4, 'github': 48.7, 'stdlib/python': 1.0, 'tinystories/en': 4.1}
+AM 1.2M patches 5554968 doc bytes 5546100 {'books/en': 35.1, 'books/fr': 16.1, 'github': 44.4, 'stdlib/python': 1.1, 'tinystories/en': 3.4}
+whole sample 35128951 doc bytes 35068107 {'books/en': 35.8, 'books/fr': 13.5, 'github': 46.0, 'stdlib/python': 1.2, 'tinystories/en': 3.7}
diff --git a/results/hashing/m8_v1b/smoke/smoke_done b/results/hashing/m8_v1b/smoke/smoke_done
new file mode 100644
index 0000000000000000000000000000000000000000..b68532b84eb6ce16bd89b6bd100495f1fe321032
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/smoke_done
@@ -0,0 +1,2 @@
+smoke_ctl exit 0
+smoke_cm exit 0
diff --git a/results/hashing/m8_v1b/smoke/verdict_M8v1b.v1_69a6a739.py b/results/hashing/m8_v1b/smoke/verdict_M8v1b.v1_69a6a739.py
new file mode 100644
index 0000000000000000000000000000000000000000..aa4362f58eba9ffd2ef3a458b1956aaf9df3b860
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/verdict_M8v1b.v1_69a6a739.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict M8 v1b (cm = M8 neurones CM concat, contre ctl = même code sans CM, budget égal), chemin v4.2.
+Dérivé de lever2_sparse/code/verdict_SP.py (sha256 7a6d5414…a2deb, copie : verdict_SP.py.orig_ref). Calculs identiques (positions in-vocab dans
+les DEUX bras, taux APPARIÉS même dénominateur, McNemar exact bilatéral, bootstrap apparié blocs 512 o B=10 000 seed 0, bootstrap positions seed 25).
+SEULS changements : (1) bras ctl/cm lus dans m8_v1b/runs ; (2) fenêtre seen = v1b_sample[:200 000] (audit trained_frac identique) ;
+(3) test_v3 ajoutée, VALIDE ssi recompte 64 o de l'échantillon = 0 ET recompte v1b = 0 ET drapeau GO_CHECKER_PASS présent, sinon exclue ;
+(4) queries rapportée À PART (hors règle) ; neither_code non évaluée (exclue) ; (5) positions propres : chaque fenêtre fraîche exige
+confirmed_window_positions = 0 dans le recompte de l'échantillon (sinon fenêtre NON COMPARABLE, exclue) ; test20k strict = masque
+mask_oldtest_strict.npz (old_local_v1 ∪ broad_local_v1) ∪ échantillon (0 position, vérifié) ; (6) gain significatif = McNemar p<0,05 ET c>b ET
+IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+epochs, ticks/époque, sha256 des données) ou seen NON COMPARABLE (trained_frac < 0,99 dans un bras).
+Règle : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+ET aucune perte significative sur une fenêtre valide (seen + fraîches valides) ; sinon REJETÉ."""
+import sys, os, json, math, hashlib, numpy as np
+B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; D = f"{B8}/runs"; OP = f"{B8}/verdict"; RT, CT = "ctl", "cm"
+SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; SEP = ["queries"]
+RCNAME = {"fc2": "fc2", "fresh_en": "m7_fresh_en", "fresh_fr": "m7_fresh_fr", "test20k": "m7_test20k", "test_v3": "corpus_v3_test", "queries": "m7_queries"}
+BLK, NB, SEED = 512, 10000, 0
+os.makedirs(OP, exist_ok=True); MS = np.load(MASKP)
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+# ---- budgets égaux (sinon NON MESURABLE)
+RES = [json.loads(l) for l in open(f"{D}/results.jsonl") if l.strip()]
+def arm_field(arm, f):
+ v = {json.dumps(r.get(f), sort_keys=True) for r in RES if r.get("arm") == arm}; return json.loads(v.pop()) if len(v) == 1 else "INCOHERENT"
+BUD = {f: {RT: arm_field(RT, f), CT: arm_field(CT, f)} for f in ("snn_tokens", "am_tokens", "epochs", "ticks_per_epoch", "data_sha256")}
+BUDGET_OK = all(v[RT] == v[CT] and v[RT] != "INCOHERENT" and v[RT] is not None for v in BUD.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA \
+ and BUD["ticks_per_epoch"][RT] == [BUD["snn_tokens"][RT]] * BUD["epochs"][RT]
+# ---- propreté des fenêtres fraîches
+RCS = json.load(open(RC_SAMPLE)); RCV = json.load(open(RC_V1B))["overlap64_recount_v1b"]["per_window"]
+assert RCS["sha256"] == SAMPLE_SHA, "recompte : échantillon différent"
+CLEAN = {}
+for w, k in RCNAME.items():
+ cs = RCS["windows"][k]["confirmed_window_positions"]; cv = RCV[k]["confirmed_window_positions"] if k in RCV else None
+ CLEAN[w] = {"sample_confirmed_window_positions": cs, "v1b_confirmed_window_positions": cv, "window_sha256_recount": RCS["windows"][k]["window_sha256"]}
+VALID = {w: CLEAN[w]["sample_confirmed_window_positions"] == 0 for w in FRESH + SEP}
+VALID["test_v3"] = VALID["test_v3"] and CLEAN["test_v3"]["v1b_confirmed_window_positions"] == 0 and os.path.exists(GO)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN + SEP:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{D}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ if w in RCNAME: assert str(A["window_sha256"]) == CLEAN[w]["window_sha256_recount"], f"{w}: fenêtre != fenêtre recomptée"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": CLEAN["test20k"]["sample_confirmed_window_positions"],
+ "excluded_union": int((bo | bb_).sum()), "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ ia1, ib1 = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k; one_side = int((ia1 ^ ib1).sum())
+ k = k & A["invocab"].astype(bool) & B["invocab"].astype(bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); p = binp(b, c)
+ acc_a, acc_b = 100 * (ha & k).sum() / max(1, k.sum()), 100 * (hb & k).sum() / max(1, k.sum())
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], k[k], nbk); sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], k[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, k)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b and lo > 0), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "invocab_identical": inv_same, "n_invocab_one_side_only_dropped": one_side, "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a), "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p,
+ "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m, "sig_gain": gain, "sig_loss": loss,
+ "boot_conflict": bool((p < 0.05 and c > b and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"]),
+ "valid": (True if w == "seen" else VALID[w]), "in_rule": w in WIN, "clean_recount": CLEAN.get(w)}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+# ---- audit trained_frac du seen (identique à verdict_SP, fenêtre = échantillon[:200 000])
+_A = np.load(f"{D}/{RT}__seen.npz"); _st, _ln = _A["tgt_start"].astype(np.int64), _A["tgt_len"].astype(np.int64)
+_contig = bool(np.all(_st[1:] == _st[:-1] + _ln[:-1]) and _st[0] > 0 and _st[0] <= int(_ln.max()))
+_sb = open(SAMPLE, "rb").read(); _wok = hashlib.sha256(_sb[:200_000]).hexdigest() == R["seen"]["window_sha256"] and hashlib.sha256(_sb).hexdigest() == SAMPLE_SHA; del _sb
+_ksnn = {"ref": BUD["snn_tokens"][RT], "cand": BUD["snn_tokens"][CT]}
+_k, _ha, _hb, _iv = KEEP["seen"]; _ivb = _k & _iv & np.load(f"{D}/{CT}__seen.npz")["invocab"].astype(bool); _ctx = np.arange(len(_st))
+SEEN_AUDIT = {"window_is_sample_prefix_200000": _wok, "targets_contiguous_from_patch1": _contig, "snn_tokens": _ksnn,
+ "max_ctx_patch_index": int(_ctx.max()), "max_byte_evaluated": int((_st + _ln).max()), "invocab_both_n": int(_ivb.sum())}
+for side in ("ref", "cand"):
+ ok = _wok and _contig and isinstance(_ksnn[side], int)
+ n_tr = int((_ivb & (_ctx < _ksnn[side])).sum()) if ok else None
+ SEEN_AUDIT[f"trained_invocab_n_{side}"] = n_tr; SEEN_AUDIT[f"trained_frac_{side}"] = (n_tr / max(1, int(_ivb.sum()))) if n_tr is not None else None
+SEEN_OK = all(SEEN_AUDIT[f"trained_frac_{x}"] is not None and SEEN_AUDIT[f"trained_frac_{x}"] >= 0.99 for x in ("ref", "cand"))
+SEEN_AUDIT["seen_comparable"] = SEEN_OK; print("seen_audit", json.dumps(SEEN_AUDIT), flush=True)
+FV = [w for w in FRESH if VALID[w]]
+def gapcalc(GW):
+ gap = {}
+ for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt),
+ "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+ dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GW], axis=0))
+ gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+ gap["windows"] = GW; return gap
+GAPS = {"with_test_v3": gapcalc(FV), "without_test_v3": gapcalc([w for w in FV if w != "test_v3"])}
+VW = ["seen"] + FV
+L = [w for w in VW if R[w]["sig_loss"]]; G = [w for w in VW if R[w]["sig_gain"]]; GF = [w for w in FV if R[w]["sig_gain"]]
+why = []
+if not BUDGET_OK: why.append("budgets inégaux ou incohérents : " + json.dumps(BUD))
+if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+if BUDGET_OK and SEEN_OK:
+ dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+ if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+else: dec = "NON MESURABLE"
+out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+ "budgets": BUD, "budget_ok": BUDGET_OK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux ou seen non comparable",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
+ "results_jsonl_sha256": hashlib.sha256(open(f"{D}/results.jsonl", "rb").read()).hexdigest(),
+ "recount_sample_sha256": hashlib.sha256(open(RC_SAMPLE, "rb").read()).hexdigest(), "mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}/verdict_M8v1b.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b {SAMPLE_SHA[:8]}…\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).", "",
+ "| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|---|"]
+for w in WIN + SEP:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ if w in SEP: dd += " (à part, hors règle)"
+ elif not r["valid"]: dd = "EXCLUE (non propre / non confirmée)"
+ md.append(f"| {w}{' strict' if w == 'test20k' else ''} | {r['valid']} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd} |")
+md += ["", f"neither_code : exclue (non évaluée). test20k strict : {EX.get('excluded_union')} positions exclues (old ∪ broad), 0 par l'échantillon.",
+ f"Budgets : {json.dumps(BUD)} → {'égaux' if BUDGET_OK else 'NON ÉGAUX'}.",
+ f"Audit seen : trained_frac ctl {SEEN_AUDIT['trained_frac_ref']} / cm {SEEN_AUDIT['trained_frac_cand']} → seen {'COMPARABLE' if SEEN_OK else 'NON COMPARABLE'}.",
+ f"Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl {GAPS['with_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f} [{GAPS['with_test_v3']['cand_minus_ref']['ci95'][0]:+.3f} ; {GAPS['with_test_v3']['cand_minus_ref']['ci95'][1]:+.3f}] ; sans test_v3 : {GAPS['without_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f}.",
+ f"Script sha256 {out['script_sha256']}.", ""]
+open(f"{OP}/verdict_M8v1b.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m8_v1b/smoke/vtest/done b/results/hashing/m8_v1b/smoke/vtest/done
new file mode 100644
index 0000000000000000000000000000000000000000..9f869b1035b9795d0aca3fb48ace8e281d362d9c
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest/done
@@ -0,0 +1,2 @@
+1
+verdict exit 0
diff --git a/results/hashing/m8_v1b/smoke/vtest/runs/results.jsonl b/results/hashing/m8_v1b/smoke/vtest/runs/results.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..b06631415a0f45cfd45d3a6f50faece7691c406b
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest/runs/results.jsonl
@@ -0,0 +1,14 @@
+{"arm": "ctl", "window": "seen", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 100.0, "fused_all_pct": 99.4, "snn_invocab_pct": 92.754, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [72.32949078360733], "eval_s": 4.1, "peak_rss_mb": 1202.6, "ckpt_sha256": "a8abab04085576783c6a0bcb557a9aefa7cbe7b41ec9e316a91cb8e1ad4e47a7", "wall_s": 170.1}
+{"arm": "ctl", "window": "fc2", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 99.4, "snn_invocab_pct": 92.754, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [72.32949078360733], "eval_s": 4.3, "peak_rss_mb": 1202.6, "ckpt_sha256": "a8abab04085576783c6a0bcb557a9aefa7cbe7b41ec9e316a91cb8e1ad4e47a7", "wall_s": 170.1}
+{"arm": "ctl", "window": "fresh_en", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.667, "fused_all_pct": 99.4, "snn_invocab_pct": 92.754, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [72.32949078360733], "eval_s": 3.8, "peak_rss_mb": 1202.6, "ckpt_sha256": "a8abab04085576783c6a0bcb557a9aefa7cbe7b41ec9e316a91cb8e1ad4e47a7", "wall_s": 170.1}
+{"arm": "ctl", "window": "fresh_fr", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 3.597, "fused_all_pct": 99.4, "snn_invocab_pct": 92.754, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [72.32949078360733], "eval_s": 5.4, "peak_rss_mb": 1202.6, "ckpt_sha256": "a8abab04085576783c6a0bcb557a9aefa7cbe7b41ec9e316a91cb8e1ad4e47a7", "wall_s": 170.1}
+{"arm": "ctl", "window": "test20k", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 99.4, "snn_invocab_pct": 92.754, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [72.32949078360733], "eval_s": 4.0, "peak_rss_mb": 1202.6, "ckpt_sha256": "a8abab04085576783c6a0bcb557a9aefa7cbe7b41ec9e316a91cb8e1ad4e47a7", "wall_s": 170.1}
+{"arm": "ctl", "window": "test_v3", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 99.4, "snn_invocab_pct": 92.754, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [72.32949078360733], "eval_s": 8.1, "peak_rss_mb": 1202.6, "ckpt_sha256": "a8abab04085576783c6a0bcb557a9aefa7cbe7b41ec9e316a91cb8e1ad4e47a7", "wall_s": 170.1}
+{"arm": "ctl", "window": "queries", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 99.4, "snn_invocab_pct": 92.754, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [72.32949078360733], "eval_s": 3.4, "peak_rss_mb": 1202.6, "ckpt_sha256": "a8abab04085576783c6a0bcb557a9aefa7cbe7b41ec9e316a91cb8e1ad4e47a7", "wall_s": 170.1}
+{"arm": "cm", "window": "seen", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 99.367, "fused_all_pct": 99.2, "snn_invocab_pct": 55.435, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [26.00268105191694], "eval_s": 10.4, "peak_rss_mb": 2040.6, "ckpt_sha256": "ffb7d275cfdbe8a8c8bfcb28d5581ef8ae0836fa8330772d58e14fe48baa6315", "wall_s": 363.1}
+{"arm": "cm", "window": "fc2", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 99.2, "snn_invocab_pct": 55.435, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [26.00268105191694], "eval_s": 10.0, "peak_rss_mb": 2040.6, "ckpt_sha256": "ffb7d275cfdbe8a8c8bfcb28d5581ef8ae0836fa8330772d58e14fe48baa6315", "wall_s": 363.1}
+{"arm": "cm", "window": "fresh_en", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 99.2, "snn_invocab_pct": 55.435, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [26.00268105191694], "eval_s": 9.8, "peak_rss_mb": 2040.6, "ckpt_sha256": "ffb7d275cfdbe8a8c8bfcb28d5581ef8ae0836fa8330772d58e14fe48baa6315", "wall_s": 363.1}
+{"arm": "cm", "window": "fresh_fr", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 2.878, "fused_all_pct": 99.2, "snn_invocab_pct": 55.435, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [26.00268105191694], "eval_s": 14.6, "peak_rss_mb": 2040.6, "ckpt_sha256": "ffb7d275cfdbe8a8c8bfcb28d5581ef8ae0836fa8330772d58e14fe48baa6315", "wall_s": 363.1}
+{"arm": "cm", "window": "test20k", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 99.2, "snn_invocab_pct": 55.435, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [26.00268105191694], "eval_s": 10.7, "peak_rss_mb": 2040.6, "ckpt_sha256": "ffb7d275cfdbe8a8c8bfcb28d5581ef8ae0836fa8330772d58e14fe48baa6315", "wall_s": 363.1}
+{"arm": "cm", "window": "test_v3", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 99.2, "snn_invocab_pct": 55.435, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [26.00268105191694], "eval_s": 16.2, "peak_rss_mb": 2040.6, "ckpt_sha256": "ffb7d275cfdbe8a8c8bfcb28d5581ef8ae0836fa8330772d58e14fe48baa6315", "wall_s": 363.1}
+{"arm": "cm", "window": "queries", "snn_tokens": 600000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 99.2, "snn_invocab_pct": 55.435, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 600000, "n_am": 1200000, "snn_bytes_read": 2791343, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [26.00268105191694], "eval_s": 9.7, "peak_rss_mb": 2040.6, "ckpt_sha256": "ffb7d275cfdbe8a8c8bfcb28d5581ef8ae0836fa8330772d58e14fe48baa6315", "wall_s": 363.1}
diff --git a/results/hashing/m8_v1b/smoke/vtest/verdict/verdict_M8v1b.json b/results/hashing/m8_v1b/smoke/vtest/verdict/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..9f6ce5ebfd32a5dbe6ccdf01c0698d7f4d8baf93
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest/verdict/verdict_M8v1b.json
@@ -0,0 +1,389 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 600000,
+ "cm": 600000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_ok": false,
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "NON MESURABLE",
+ "reasons": [
+ "budgets inégaux ou incohérents : {\"snn_tokens\": {\"ctl\": 600000, \"cm\": 600000}, \"am_tokens\": {\"ctl\": 1200000, \"cm\": 1200000}, \"epochs\": {\"ctl\": 1, \"cm\": 1}, \"ticks_per_epoch\": {\"ctl\": [3000], \"cm\": [3000]}, \"data_sha256\": {\"ctl\": \"9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b\", \"cm\": \"9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b\"}}"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux ou seen non comparable",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 600000,
+ "cand": 600000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "69a6a73991458ad8da675190c2ac797311fbe117cb4c7656e441880d474e2da7",
+ "inputs_sha256": {
+ "ctl__seen.npz": "946032bb309efe4b0283da009610a9473c514cc987f04b7486dc00dca614bb2e",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "ca73f541bf12144d5136faf1ee54fe36b688361fb8752bcca239bd590f084b29",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "d8c4431270de50778f061341d055370d697e363ff7f03a07fe64cb654cc42c5f",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/smoke/vtest/verdict/verdict_M8v1b.md b/results/hashing/m8_v1b/smoke/vtest/verdict/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..c422b75f1d0095e2d8615fb972127fac9d9c6472
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest/verdict/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**NON MESURABLE** — budgets inégaux ou incohérents : {"snn_tokens": {"ctl": 600000, "cm": 600000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}}
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 600000, "cm": 600000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} → NON ÉGAUX.
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 69a6a73991458ad8da675190c2ac797311fbe117cb4c7656e441880d474e2da7.
+
diff --git a/results/hashing/m8_v1b/smoke/vtest/verdict_r2/verdict_M8v1b.json b/results/hashing/m8_v1b/smoke/vtest/verdict_r2/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..8218e1842920c00df8e9ee174a0ea90237f67dd7
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest/verdict_r2/verdict_M8v1b.json
@@ -0,0 +1,412 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 600000,
+ "cm": 600000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": false,
+ "cm": false
+ }
+ },
+ "budget_ok": false,
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "NON MESURABLE",
+ "reasons": [
+ "passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "6bfb8834c491131f6beda012138dc69c5102c066a6e8d8eb41fa98f446f97f1e",
+ "inputs_sha256": {
+ "ctl__seen.npz": "946032bb309efe4b0283da009610a9473c514cc987f04b7486dc00dca614bb2e",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "ca73f541bf12144d5136faf1ee54fe36b688361fb8752bcca239bd590f084b29",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "d8c4431270de50778f061341d055370d697e363ff7f03a07fe64cb654cc42c5f",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/smoke/vtest/verdict_r2/verdict_M8v1b.md b/results/hashing/m8_v1b/smoke/vtest/verdict_r2/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..c4b1a204000183901bbd819c47859a50a0d7948b
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest/verdict_r2/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**NON MESURABLE** — passe SNN incomplète : tokens entraînés/époque (ticks × 1) ctl [3000] / cm [3000] != snn_tokens 600000
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 600000, "cm": 600000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": false, "cm": false}} → NON OK.
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 6bfb8834c491131f6beda012138dc69c5102c066a6e8d8eb41fa98f446f97f1e.
+
diff --git a/results/hashing/m8_v1b/smoke/vtest/verdict_test_copy.py b/results/hashing/m8_v1b/smoke/vtest/verdict_test_copy.py
new file mode 100644
index 0000000000000000000000000000000000000000..fd3d1dab849ec769e1f52b4eb8c852139c8e6102
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest/verdict_test_copy.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict M8 v1b (cm = M8 neurones CM concat, contre ctl = même code sans CM, budget égal), chemin v4.2.
+Dérivé de lever2_sparse/code/verdict_SP.py (sha256 7a6d5414…a2deb, copie : verdict_SP.py.orig_ref). Calculs identiques (positions in-vocab dans
+les DEUX bras, taux APPARIÉS même dénominateur, McNemar exact bilatéral, bootstrap apparié blocs 512 o B=10 000 seed 0, bootstrap positions seed 25).
+SEULS changements : (1) bras ctl/cm lus dans m8_v1b/runs ; (2) fenêtre seen = v1b_sample[:200 000] (audit trained_frac identique) ;
+(3) test_v3 ajoutée, VALIDE ssi recompte 64 o de l'échantillon = 0 ET recompte v1b = 0 ET drapeau GO_CHECKER_PASS présent, sinon exclue ;
+(4) queries rapportée À PART (hors règle) ; neither_code non évaluée (exclue) ; (5) positions propres : chaque fenêtre fraîche exige
+confirmed_window_positions = 0 dans le recompte de l'échantillon (sinon fenêtre NON COMPARABLE, exclue) ; test20k strict = masque
+mask_oldtest_strict.npz (old_local_v1 ∪ broad_local_v1) ∪ échantillon (0 position, vérifié) ; (6) gain significatif = McNemar p<0,05 ET c>b ET
+IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+epochs, ticks/époque, sha256 des données) ou seen NON COMPARABLE (trained_frac < 0,99 dans un bras).
+Règle : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+ET aucune perte significative sur une fenêtre valide (seen + fraîches valides) ; sinon REJETÉ."""
+import sys, os, json, math, hashlib, numpy as np
+B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; D = "/workspace/spira_shared/hashing_gen/m8_v1b/smoke/vtest/runs"; OP = "/workspace/spira_shared/hashing_gen/m8_v1b/smoke/vtest/verdict"; RT, CT = "ctl", "cm"
+SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; SEP = ["queries"]
+RCNAME = {"fc2": "fc2", "fresh_en": "m7_fresh_en", "fresh_fr": "m7_fresh_fr", "test20k": "m7_test20k", "test_v3": "corpus_v3_test", "queries": "m7_queries"}
+BLK, NB, SEED = 512, 10000, 0
+os.makedirs(OP, exist_ok=True); MS = np.load(MASKP)
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+# ---- budgets égaux (sinon NON MESURABLE)
+RES = [json.loads(l) for l in open(f"{D}/results.jsonl") if l.strip()]
+def arm_field(arm, f):
+ v = {json.dumps(r.get(f), sort_keys=True) for r in RES if r.get("arm") == arm}; return json.loads(v.pop()) if len(v) == 1 else "INCOHERENT"
+BUD = {f: {RT: arm_field(RT, f), CT: arm_field(CT, f)} for f in ("snn_tokens", "am_tokens", "epochs", "ticks_per_epoch", "data_sha256")}
+BUDGET_OK = all(v[RT] == v[CT] and v[RT] != "INCOHERENT" and v[RT] is not None for v in BUD.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA \
+ and BUD["ticks_per_epoch"][RT] == [BUD["snn_tokens"][RT]] * BUD["epochs"][RT]
+# ---- propreté des fenêtres fraîches
+RCS = json.load(open(RC_SAMPLE)); RCV = json.load(open(RC_V1B))["overlap64_recount_v1b"]["per_window"]
+assert RCS["sha256"] == SAMPLE_SHA, "recompte : échantillon différent"
+CLEAN = {}
+for w, k in RCNAME.items():
+ cs = RCS["windows"][k]["confirmed_window_positions"]; cv = RCV[k]["confirmed_window_positions"] if k in RCV else None
+ CLEAN[w] = {"sample_confirmed_window_positions": cs, "v1b_confirmed_window_positions": cv, "window_sha256_recount": RCS["windows"][k]["window_sha256"]}
+VALID = {w: CLEAN[w]["sample_confirmed_window_positions"] == 0 for w in FRESH + SEP}
+VALID["test_v3"] = VALID["test_v3"] and CLEAN["test_v3"]["v1b_confirmed_window_positions"] == 0 and os.path.exists(GO)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN + SEP:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{D}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ if w in RCNAME: assert str(A["window_sha256"]) == CLEAN[w]["window_sha256_recount"], f"{w}: fenêtre != fenêtre recomptée"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": CLEAN["test20k"]["sample_confirmed_window_positions"],
+ "excluded_union": int((bo | bb_).sum()), "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ ia1, ib1 = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k; one_side = int((ia1 ^ ib1).sum())
+ k = k & A["invocab"].astype(bool) & B["invocab"].astype(bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); p = binp(b, c)
+ acc_a, acc_b = 100 * (ha & k).sum() / max(1, k.sum()), 100 * (hb & k).sum() / max(1, k.sum())
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], k[k], nbk); sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], k[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, k)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b and lo > 0), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "invocab_identical": inv_same, "n_invocab_one_side_only_dropped": one_side, "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a), "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p,
+ "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m, "sig_gain": gain, "sig_loss": loss,
+ "boot_conflict": bool((p < 0.05 and c > b and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"]),
+ "valid": (True if w == "seen" else VALID[w]), "in_rule": w in WIN, "clean_recount": CLEAN.get(w)}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+# ---- audit trained_frac du seen (identique à verdict_SP, fenêtre = échantillon[:200 000])
+_A = np.load(f"{D}/{RT}__seen.npz"); _st, _ln = _A["tgt_start"].astype(np.int64), _A["tgt_len"].astype(np.int64)
+_contig = bool(np.all(_st[1:] == _st[:-1] + _ln[:-1]) and _st[0] > 0 and _st[0] <= int(_ln.max()))
+_sb = open(SAMPLE, "rb").read(); _wok = hashlib.sha256(_sb[:200_000]).hexdigest() == R["seen"]["window_sha256"] and hashlib.sha256(_sb).hexdigest() == SAMPLE_SHA; del _sb
+_ksnn = {"ref": BUD["snn_tokens"][RT], "cand": BUD["snn_tokens"][CT]}
+_k, _ha, _hb, _iv = KEEP["seen"]; _ivb = _k & _iv & np.load(f"{D}/{CT}__seen.npz")["invocab"].astype(bool); _ctx = np.arange(len(_st))
+SEEN_AUDIT = {"window_is_sample_prefix_200000": _wok, "targets_contiguous_from_patch1": _contig, "snn_tokens": _ksnn,
+ "max_ctx_patch_index": int(_ctx.max()), "max_byte_evaluated": int((_st + _ln).max()), "invocab_both_n": int(_ivb.sum())}
+for side in ("ref", "cand"):
+ ok = _wok and _contig and isinstance(_ksnn[side], int)
+ n_tr = int((_ivb & (_ctx < _ksnn[side])).sum()) if ok else None
+ SEEN_AUDIT[f"trained_invocab_n_{side}"] = n_tr; SEEN_AUDIT[f"trained_frac_{side}"] = (n_tr / max(1, int(_ivb.sum()))) if n_tr is not None else None
+SEEN_OK = all(SEEN_AUDIT[f"trained_frac_{x}"] is not None and SEEN_AUDIT[f"trained_frac_{x}"] >= 0.99 for x in ("ref", "cand"))
+SEEN_AUDIT["seen_comparable"] = SEEN_OK; print("seen_audit", json.dumps(SEEN_AUDIT), flush=True)
+FV = [w for w in FRESH if VALID[w]]
+def gapcalc(GW):
+ gap = {}
+ for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt),
+ "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+ dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GW], axis=0))
+ gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+ gap["windows"] = GW; return gap
+GAPS = {"with_test_v3": gapcalc(FV), "without_test_v3": gapcalc([w for w in FV if w != "test_v3"])}
+VW = ["seen"] + FV
+L = [w for w in VW if R[w]["sig_loss"]]; G = [w for w in VW if R[w]["sig_gain"]]; GF = [w for w in FV if R[w]["sig_gain"]]
+why = []
+if not BUDGET_OK: why.append("budgets inégaux ou incohérents : " + json.dumps(BUD))
+if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+if BUDGET_OK and SEEN_OK:
+ dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+ if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+else: dec = "NON MESURABLE"
+out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+ "budgets": BUD, "budget_ok": BUDGET_OK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux ou seen non comparable",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
+ "results_jsonl_sha256": hashlib.sha256(open(f"{D}/results.jsonl", "rb").read()).hexdigest(),
+ "recount_sample_sha256": hashlib.sha256(open(RC_SAMPLE, "rb").read()).hexdigest(), "mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}/verdict_M8v1b.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b {SAMPLE_SHA[:8]}…\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).", "",
+ "| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|---|"]
+for w in WIN + SEP:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ if w in SEP: dd += " (à part, hors règle)"
+ elif not r["valid"]: dd = "EXCLUE (non propre / non confirmée)"
+ md.append(f"| {w}{' strict' if w == 'test20k' else ''} | {r['valid']} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd} |")
+md += ["", f"neither_code : exclue (non évaluée). test20k strict : {EX.get('excluded_union')} positions exclues (old ∪ broad), 0 par l'échantillon.",
+ f"Budgets : {json.dumps(BUD)} → {'égaux' if BUDGET_OK else 'NON ÉGAUX'}.",
+ f"Audit seen : trained_frac ctl {SEEN_AUDIT['trained_frac_ref']} / cm {SEEN_AUDIT['trained_frac_cand']} → seen {'COMPARABLE' if SEEN_OK else 'NON COMPARABLE'}.",
+ f"Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl {GAPS['with_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f} [{GAPS['with_test_v3']['cand_minus_ref']['ci95'][0]:+.3f} ; {GAPS['with_test_v3']['cand_minus_ref']['ci95'][1]:+.3f}] ; sans test_v3 : {GAPS['without_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f}.",
+ f"Script sha256 {out['script_sha256']}.", ""]
+open(f"{OP}/verdict_M8v1b.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m8_v1b/smoke/vtest/verdict_test_copy_r2.py b/results/hashing/m8_v1b/smoke/vtest/verdict_test_copy_r2.py
new file mode 100644
index 0000000000000000000000000000000000000000..536ded09cd077f6a2b021f4dca70402b65944bdd
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest/verdict_test_copy_r2.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict M8 v1b (cm = M8 neurones CM concat, contre ctl = même code sans CM, budget égal), chemin v4.2.
+Dérivé de lever2_sparse/code/verdict_SP.py (sha256 7a6d5414…a2deb, copie : verdict_SP.py.orig_ref). Calculs identiques (positions in-vocab dans
+les DEUX bras, taux APPARIÉS même dénominateur, McNemar exact bilatéral, bootstrap apparié blocs 512 o B=10 000 seed 0, bootstrap positions seed 25).
+SEULS changements : (1) bras ctl/cm lus dans m8_v1b/runs ; (2) fenêtre seen = v1b_sample[:200 000] (audit trained_frac identique) ;
+(3) test_v3 ajoutée, VALIDE ssi recompte 64 o de l'échantillon = 0 ET recompte v1b = 0 ET drapeau GO_CHECKER_PASS présent, sinon exclue ;
+(4) queries rapportée À PART (hors règle) ; neither_code non évaluée (exclue) ; (5) positions propres : chaque fenêtre fraîche exige
+confirmed_window_positions = 0 dans le recompte de l'échantillon (sinon fenêtre NON COMPARABLE, exclue) ; test20k strict = masque
+mask_oldtest_strict.npz (old_local_v1 ∪ broad_local_v1) ∪ échantillon (0 position, vérifié) ; (6) gain significatif = McNemar p<0,05 ET c>b ET
+IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+epochs, ticks/époque, sha256 des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick != snn_tokens), ou seen NON COMPARABLE
+(trained_frac < 0,99 dans un bras ; trained_frac calculé sur les tokens RÉELLEMENT entraînés = ticks × 1, pas sur snn_tokens déclaré).
+Révision 2 (12 h 08 Toronto) : contrôle d'unités rendu explicite (TOKENS_PER_TICK = 1, spiking.py l. 471-539) et audit seen sur tokens réellement entraînés.
+Règle : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+ET aucune perte significative sur une fenêtre valide (seen + fraîches valides) ; sinon REJETÉ."""
+import sys, os, json, math, hashlib, numpy as np
+B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; D = "/workspace/spira_shared/hashing_gen/m8_v1b/smoke/vtest/runs"; OP = "/workspace/spira_shared/hashing_gen/m8_v1b/smoke/vtest/verdict_r2"; RT, CT = "ctl", "cm"
+SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; SEP = ["queries"]
+RCNAME = {"fc2": "fc2", "fresh_en": "m7_fresh_en", "fresh_fr": "m7_fresh_fr", "test20k": "m7_test20k", "test_v3": "corpus_v3_test", "queries": "m7_queries"}
+BLK, NB, SEED = 512, 10000, 0
+os.makedirs(OP, exist_ok=True); MS = np.load(MASKP)
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+# ---- budgets égaux (sinon NON MESURABLE)
+RES = [json.loads(l) for l in open(f"{D}/results.jsonl") if l.strip()]
+def arm_field(arm, f):
+ v = {json.dumps(r.get(f), sort_keys=True) for r in RES if r.get("arm") == arm}; return json.loads(v.pop()) if len(v) == 1 else "INCOHERENT"
+BUD = {f: {RT: arm_field(RT, f), CT: arm_field(CT, f)} for f in ("snn_tokens", "am_tokens", "epochs", "ticks_per_epoch", "data_sha256")}
+# Unités : spira/spiking.py SpikingCore.train_pass (l. 471-539) fait UN tick par token SNN (neurons[t] = token t, "ticks": T = len(cols)),
+# donc tokens SNN entraînés par époque = ticks × TOKENS_PER_TICK, TOKENS_PER_TICK = 1. Contrôles : (i) égalité cm == ctl de chaque champ ;
+# (ii) données = échantillon ; (iii) chaque époque a entraîné TOUT le budget : ticks × TOKENS_PER_TICK == snn_tokens (sinon passe tronquée).
+TOKENS_PER_TICK = 1
+EQUAL = {f: (v[RT] == v[CT] and v[RT] != "INCOHERENT" and v[RT] is not None) for f, v in BUD.items()}
+TRAINED = {x: ([t * TOKENS_PER_TICK for t in BUD["ticks_per_epoch"][x]] if isinstance(BUD["ticks_per_epoch"][x], list) else None) for x in (RT, CT)}
+FULL = {x: (TRAINED[x] is not None and isinstance(BUD["epochs"][x], int) and len(TRAINED[x]) == BUD["epochs"][x]
+ and all(t == BUD["snn_tokens"][x] for t in TRAINED[x])) for x in (RT, CT)}
+BUDGET_OK = all(EQUAL.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA and FULL[RT] and FULL[CT]
+BUDGET_CHECK = {"equal_cm_ctl": EQUAL, "data_is_sample": BUD["data_sha256"][RT] == SAMPLE_SHA, "tokens_per_tick": TOKENS_PER_TICK,
+ "trained_snn_tokens_per_epoch": TRAINED, "full_budget_each_epoch": FULL}
+# tokens SNN réellement entraînés (pour l'audit seen) = min sur les époques de ticks × TOKENS_PER_TICK, borné par snn_tokens
+TRAINED_MIN = {x: (min(min(TRAINED[x]), BUD["snn_tokens"][x]) if TRAINED[x] and isinstance(BUD["snn_tokens"][x], int) else None) for x in (RT, CT)}
+# ---- propreté des fenêtres fraîches
+RCS = json.load(open(RC_SAMPLE)); RCV = json.load(open(RC_V1B))["overlap64_recount_v1b"]["per_window"]
+assert RCS["sha256"] == SAMPLE_SHA, "recompte : échantillon différent"
+CLEAN = {}
+for w, k in RCNAME.items():
+ cs = RCS["windows"][k]["confirmed_window_positions"]; cv = RCV[k]["confirmed_window_positions"] if k in RCV else None
+ CLEAN[w] = {"sample_confirmed_window_positions": cs, "v1b_confirmed_window_positions": cv, "window_sha256_recount": RCS["windows"][k]["window_sha256"]}
+VALID = {w: CLEAN[w]["sample_confirmed_window_positions"] == 0 for w in FRESH + SEP}
+VALID["test_v3"] = VALID["test_v3"] and CLEAN["test_v3"]["v1b_confirmed_window_positions"] == 0 and os.path.exists(GO)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN + SEP:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{D}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ if w in RCNAME: assert str(A["window_sha256"]) == CLEAN[w]["window_sha256_recount"], f"{w}: fenêtre != fenêtre recomptée"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": CLEAN["test20k"]["sample_confirmed_window_positions"],
+ "excluded_union": int((bo | bb_).sum()), "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ ia1, ib1 = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k; one_side = int((ia1 ^ ib1).sum())
+ k = k & A["invocab"].astype(bool) & B["invocab"].astype(bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); p = binp(b, c)
+ acc_a, acc_b = 100 * (ha & k).sum() / max(1, k.sum()), 100 * (hb & k).sum() / max(1, k.sum())
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], k[k], nbk); sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], k[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, k)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b and lo > 0), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "invocab_identical": inv_same, "n_invocab_one_side_only_dropped": one_side, "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a), "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p,
+ "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m, "sig_gain": gain, "sig_loss": loss,
+ "boot_conflict": bool((p < 0.05 and c > b and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"]),
+ "valid": (True if w == "seen" else VALID[w]), "in_rule": w in WIN, "clean_recount": CLEAN.get(w)}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+# ---- audit trained_frac du seen (identique à verdict_SP, fenêtre = échantillon[:200 000])
+_A = np.load(f"{D}/{RT}__seen.npz"); _st, _ln = _A["tgt_start"].astype(np.int64), _A["tgt_len"].astype(np.int64)
+_contig = bool(np.all(_st[1:] == _st[:-1] + _ln[:-1]) and _st[0] > 0 and _st[0] <= int(_ln.max()))
+_sb = open(SAMPLE, "rb").read(); _wok = hashlib.sha256(_sb[:200_000]).hexdigest() == R["seen"]["window_sha256"] and hashlib.sha256(_sb).hexdigest() == SAMPLE_SHA; del _sb
+_ksnn = {"ref": TRAINED_MIN[RT], "cand": TRAINED_MIN[CT]} # tokens SNN réellement entraînés (ticks × 1), pas le budget déclaré
+_k, _ha, _hb, _iv = KEEP["seen"]; _ivb = _k & _iv & np.load(f"{D}/{CT}__seen.npz")["invocab"].astype(bool); _ctx = np.arange(len(_st))
+SEEN_AUDIT = {"window_is_sample_prefix_200000": _wok, "targets_contiguous_from_patch1": _contig, "snn_tokens": _ksnn,
+ "max_ctx_patch_index": int(_ctx.max()), "max_byte_evaluated": int((_st + _ln).max()), "invocab_both_n": int(_ivb.sum())}
+for side in ("ref", "cand"):
+ ok = _wok and _contig and isinstance(_ksnn[side], int)
+ n_tr = int((_ivb & (_ctx < _ksnn[side])).sum()) if ok else None
+ SEEN_AUDIT[f"trained_invocab_n_{side}"] = n_tr; SEEN_AUDIT[f"trained_frac_{side}"] = (n_tr / max(1, int(_ivb.sum()))) if n_tr is not None else None
+SEEN_OK = all(SEEN_AUDIT[f"trained_frac_{x}"] is not None and SEEN_AUDIT[f"trained_frac_{x}"] >= 0.99 for x in ("ref", "cand"))
+SEEN_AUDIT["seen_comparable"] = SEEN_OK; print("seen_audit", json.dumps(SEEN_AUDIT), flush=True)
+FV = [w for w in FRESH if VALID[w]]
+def gapcalc(GW):
+ gap = {}
+ for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt),
+ "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+ dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GW], axis=0))
+ gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+ gap["windows"] = GW; return gap
+GAPS = {"with_test_v3": gapcalc(FV), "without_test_v3": gapcalc([w for w in FV if w != "test_v3"])}
+VW = ["seen"] + FV
+L = [w for w in VW if R[w]["sig_loss"]]; G = [w for w in VW if R[w]["sig_gain"]]; GF = [w for w in FV if R[w]["sig_gain"]]
+why = []
+if not BUDGET_OK:
+ if not all(EQUAL.values()): why.append("budgets cm/ctl inégaux : " + ", ".join(f for f, ok in EQUAL.items() if not ok))
+ if BUD["data_sha256"][RT] != SAMPLE_SHA: why.append("données != échantillon v1b")
+ if not (FULL[RT] and FULL[CT]): why.append(f"passe SNN incomplète : tokens entraînés/époque (ticks × {TOKENS_PER_TICK}) ctl {TRAINED[RT]} / cm {TRAINED[CT]} != snn_tokens {BUD['snn_tokens'][RT]}")
+if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+if BUDGET_OK and SEEN_OK:
+ dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+ if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+else: dec = "NON MESURABLE"
+out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+ "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
+ "results_jsonl_sha256": hashlib.sha256(open(f"{D}/results.jsonl", "rb").read()).hexdigest(),
+ "recount_sample_sha256": hashlib.sha256(open(RC_SAMPLE, "rb").read()).hexdigest(), "mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}/verdict_M8v1b.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b {SAMPLE_SHA[:8]}…\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).", "",
+ "| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|---|"]
+for w in WIN + SEP:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ if w in SEP: dd += " (à part, hors règle)"
+ elif not r["valid"]: dd = "EXCLUE (non propre / non confirmée)"
+ md.append(f"| {w}{' strict' if w == 'test20k' else ''} | {r['valid']} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd} |")
+md += ["", f"neither_code : exclue (non évaluée). test20k strict : {EX.get('excluded_union')} positions exclues (old ∪ broad), 0 par l'échantillon.",
+ f"Budgets : {json.dumps(BUD)} ; contrôle {json.dumps(BUDGET_CHECK)} → {'OK (égaux, budget SNN entier entraîné)' if BUDGET_OK else 'NON OK'}.",
+ f"Audit seen : trained_frac ctl {SEEN_AUDIT['trained_frac_ref']} / cm {SEEN_AUDIT['trained_frac_cand']} → seen {'COMPARABLE' if SEEN_OK else 'NON COMPARABLE'}.",
+ f"Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl {GAPS['with_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f} [{GAPS['with_test_v3']['cand_minus_ref']['ci95'][0]:+.3f} ; {GAPS['with_test_v3']['cand_minus_ref']['ci95'][1]:+.3f}] ; sans test_v3 : {GAPS['without_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f}.",
+ f"Script sha256 {out['script_sha256']}.", ""]
+open(f"{OP}/verdict_M8v1b.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m8_v1b/smoke/vtest2/done b/results/hashing/m8_v1b/smoke/vtest2/done
new file mode 100644
index 0000000000000000000000000000000000000000..7b9285812974d962aee12dfd06f0a8483124bdf7
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest2/done
@@ -0,0 +1,2 @@
+copy differs only on path line
+verdict exit 0
diff --git a/results/hashing/m8_v1b/smoke/vtest2/runs/results.jsonl b/results/hashing/m8_v1b/smoke/vtest2/runs/results.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..ff24f88feed745424f3ea3e855bcf4e39cd88825
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest2/runs/results.jsonl
@@ -0,0 +1,14 @@
+{"arm": "ctl", "window": "seen", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 100.0, "fused_all_pct": 99.0, "snn_invocab_pct": 91.772, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [68.74531881200475], "eval_s": 4.2, "peak_rss_mb": 1142.8, "ckpt_sha256": null, "wall_s": 128.2}
+{"arm": "ctl", "window": "fc2", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [68.74531881200475], "eval_s": 4.2, "peak_rss_mb": 1142.8, "ckpt_sha256": null, "wall_s": 132.4}
+{"arm": "ctl", "window": "fresh_en", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.667, "fused_all_pct": 0.333, "snn_invocab_pct": 0.0, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [68.74531881200475], "eval_s": 4.0, "peak_rss_mb": 1142.8, "ckpt_sha256": null, "wall_s": 136.4}
+{"arm": "ctl", "window": "fresh_fr", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 3.597, "fused_all_pct": 4.333, "snn_invocab_pct": 0.719, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [68.74531881200475], "eval_s": 5.6, "peak_rss_mb": 1142.8, "ckpt_sha256": null, "wall_s": 142.0}
+{"arm": "ctl", "window": "test20k", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [68.74531881200475], "eval_s": 4.5, "peak_rss_mb": 1142.8, "ckpt_sha256": null, "wall_s": 146.5}
+{"arm": "ctl", "window": "test_v3", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [68.74531881200475], "eval_s": 8.3, "peak_rss_mb": 1142.8, "ckpt_sha256": null, "wall_s": 154.8}
+{"arm": "ctl", "window": "queries", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 1.0507417508415837, "sigma_fast": 0.06893261672552685, "sigma_slow": 0.06560376673936844}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre"}, "n_state": 2560, "train_acc": [0.046], "ticks_per_sec": [68.74531881200475], "eval_s": 3.6, "peak_rss_mb": 1142.8, "ckpt_sha256": null, "wall_s": 158.4}
+{"arm": "cm", "window": "seen", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 99.367, "fused_all_pct": 98.667, "snn_invocab_pct": 59.494, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [25.10472753200359], "eval_s": 11.1, "peak_rss_mb": 1410.6, "ckpt_sha256": null, "wall_s": 279.9}
+{"arm": "cm", "window": "fc2", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [25.10472753200359], "eval_s": 10.7, "peak_rss_mb": 1410.6, "ckpt_sha256": null, "wall_s": 290.5}
+{"arm": "cm", "window": "fresh_en", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [25.10472753200359], "eval_s": 10.8, "peak_rss_mb": 1410.6, "ckpt_sha256": null, "wall_s": 301.3}
+{"arm": "cm", "window": "fresh_fr", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 2.878, "fused_all_pct": 4.0, "snn_invocab_pct": 0.0, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [25.10472753200359], "eval_s": 12.4, "peak_rss_mb": 1410.6, "ckpt_sha256": null, "wall_s": 313.7}
+{"arm": "cm", "window": "test20k", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [25.10472753200359], "eval_s": 10.8, "peak_rss_mb": 1410.6, "ckpt_sha256": null, "wall_s": 324.5}
+{"arm": "cm", "window": "test_v3", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [25.10472753200359], "eval_s": 15.4, "peak_rss_mb": 1410.6, "ckpt_sha256": null, "wall_s": 339.9}
+{"arm": "cm", "window": "queries", "snn_tokens": 3000, "am_tokens": 1200000, "epochs": 1, "ticks_per_epoch": [3000], "n": 300, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 1.130901526059381, "sigma_fast": 0.08126576582987112, "sigma_slow": 0.07185927683115005}, "data_sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "read": {"n_patches_train": 7739248, "n_snn": 3000, "n_am": 1200000, "snn_bytes_read": 12845, "am_bytes_read": 5554968, "data_bytes": 35128951, "ept_fit_bytes": 2000000, "ept_calib_bytes": [2000000, 2400000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.020666666666666667], "ticks_per_sec": [25.10472753200359], "eval_s": 10.2, "peak_rss_mb": 1410.6, "ckpt_sha256": null, "wall_s": 350.1}
diff --git a/results/hashing/m8_v1b/smoke/vtest2/runs/rss_cm.tsv b/results/hashing/m8_v1b/smoke/vtest2/runs/rss_cm.tsv
new file mode 100644
index 0000000000000000000000000000000000000000..a8bdba7e4cbeb52d95c4c1402e0ea21266475cb1
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest2/runs/rss_cm.tsv
@@ -0,0 +1,36 @@
+1792858278 0.0 33508 load 0
+1792858288 10.0 678540 build 0
+1792858298 20.0 679156 build 0
+1792858308 30.0 295404 build 0
+1792858318 40.0 805888 snn_ep1 0
+1792858328 50.0 805888 snn_ep1 0
+1792858338 60.0 805888 snn_ep1 0
+1792858348 70.0 805888 snn_ep1 0
+1792858358 80.0 805888 snn_ep1 0
+1792858368 90.0 805888 snn_ep1 0
+1792858378 100.0 805888 snn_ep1 0
+1792858388 110.0 805888 snn_ep1 0
+1792858398 120.0 805888 snn_ep1 0
+1792858408 130.0 805888 snn_ep1 0
+1792858418 140.0 805888 snn_ep1 0
+1792858428 150.0 805988 snn_ep1 0
+1792858438 160.0 1019044 am_write 0
+1792858448 170.0 1019044 calibrate_save 0
+1792858458 180.0 1019044 calibrate_save 0
+1792858468 190.0 1019044 calibrate_save 0
+1792858478 200.0 1019044 calibrate_save 0
+1792858488 210.0 1019044 calibrate_save 0
+1792858498 220.1 1019044 calibrate_save 0
+1792858508 230.1 1019044 calibrate_save 0
+1792858518 240.1 1019044 calibrate_save 0
+1792858528 250.1 1019044 calibrate_save 0
+1792858538 260.1 1019044 calibrate_save 0
+1792858548 270.1 1023100 eval_seen 0
+1792858558 280.1 1024004 eval_fc2 0
+1792858568 290.1 1024804 eval_fc2 0
+1792858578 300.1 1025688 eval_fresh_en 0
+1792858588 310.1 1085300 eval_fresh_fr 0
+1792858598 320.1 1053744 eval_test20k 0
+1792858608 330.1 1266680 eval_test_v3 0
+1792858618 340.1 1103152 eval_queries 0
+1792858628 350.1 1103152 eval_queries 0
diff --git a/results/hashing/m8_v1b/smoke/vtest2/runs/rss_ctl.tsv b/results/hashing/m8_v1b/smoke/vtest2/runs/rss_ctl.tsv
new file mode 100644
index 0000000000000000000000000000000000000000..cc0dcafd41dbd30e9e8a2c0de8c71181a97b8807
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest2/runs/rss_ctl.tsv
@@ -0,0 +1,16 @@
+1792858119 0.0 33568 load 0
+1792858129 10.0 667272 build 0
+1792858139 20.0 662536 build 0
+1792858149 30.0 509876 snn_ep1 0
+1792858159 40.0 509876 snn_ep1 0
+1792858169 50.0 509876 snn_ep1 0
+1792858179 60.0 509880 snn_ep1 0
+1792858189 70.0 509880 snn_ep1 0
+1792858199 80.0 723040 am_write 0
+1792858209 90.0 739424 calibrate_save 0
+1792858219 100.0 739424 calibrate_save 0
+1792858229 110.1 739424 calibrate_save 0
+1792858239 120.1 739424 calibrate_save 0
+1792858249 130.1 744252 eval_fc2 0
+1792858259 140.1 771712 eval_fresh_fr 0
+1792858269 150.1 894372 eval_test_v3 0
diff --git a/results/hashing/m8_v1b/smoke/vtest2/verdict/verdict_M8v1b.json b/results/hashing/m8_v1b/smoke/vtest2/verdict/verdict_M8v1b.json
new file mode 100644
index 0000000000000000000000000000000000000000..6abe2fb6fb6a1de0e265e9ad1f058cec382f9a4d
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest2/verdict/verdict_M8v1b.json
@@ -0,0 +1,413 @@
+{
+ "cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)",
+ "ref": "ctl = même code (SPIRA) sans CM, budget égal",
+ "corpus": "v1b_sample.bin 9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "budgets": {
+ "snn_tokens": {
+ "ctl": 3000,
+ "cm": 3000
+ },
+ "am_tokens": {
+ "ctl": 1200000,
+ "cm": 1200000
+ },
+ "epochs": {
+ "ctl": 1,
+ "cm": 1
+ },
+ "ticks_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "data_sha256": {
+ "ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
+ "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+ }
+ },
+ "budget_check": {
+ "equal_cm_ctl": {
+ "snn_tokens": true,
+ "am_tokens": true,
+ "epochs": true,
+ "ticks_per_epoch": true,
+ "data_sha256": true
+ },
+ "data_is_sample": true,
+ "tokens_per_tick": 1,
+ "trained_snn_tokens_per_epoch": {
+ "ctl": [
+ 3000
+ ],
+ "cm": [
+ 3000
+ ]
+ },
+ "full_budget_each_epoch": {
+ "ctl": true,
+ "cm": true
+ }
+ },
+ "budget_ok": true,
+ "windows_rule": [
+ "seen",
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k",
+ "test_v3"
+ ],
+ "fresh_valid": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ],
+ "windows_invalid": [
+ "test_v3"
+ ],
+ "reported_separately": [
+ "queries"
+ ],
+ "excluded": [
+ "neither_code (non évaluée)"
+ ],
+ "decision": "REJETÉ",
+ "reasons": [
+ "pas de gain significatif sur seen",
+ "aucun gain significatif sur une fenêtre fraîche valide"
+ ],
+ "losses": [],
+ "gains": [],
+ "fresh_gains": [],
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable",
+ "bootstrap": {
+ "block_bytes": 512,
+ "B": 10000,
+ "seed": 0
+ },
+ "per_window": {
+ "seen": {
+ "n_positions": 300,
+ "n_clean": 158,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 100.0,
+ "acc_cand_pct": 99.36708860759494,
+ "delta_pct": -0.6329113924050631,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.2222222222222285,
+ 0.0
+ ],
+ "boot_p": 0.5866,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "4bf84913abd943b195ce2b42e1ae5416fe757805ea73b27f83fc9eea0c30cec0",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": null
+ },
+ "fc2": {
+ "n_positions": 300,
+ "n_clean": 153,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
+ }
+ },
+ "fresh_en": {
+ "n_positions": 300,
+ "n_clean": 150,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.6666666666666666,
+ "acc_cand_pct": 0.0,
+ "delta_pct": -0.6666666666666666,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -2.0833333333333335,
+ 0.0
+ ],
+ "boot_p": 0.5792,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
+ }
+ },
+ "fresh_fr": {
+ "n_positions": 300,
+ "n_clean": 139,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 3.597122302158273,
+ "acc_cand_pct": 2.8776978417266186,
+ "delta_pct": -0.7194244604316546,
+ "b_ref_only": 1,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ -1.7857142857142856,
+ 0.0
+ ],
+ "boot_p": 0.5896,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
+ }
+ },
+ "test20k": {
+ "n_positions": 300,
+ "n_clean": 161,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
+ "valid": true,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
+ },
+ "strict_mask": {
+ "excluded_by_old_local_v1": 0,
+ "excluded_by_broad_local_v1": 0,
+ "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": 0,
+ "excluded_union": 0,
+ "max_byte_evaluated": 1506
+ }
+ },
+ "test_v3": {
+ "n_positions": 300,
+ "n_clean": 72,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
+ "valid": false,
+ "in_rule": true,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
+ }
+ },
+ "queries": {
+ "n_positions": 300,
+ "n_clean": 113,
+ "invocab_identical": true,
+ "n_invocab_one_side_only_dropped": 0,
+ "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": 0.0,
+ "acc_cand_pct": 0.0,
+ "delta_pct": 0.0,
+ "b_ref_only": 0,
+ "c_cand_only": 0,
+ "mcnemar_p": 1.0,
+ "boot_ci95_delta_pct": [
+ 0.0,
+ 0.0
+ ],
+ "boot_p": 1.0,
+ "n_blocks": 3,
+ "sig_gain": false,
+ "sig_loss": false,
+ "boot_conflict": false,
+ "window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
+ "valid": true,
+ "in_rule": false,
+ "clean_recount": {
+ "sample_confirmed_window_positions": 0,
+ "v1b_confirmed_window_positions": 0,
+ "window_sha256_recount": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
+ }
+ }
+ },
+ "seen_fresh_gap": {
+ "with_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ },
+ "without_test_v3": {
+ "ref": {
+ "fresh_mean_pct": 1.065947242206235,
+ "seen_pct": 100.0,
+ "gap_pct": 98.93405275779376,
+ "ci95": [
+ 97.60551948051948,
+ 100.0
+ ]
+ },
+ "cand": {
+ "fresh_mean_pct": 0.7194244604316546,
+ "seen_pct": 99.36708860759494,
+ "gap_pct": 98.64766414716328,
+ "ci95": [
+ 97.0265954517923,
+ 100.0
+ ]
+ },
+ "cand_minus_ref": {
+ "gap_diff_pct": -0.2863886106304818,
+ "ci95": [
+ -1.8436911487759033,
+ 0.6130952380952266
+ ]
+ },
+ "windows": [
+ "fc2",
+ "fresh_en",
+ "fresh_fr",
+ "test20k"
+ ]
+ }
+ },
+ "seen_trained_audit": {
+ "window_is_sample_prefix_200000": true,
+ "targets_contiguous_from_patch1": true,
+ "snn_tokens": {
+ "ref": 3000,
+ "cand": 3000
+ },
+ "max_ctx_patch_index": 299,
+ "max_byte_evaluated": 1299,
+ "invocab_both_n": 158,
+ "trained_invocab_n_ref": 158,
+ "trained_frac_ref": 1.0,
+ "trained_invocab_n_cand": 158,
+ "trained_frac_cand": 1.0,
+ "seen_comparable": true
+ },
+ "go_flag_present": false,
+ "script_sha256": "124ac3cda96fa2197af2c5da6ca1ba20704c267c2b47d52badb92817e552fa3b",
+ "inputs_sha256": {
+ "ctl__seen.npz": "060d52c025bac6c903af8844cd20ed889d15d8661a3cdc246d5918a2c0d3a36d",
+ "ctl__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "ctl__fresh_en.npz": "b8f00334ca8e513e71be3e712aa640ec5f8cd1a77cb9e6792ae7b91f57ef26cd",
+ "ctl__fresh_fr.npz": "3489278456cf80980f716aec6ddcd4328e4cbc139590c74d002ad4eff63a7071",
+ "ctl__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "ctl__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "ctl__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e",
+ "cm__seen.npz": "15e0eb6c46aa88bcf9f0d0a791977abea4a97a5d0b8b3cd14011229474e01038",
+ "cm__fc2.npz": "826916a0a689bd2d3a436c8f0f9f88e2f1c2f8ec0961ccd710680cd2e202f5a3",
+ "cm__fresh_en.npz": "64c18a1a99bc814d0f9b1de07d751194ec576465927a53bd8857ddc9d01213c4",
+ "cm__fresh_fr.npz": "dd6a342ad590f4ae559f6f7a3058a5cc166d81519d764f6b104d85c985a81ac0",
+ "cm__test20k.npz": "b183286c7fc6ab4bfcc0713f763e38fd29f90b5cb42f522803241cd60b79a60f",
+ "cm__test_v3.npz": "11d54d0f4bfcf98d6e267b31c63e57033540ffd36388f8d6b8ff30a468504050",
+ "cm__queries.npz": "6f03b3345b76252e7ff11935c2080f8602d29f3e8f70dbf899b86a3220a12c2e"
+ },
+ "results_jsonl_sha256": "dc54b207075ff91e04e253a005e5967c67bb5e37884c03e508b3ceb2db7743e7",
+ "recount_sample_sha256": "a307ccc7cdbb20fb0882e9b082c2b8f474943fb79012e76eb50edf5ad0ceb20c",
+ "mask_sha256": "50fa08f902239d344fab34822b576fd5e138449c2697d60ce4329e92ca5ca178"
+}
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/smoke/vtest2/verdict/verdict_M8v1b.md b/results/hashing/m8_v1b/smoke/vtest2/verdict/verdict_M8v1b.md
new file mode 100644
index 0000000000000000000000000000000000000000..05d91f1cf344d2bc4b62805b3e9f0589fd0cbd11
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest2/verdict/verdict_M8v1b.md
@@ -0,0 +1,22 @@
+# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b 9ea562e4…
+
+**REJETÉ** — pas de gain significatif sur seen; aucun gain significatif sur une fenêtre fraîche valide
+
+Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).
+
+| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |
+|---|---|---|---|---|---|---|---|---|---|
+| seen | True | 158 | 99.367 | 100.000 | -0.633 | 1/0 | 1 | [-2.222 ; +0.000] | n.s. |
+| fc2 | True | 153 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| fresh_en | True | 150 | 0.000 | 0.667 | -0.667 | 1/0 | 1 | [-2.083 ; +0.000] | n.s. |
+| fresh_fr | True | 139 | 2.878 | 3.597 | -0.719 | 1/0 | 1 | [-1.786 ; +0.000] | n.s. |
+| test20k strict | True | 161 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. |
+| test_v3 | False | 72 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | EXCLUE (non propre / non confirmée) |
+| queries | True | 113 | 0.000 | 0.000 | +0.000 | 0/0 | 1 | [+0.000 ; +0.000] | n.s. (à part, hors règle) |
+
+neither_code : exclue (non évaluée). test20k strict : 0 positions exclues (old ∪ broad), 0 par l'échantillon.
+Budgets : {"snn_tokens": {"ctl": 3000, "cm": 3000}, "am_tokens": {"ctl": 1200000, "cm": 1200000}, "epochs": {"ctl": 1, "cm": 1}, "ticks_per_epoch": {"ctl": [3000], "cm": [3000]}, "data_sha256": {"ctl": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b", "cm": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"}} ; contrôle {"equal_cm_ctl": {"snn_tokens": true, "am_tokens": true, "epochs": true, "ticks_per_epoch": true, "data_sha256": true}, "data_is_sample": true, "tokens_per_tick": 1, "trained_snn_tokens_per_epoch": {"ctl": [3000], "cm": [3000]}, "full_budget_each_epoch": {"ctl": true, "cm": true}} → OK (égaux, budget SNN entier entraîné).
+Audit seen : trained_frac ctl 1.0 / cm 1.0 → seen COMPARABLE.
+Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl -0.286 [-1.844 ; +0.613] ; sans test_v3 : -0.286.
+Script sha256 124ac3cda96fa2197af2c5da6ca1ba20704c267c2b47d52badb92817e552fa3b.
+
diff --git a/results/hashing/m8_v1b/smoke/vtest2/verdict_test_copy.py b/results/hashing/m8_v1b/smoke/vtest2/verdict_test_copy.py
new file mode 100644
index 0000000000000000000000000000000000000000..92e01d0b7fc8f647bc29894c84aa3a6099fdb5c8
--- /dev/null
+++ b/results/hashing/m8_v1b/smoke/vtest2/verdict_test_copy.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — verdict M8 v1b (cm = M8 neurones CM concat, contre ctl = même code sans CM, budget égal), chemin v4.2.
+Dérivé de lever2_sparse/code/verdict_SP.py (sha256 7a6d5414…a2deb, copie : verdict_SP.py.orig_ref). Calculs identiques (positions in-vocab dans
+les DEUX bras, taux APPARIÉS même dénominateur, McNemar exact bilatéral, bootstrap apparié blocs 512 o B=10 000 seed 0, bootstrap positions seed 25).
+SEULS changements : (1) bras ctl/cm lus dans m8_v1b/runs ; (2) fenêtre seen = v1b_sample[:200 000] (audit trained_frac identique) ;
+(3) test_v3 ajoutée, VALIDE ssi recompte 64 o de l'échantillon = 0 ET recompte v1b = 0 ET drapeau GO_CHECKER_PASS présent, sinon exclue ;
+(4) queries rapportée À PART (hors règle) ; neither_code non évaluée (exclue) ; (5) positions propres : chaque fenêtre fraîche exige
+confirmed_window_positions = 0 dans le recompte de l'échantillon (sinon fenêtre NON COMPARABLE, exclue) ; test20k strict = masque
+mask_oldtest_strict.npz (old_local_v1 ∪ broad_local_v1) ∪ échantillon (0 position, vérifié) ; (6) gain significatif = McNemar p<0,05 ET c>b ET
+IC95 bootstrap > 0 (plan §3) ; perte significative = McNemar p<0,05 ET b>c ; (7) NON MESURABLE si budgets inégaux (snn_tokens, am_tokens,
+epochs, ticks/époque, sha256 des données), si une époque n'a pas entraîné tout le budget (ticks × 1 token/tick != snn_tokens), ou seen NON COMPARABLE
+(trained_frac < 0,99 dans un bras ; trained_frac calculé sur les tokens RÉELLEMENT entraînés = ticks × 1, pas sur snn_tokens déclaré).
+Révision 2 (12 h 08 Toronto) : contrôle d'unités rendu explicite (TOKENS_PER_TICK = 1, spiking.py l. 471-539) et audit seen sur tokens réellement entraînés.
+Règle : ADOPTÉ ssi gain significatif sur seen ET sur >=1 fenêtre fraîche valide (fc2, fresh_en, fresh_fr, test20k strict, test_v3 si propre)
+ET aucune perte significative sur une fenêtre valide (seen + fraîches valides) ; sinon REJETÉ."""
+import sys, os, json, math, hashlib, numpy as np
+B8 = "/workspace/spira_shared/hashing_gen/m8_v1b"; D = "/workspace/spira_shared/hashing_gen/m8_v1b/smoke/vtest2/runs"; OP = "/workspace/spira_shared/hashing_gen/m8_v1b/smoke/vtest2/verdict"; RT, CT = "ctl", "cm"
+SAMPLE = f"{B8}/sample/v1b_sample.bin"; SAMPLE_SHA = "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b"
+RC_SAMPLE = f"{B8}/sample/recount64_v1b_sample.json"; RC_V1B = "/workspace/spira_shared/hashing_gen/corpus_v1b/manifest_corpus_diverse_v1b.json"
+GO = f"{B8}/GO_CHECKER_PASS"; MASKP = "/workspace/spira_shared/hashing_gen/lever2/verdict_AH1/mask_oldtest_strict.npz"
+WIN = ["seen", "fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; SEP = ["queries"]
+RCNAME = {"fc2": "fc2", "fresh_en": "m7_fresh_en", "fresh_fr": "m7_fresh_fr", "test20k": "m7_test20k", "test_v3": "corpus_v3_test", "queries": "m7_queries"}
+BLK, NB, SEED = 512, 10000, 0
+os.makedirs(OP, exist_ok=True); MS = np.load(MASKP)
+def binp(b, c):
+ n = b + c
+ return 1.0 if n == 0 else min(1.0, 2 * sum(math.comb(n, i) for i in range(min(b, c) + 1)) / 2 ** n)
+def blocksums(st, h, iv, nbk):
+ b = st // BLK; return np.bincount(b, weights=h & iv, minlength=nbk), np.bincount(b, weights=iv, minlength=nbk)
+# ---- budgets égaux (sinon NON MESURABLE)
+RES = [json.loads(l) for l in open(f"{D}/results.jsonl") if l.strip()]
+def arm_field(arm, f):
+ v = {json.dumps(r.get(f), sort_keys=True) for r in RES if r.get("arm") == arm}; return json.loads(v.pop()) if len(v) == 1 else "INCOHERENT"
+BUD = {f: {RT: arm_field(RT, f), CT: arm_field(CT, f)} for f in ("snn_tokens", "am_tokens", "epochs", "ticks_per_epoch", "data_sha256")}
+# Unités : spira/spiking.py SpikingCore.train_pass (l. 471-539) fait UN tick par token SNN (neurons[t] = token t, "ticks": T = len(cols)),
+# donc tokens SNN entraînés par époque = ticks × TOKENS_PER_TICK, TOKENS_PER_TICK = 1. Contrôles : (i) égalité cm == ctl de chaque champ ;
+# (ii) données = échantillon ; (iii) chaque époque a entraîné TOUT le budget : ticks × TOKENS_PER_TICK == snn_tokens (sinon passe tronquée).
+TOKENS_PER_TICK = 1
+EQUAL = {f: (v[RT] == v[CT] and v[RT] != "INCOHERENT" and v[RT] is not None) for f, v in BUD.items()}
+TRAINED = {x: ([t * TOKENS_PER_TICK for t in BUD["ticks_per_epoch"][x]] if isinstance(BUD["ticks_per_epoch"][x], list) else None) for x in (RT, CT)}
+FULL = {x: (TRAINED[x] is not None and isinstance(BUD["epochs"][x], int) and len(TRAINED[x]) == BUD["epochs"][x]
+ and all(t == BUD["snn_tokens"][x] for t in TRAINED[x])) for x in (RT, CT)}
+BUDGET_OK = all(EQUAL.values()) and BUD["data_sha256"][RT] == SAMPLE_SHA and FULL[RT] and FULL[CT]
+BUDGET_CHECK = {"equal_cm_ctl": EQUAL, "data_is_sample": BUD["data_sha256"][RT] == SAMPLE_SHA, "tokens_per_tick": TOKENS_PER_TICK,
+ "trained_snn_tokens_per_epoch": TRAINED, "full_budget_each_epoch": FULL}
+# tokens SNN réellement entraînés (pour l'audit seen) = min sur les époques de ticks × TOKENS_PER_TICK, borné par snn_tokens
+TRAINED_MIN = {x: (min(min(TRAINED[x]), BUD["snn_tokens"][x]) if TRAINED[x] and isinstance(BUD["snn_tokens"][x], int) else None) for x in (RT, CT)}
+# ---- propreté des fenêtres fraîches
+RCS = json.load(open(RC_SAMPLE)); RCV = json.load(open(RC_V1B))["overlap64_recount_v1b"]["per_window"]
+assert RCS["sha256"] == SAMPLE_SHA, "recompte : échantillon différent"
+CLEAN = {}
+for w, k in RCNAME.items():
+ cs = RCS["windows"][k]["confirmed_window_positions"]; cv = RCV[k]["confirmed_window_positions"] if k in RCV else None
+ CLEAN[w] = {"sample_confirmed_window_positions": cs, "v1b_confirmed_window_positions": cv, "window_sha256_recount": RCS["windows"][k]["window_sha256"]}
+VALID = {w: CLEAN[w]["sample_confirmed_window_positions"] == 0 for w in FRESH + SEP}
+VALID["test_v3"] = VALID["test_v3"] and CLEAN["test_v3"]["v1b_confirmed_window_positions"] == 0 and os.path.exists(GO)
+R = {}; RNG = np.random.default_rng(SEED); BOOT = {}; KEEP = {}; EX = {}
+for w in WIN + SEP:
+ A = np.load(f"{D}/{RT}__{w}.npz"); B = np.load(f"{D}/{CT}__{w}.npz")
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), f"{w}: octets différents"
+ if w in RCNAME: assert str(A["window_sha256"]) == CLEAN[w]["window_sha256_recount"], f"{w}: fenêtre != fenêtre recomptée"
+ na, nb_ = len(A["fused_hit"]), len(B["fused_hit"])
+ same_tok = na == nb_ and np.array_equal(A["tgt_start"], B["tgt_start"]) and np.array_equal(A["tgt_len"], B["tgt_len"])
+ assert same_tok, f"{w}: tokenisation différente, appariement par position impossible"
+ ha, hb = A["fused_hit"].astype(bool) & A["invocab"].astype(bool), B["fused_hit"].astype(bool) & B["invocab"].astype(bool)
+ if w == "test20k":
+ assert str(MS["sha__test20k"]) == str(A["window_sha256"]), "masque : fenêtre différente"
+ bad = lambda cov: np.array([cov[max(0, int(s) - 64):int(s) + int(l)].any() for s, l in zip(A["tgt_start"], A["tgt_len"])])
+ bo, bb_ = bad(MS["old_local_v1__covered"]), bad(MS["broad_local_v1__covered"]); k = ~(bo | bb_)
+ EX = {"excluded_by_old_local_v1": int(bo.sum()), "excluded_by_broad_local_v1": int(bb_.sum()), "excluded_by_v1b_sample": 0,
+ "v1b_sample_confirmed_window_positions": CLEAN["test20k"]["sample_confirmed_window_positions"],
+ "excluded_union": int((bo | bb_).sum()), "max_byte_evaluated": int((A["tgt_start"] + A["tgt_len"]).max())}
+ else: k = np.ones(na, bool)
+ inv_same = bool(np.array_equal(A["invocab"][k], B["invocab"][k]))
+ ia1, ib1 = A["invocab"].astype(bool) & k, B["invocab"].astype(bool) & k; one_side = int((ia1 ^ ib1).sum())
+ k = k & A["invocab"].astype(bool) & B["invocab"].astype(bool)
+ b = int((ha & ~hb & k).sum()); c = int((~ha & hb & k).sum()); npair = int(k.sum()); p = binp(b, c)
+ acc_a, acc_b = 100 * (ha & k).sum() / max(1, k.sum()), 100 * (hb & k).sum() / max(1, k.sum())
+ nbk = int(A["tgt_start"].max() // BLK + 1)
+ sa_h, sa_n = blocksums(A["tgt_start"][k], ha[k], k[k], nbk); sb_h, sb_n = blocksums(B["tgt_start"][k], hb[k], k[k], nbk)
+ nz = (sa_n + sb_n) > 0; sa_h, sa_n, sb_h, sb_n = sa_h[nz], sa_n[nz], sb_h[nz], sb_n[nz]; m = len(sa_h)
+ idx = RNG.integers(0, m, (NB, m))
+ with np.errstate(invalid="ignore", divide="ignore"):
+ ba = 100 * sa_h[idx].sum(1) / sa_n[idx].sum(1); bb = 100 * sb_h[idx].sum(1) / sb_n[idx].sum(1)
+ d = bb - ba; BOOT[w] = (ba, bb); KEEP[w] = (k, ha, hb, k)
+ lo, hi = np.percentile(d, [2.5, 97.5]); pboot = float(min(1.0, 2 * min((d <= 0).mean(), (d >= 0).mean())))
+ gain, loss = bool(p < 0.05 and c > b and lo > 0), bool(p < 0.05 and b > c)
+ R[w] = {"n_positions": na, "n_clean": npair, "invocab_identical": inv_same, "n_invocab_one_side_only_dropped": one_side, "method": "v4.2 : in-vocab deux bras, taux appariés",
+ "acc_ref_pct": float(acc_a), "acc_cand_pct": float(acc_b), "delta_pct": float(acc_b - acc_a), "b_ref_only": b, "c_cand_only": c, "mcnemar_p": p,
+ "boot_ci95_delta_pct": [float(lo), float(hi)], "boot_p": pboot, "n_blocks": m, "sig_gain": gain, "sig_loss": loss,
+ "boot_conflict": bool((p < 0.05 and c > b and hi < 0) or (loss and lo > 0)), "window_sha256": str(A["window_sha256"]),
+ "valid": (True if w == "seen" else VALID[w]), "in_rule": w in WIN, "clean_recount": CLEAN.get(w)}
+ if w == "test20k": R[w]["strict_mask"] = EX
+ print(w, json.dumps(R[w]), flush=True)
+# ---- audit trained_frac du seen (identique à verdict_SP, fenêtre = échantillon[:200 000])
+_A = np.load(f"{D}/{RT}__seen.npz"); _st, _ln = _A["tgt_start"].astype(np.int64), _A["tgt_len"].astype(np.int64)
+_contig = bool(np.all(_st[1:] == _st[:-1] + _ln[:-1]) and _st[0] > 0 and _st[0] <= int(_ln.max()))
+_sb = open(SAMPLE, "rb").read(); _wok = hashlib.sha256(_sb[:200_000]).hexdigest() == R["seen"]["window_sha256"] and hashlib.sha256(_sb).hexdigest() == SAMPLE_SHA; del _sb
+_ksnn = {"ref": TRAINED_MIN[RT], "cand": TRAINED_MIN[CT]} # tokens SNN réellement entraînés (ticks × 1), pas le budget déclaré
+_k, _ha, _hb, _iv = KEEP["seen"]; _ivb = _k & _iv & np.load(f"{D}/{CT}__seen.npz")["invocab"].astype(bool); _ctx = np.arange(len(_st))
+SEEN_AUDIT = {"window_is_sample_prefix_200000": _wok, "targets_contiguous_from_patch1": _contig, "snn_tokens": _ksnn,
+ "max_ctx_patch_index": int(_ctx.max()), "max_byte_evaluated": int((_st + _ln).max()), "invocab_both_n": int(_ivb.sum())}
+for side in ("ref", "cand"):
+ ok = _wok and _contig and isinstance(_ksnn[side], int)
+ n_tr = int((_ivb & (_ctx < _ksnn[side])).sum()) if ok else None
+ SEEN_AUDIT[f"trained_invocab_n_{side}"] = n_tr; SEEN_AUDIT[f"trained_frac_{side}"] = (n_tr / max(1, int(_ivb.sum()))) if n_tr is not None else None
+SEEN_OK = all(SEEN_AUDIT[f"trained_frac_{x}"] is not None and SEEN_AUDIT[f"trained_frac_{x}"] >= 0.99 for x in ("ref", "cand"))
+SEEN_AUDIT["seen_comparable"] = SEEN_OK; print("seen_audit", json.dumps(SEEN_AUDIT), flush=True)
+FV = [w for w in FRESH if VALID[w]]
+def gapcalc(GW):
+ gap = {}
+ for side, j in (("ref", 0), ("cand", 1)):
+ fm = np.mean([BOOT[w][j] for w in GW], axis=0); g = BOOT["seen"][j] - fm
+ pt = R["seen"]["acc_%s_pct" % side] - np.mean([R[w]["acc_%s_pct" % side] for w in GW])
+ gap[side] = {"fresh_mean_pct": float(np.mean([R[w]["acc_%s_pct" % side] for w in GW])), "seen_pct": R["seen"]["acc_%s_pct" % side], "gap_pct": float(pt),
+ "ci95": [float(x) for x in np.nanpercentile(g, [2.5, 97.5])]}
+ dg = (BOOT["seen"][1] - np.mean([BOOT[w][1] for w in GW], axis=0)) - (BOOT["seen"][0] - np.mean([BOOT[w][0] for w in GW], axis=0))
+ gap["cand_minus_ref"] = {"gap_diff_pct": gap["cand"]["gap_pct"] - gap["ref"]["gap_pct"], "ci95": [float(x) for x in np.nanpercentile(dg, [2.5, 97.5])]}
+ gap["windows"] = GW; return gap
+GAPS = {"with_test_v3": gapcalc(FV), "without_test_v3": gapcalc([w for w in FV if w != "test_v3"])}
+VW = ["seen"] + FV
+L = [w for w in VW if R[w]["sig_loss"]]; G = [w for w in VW if R[w]["sig_gain"]]; GF = [w for w in FV if R[w]["sig_gain"]]
+why = []
+if not BUDGET_OK:
+ if not all(EQUAL.values()): why.append("budgets cm/ctl inégaux : " + ", ".join(f for f, ok in EQUAL.items() if not ok))
+ if BUD["data_sha256"][RT] != SAMPLE_SHA: why.append("données != échantillon v1b")
+ if not (FULL[RT] and FULL[CT]): why.append(f"passe SNN incomplète : tokens entraînés/époque (ticks × {TOKENS_PER_TICK}) ctl {TRAINED[RT]} / cm {TRAINED[CT]} != snn_tokens {BUD['snn_tokens'][RT]}")
+if not SEEN_OK: why.append("seen NON COMPARABLE (trained_frac < 0,99 ou non vérifiable)")
+if BUDGET_OK and SEEN_OK:
+ dec = "ADOPTÉ" if (R["seen"]["sig_gain"] and GF and not L) else "REJETÉ"
+ if not R["seen"]["sig_gain"]: why.append("pas de gain significatif sur seen")
+ if not GF: why.append("aucun gain significatif sur une fenêtre fraîche valide")
+ if L: why.append("perte(s) significative(s) : " + ", ".join(L))
+else: dec = "NON MESURABLE"
+out = {"cand": "cm = M8 (CMSPIRA, neurones Count-Min ±2 top-16 PPMI d24/4096, concat)", "ref": "ctl = même code (SPIRA) sans CM, budget égal", "corpus": f"v1b_sample.bin {SAMPLE_SHA}",
+ "budgets": BUD, "budget_check": BUDGET_CHECK, "budget_ok": BUDGET_OK, "windows_rule": WIN, "fresh_valid": FV, "windows_invalid": [w for w in FRESH if not VALID[w]],
+ "reported_separately": SEP, "excluded": ["neither_code (non évaluée)"], "decision": dec, "reasons": why, "losses": L, "gains": G, "fresh_gains": GF,
+ "rule": "ADOPTÉ ssi gain significatif (McNemar exact p<0,05, c>b, IC95 bootstrap > 0) sur seen ET sur >=1 fenêtre fraîche valide ET aucune perte significative (McNemar p<0,05, b>c) sur une fenêtre valide ; NON MESURABLE si budgets inégaux, passe SNN incomplète (ticks × 1 != snn_tokens) ou seen non comparable",
+ "bootstrap": {"block_bytes": BLK, "B": NB, "seed": SEED}, "per_window": R, "seen_fresh_gap": GAPS, "seen_trained_audit": SEEN_AUDIT, "go_flag_present": os.path.exists(GO),
+ "script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(),
+ "inputs_sha256": {f"{a}__{w}.npz": hashlib.sha256(open(f"{D}/{a}__{w}.npz", "rb").read()).hexdigest() for a in (RT, CT) for w in WIN + SEP},
+ "results_jsonl_sha256": hashlib.sha256(open(f"{D}/results.jsonl", "rb").read()).hexdigest(),
+ "recount_sample_sha256": hashlib.sha256(open(RC_SAMPLE, "rb").read()).hexdigest(), "mask_sha256": hashlib.sha256(open(MASKP, "rb").read()).hexdigest()}
+json.dump(out, open(f"{OP}/verdict_M8v1b.json", "w"), indent=1, ensure_ascii=False)
+md = [f"# Verdict M8 v1b — cm (M8 concat) contre ctl (même code sans CM, budget égal), échantillon v1b {SAMPLE_SHA[:8]}…\n",
+ f"**{dec}** — " + ("; ".join(why) if why else "critère rempli"), "",
+ "Précision fused APPARIÉE (%) sur les cibles in-vocab dans les DEUX bras (v4.2), appariement par position (tokenisation identique vérifiée).", "",
+ "| fenêtre | valide | n apparié | cm % | ctl % | Δ pts | b (ctl seul) / c (cm seul) | p McNemar exact | IC95 Δ bootstrap (512 o, B=10 000, seed 0) | décision |", "|---|---|---|---|---|---|---|---|---|---|"]
+for w in WIN + SEP:
+ r = R[w]; dd = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
+ if w in SEP: dd += " (à part, hors règle)"
+ elif not r["valid"]: dd = "EXCLUE (non propre / non confirmée)"
+ md.append(f"| {w}{' strict' if w == 'test20k' else ''} | {r['valid']} | {r['n_clean']} | {r['acc_cand_pct']:.3f} | {r['acc_ref_pct']:.3f} | {r['delta_pct']:+.3f} | {r['b_ref_only']}/{r['c_cand_only']} | {r['mcnemar_p']:.3g} | [{r['boot_ci95_delta_pct'][0]:+.3f} ; {r['boot_ci95_delta_pct'][1]:+.3f}] | {dd} |")
+md += ["", f"neither_code : exclue (non évaluée). test20k strict : {EX.get('excluded_union')} positions exclues (old ∪ broad), 0 par l'échantillon.",
+ f"Budgets : {json.dumps(BUD)} ; contrôle {json.dumps(BUDGET_CHECK)} → {'OK (égaux, budget SNN entier entraîné)' if BUDGET_OK else 'NON OK'}.",
+ f"Audit seen : trained_frac ctl {SEEN_AUDIT['trained_frac_ref']} / cm {SEEN_AUDIT['trained_frac_cand']} → seen {'COMPARABLE' if SEEN_OK else 'NON COMPARABLE'}.",
+ f"Écart seen − moyenne fraîche (avec test_v3 si valide) : cm−ctl {GAPS['with_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f} [{GAPS['with_test_v3']['cand_minus_ref']['ci95'][0]:+.3f} ; {GAPS['with_test_v3']['cand_minus_ref']['ci95'][1]:+.3f}] ; sans test_v3 : {GAPS['without_test_v3']['cand_minus_ref']['gap_diff_pct']:+.3f}.",
+ f"Script sha256 {out['script_sha256']}.", ""]
+open(f"{OP}/verdict_M8v1b.md", "w").write("\n".join(md) + "\n"); print("\n".join(md))
diff --git a/results/hashing/m8_v1b/tmp/relay_1792890412.md b/results/hashing/m8_v1b/tmp/relay_1792890412.md
new file mode 100644
index 0000000000000000000000000000000000000000..12d21a34f06beaee48caad706b97a3e93187b8c3
--- /dev/null
+++ b/results/hashing/m8_v1b/tmp/relay_1792890412.md
@@ -0,0 +1,8 @@
+
+## 24 oct 21 h 06 (Toronto) — SPIRA Hashing — routine horaire : cm M8 v1b essai 2 arrêté par sa garde
+- Le bras cm M8 v1b (PID 666012, essai 2, lancé à 17 h 51) a été arrêté à 21 h 05 par sa propre garde mémoire : MemAvailable box est descendu à 4 438 634 496 o (< 4,4 Gio). Code 143, RSS max du groupe 1 159 172 kB. Aucun checkpoint d'époque n'avait été écrit (runs/ckpt_cm/ vide), donc les 3 h 13 sont perdues. Seul notre groupe a été arrêté.
+- La porte 218845 reste armée : ctl fini (code 0, 17 h 21), cm en attente de l'essai 3, **le dernier autorisé** (besoin MemAvailable ≥ 7 224 464 025 o). Au passage de 21 h 06 : MemAvailable ~10 Go, charge ~3,4.
+- Demande aux bots : éviter les pics mémoire pendant l'essai 3 (environ 3 h 15). Le creux de 21 h 05 coïncide avec le lancement du recompte M7sem de Checker (923486) ; à confirmer par Checker.
+- Rappel : cov b r2 v3 (15953) et broad (16884) sont morts vers 17 h 26–17 h 29, gates en FAIL_TRAIN à 17 h 31. Le relancement r3 est déjà pris en charge par la chaîne 784212, qui attend 666012 et 218845.
+- Aucun verdict, aucun push HF, rien tué, rien sous /tmp.
+— SPIRA Hashing
diff --git a/results/hashing/m8_v1b/v2_resume/README.md b/results/hashing/m8_v1b/v2_resume/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..b424db9eb35f7d851c058f2dd91d319526ab9595
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/README.md
@@ -0,0 +1,155 @@
+# M8 v1b — bras cm v2 : checkpoint intra-époque + `--resume` + chien de garde v2 (SPIRA Hashing, 25 oct 2026)
+
+**Statut : codé et testé sur config synthétique seulement. AUCUN entraînement réel lancé. La porte `gate_cm_try4.sh` est un BROUILLON non armé ;
+un essai 4 exige le oui écrit de Philippe-Antoine (drapeau `GO_TRY4_USER`, jamais créé par Hashing sans ce oui).**
+
+## Pourquoi
+cm essai 3 (PID 925745, lancé 24 oct 21 h 06) tué le 25 oct à 01 h 35 min 21 s (Toronto) par son propre chien de garde v1 (`code/run_guarded.sh`,
+plancher 4,4 GiB → `kill -TERM` du groupe, puis SIGKILL 5 s plus tard ; le job v1 n'avait pas de gestionnaire SIGTERM → code 143, rien sauvé).
+Mesures du `.mem` (échantillon toutes les ~2 s) : MemAvailable 10,36 Go (01:35:05) → 5,94 Go (01:35:17) → 4,41 Go (01:35:21), soit −5,9 Go en 16 s
+et −1,52 Go dans les 4 dernières s ; RSS du job plate à 951 696 Ko, max RSS groupe 1 159 248 Ko. Un trou de 44 s dans l'échantillonnage
+(01:34:21 → 01:35:05) est visible (garde/machine figée ? non établi). Cause externe au job (ballon VM / autres processus — non attribuée
+précisément). Tick 480 000/600 000 de l'époque 1/2, aucun point de reprise intra-époque en v1 → 4 h 28 perdues. Porte v1 : ÉCHEC (3 essais).
+
+## Fichiers
+| fichier | rôle |
+|---|---|
+| `train_m8v1b_v2.py` | copie éditée de `code/train_m8v1b.py` (copie de réf. `train_m8v1b.py.orig_ref`, diff `train_v2_vs_orig.diff`) |
+| `run_guarded_v2.py` | chien de garde v2 (remplace `code/run_guarded.sh` pour ce bras ; v1 non modifié, réf. `run_guarded.sh.orig_ref`) |
+| `gate_cm_try4.sh` | BROUILLON de porte cm essai 4, NON exécuté, non exécutable (chmod −x), refuse sans `GO_TRY4_USER` |
+| `tests/run_tests.py` | 26 tests synthétiques ; `tests/test_report.json`, `tests/run_tests.out` = résultats ; `tests/out/` = journaux (relancés en rév. 0227 : 26/26 PASS) |
+| `tests/run_tests_0227.py` | T15–T18 (réserves Checker .tmp / dossier vide / échec de sauvegarde / verrou) ; `tests/test_report_0227.json`, `tests/run_tests_0227.out` |
+| `tests/test_gate_try4.sh` | 29 tests à blanc de la porte (sandbox `tests/sbx_gate/`, supprimée après ; jamais la vraie file) ; `tests/test_gate_try4.out` |
+| `*.pre0227` | copies avant la révision 0227 ; `gate_try4_0227.diff`, `train_v2_0227.diff` = différences de la révision |
+| `tests/orig_loop_ref.py` | référence : `SpikingCore.train_pass` ORIGINAL sur la même config tiny, comparé octet pour octet |
+| `tests/disk_bench.py` | banc disque à la taille estimée d'un ckpt production |
+| `test_data/tiny600k.bin` | 600 000 premiers octets de `sample/v1b_sample.bin` |
+Aucun fichier figé modifié ; rien écrit dans `checker/`, `broad/`, `/tmp` (TMPDIR = `v2_resume/tmp`). Mathématiques du modèle inchangées.
+
+## (A) Checkpoint + `--resume` (train_m8v1b_v2.py)
+- **Passe SNN** = copie ligne à ligne de `SpikingCore.train_pass` (spiking.py l. 471-548, sha `beabae44…`), avec un point d'arrêt APRÈS chaque tick complet
+ (y compris décroissance `W_out`/`W_outG` et apprentissage lent). T1 : poids finaux `W_rec`, `W_out`, `W_out_G`, `beta`, précisions, `acc_ema_final`
+ identiques octet pour octet à l'original appelé tel quel.
+- **État sauvegardé** : TOUS les tableaux de `core` (W_rec, W_out, W_outG, W_in, W_inG, W_recG, v, thr, rhat, refr, x, x_prev, x_mean, x_eff,
+ _banks, _direct, s, v_G, thr_G, rhat_G, x_G, x_mean_G, s_G, win_spikes, u_slow, inhibitory, bornes…) + tous ses scalaires (tick, baseline, beta…,
+ type et dtype conservés) ; curseur (époque, tick) ; accumulateurs (n_correct, n_correct_fast, acc_ema, d_ema, temps écoulé) ; historique des époques ;
+ RNG global numpy (MT19937) et python (`random`) ; `m.meta`.
+ **AM** : elle n'est écrite qu'APRÈS les époques SNN (`write_stream`) ; pendant le SNN elle est dans son état de construction. Le ckpt stocke donc
+ l'empreinte sha256 de tous ses tableaux + scalaires, re-vérifiée sur l'AM reconstruite (pas les ~218 Mo de tableaux à am_size 8 M).
+ **Entrées** (`_neurons`, `_cols`, `_am_ctx`, `_ids_train`, `_reg_idx`, vocab, registre, EPT, `cm_sem`) : empreinte sha256 re-vérifiée.
+ Reprise = build + prepare déterministes (~35 s en production d'après le log de l'essai 3), vérification des empreintes, restauration EN PLACE
+ (lecture du membre npz directement dans `core.W_out` : pas de double allocation des ~436 Mo).
+- **Quand** : toutes les `--ckpt-every-s` (1800 s, horloge murale), à chaque fin d'époque, et sur SIGTERM/SIGUSR1 (le gestionnaire, installé avant
+ l'import de numpy, lève un drapeau ; le tick courant se termine, ckpt, sortie **75**). Arrêt demandé pendant build/prepare/AM/calibration/éval :
+ sortie 75 à la frontière de phase suivante, sans nouveau ckpt (reprise depuis le dernier ; après la fin du SNN, le ckpt `snn_done` fait refaire
+ AM + calibration + éval, déterministes).
+- **Atomique** : `ckpt_cm_NNNNNN.npz.tmp` → fsync → sha256 relu sur disque → rename → `.sha256` (tmp + fsync + rename) → fsync du dossier ;
+ puis suppression des plus anciens : **2 gardés** (courant + précédent). Testé : jamais plus de 2.
+- **Refus** (avant tout build, ~0,1 s) : sortie **65** = intégrité (absent, sidecar absent, sha256 faux, tronqué, zip illisible) ;
+ **68** = incompatible (format, clé meta = sha256 de {arm, sha données, cfg, options test, sha du code v2 + countmin + spiking + model + hippocampus},
+ ou empreintes entrées/AM reconstruites différentes). `--resume auto` prend le plus récent ; s'il est invalide → refus, sauf `--allow-fallback`
+ (essai du précédent, testé T8).
+- **Écarts assumés vs v1** (hors calcul) : (1) horodatage des entrées zip figé au 1980-01-01 dans tous les npz écrits (sinon deux runs identiques
+ diffèrent par l'heure) ; (2) `results.jsonl` : lignes d'éval mises en tampon et ajoutées en une fois à la fin (flock + fsync), même contenu/ordre ;
+ (3) options TEST (`--test-vocab-size`, `--test-am-size`, `--test-stop-at`, `--test-ckpt-every-ticks`, `--test-balloon-mb`) — elles entrent dans la
+ clé meta, jamais utilisées par la porte ; (4) plus de ckpt par époque v1 `runs/ckpt_cm/epochN.npz` (remplacé par `--ckpt-dir`).
+- **« Octet pour octet » — mesure honnête** : `cm__.npz` sont identiques au niveau du fichier brut (sha256) entre run interrompu+repris et
+ run continu. `cm.npz` et `results.jsonl` NE le sont PAS, et ne le sont pas non plus entre DEUX runs continus (T0) : `cm.npz` contient
+ `meta.segmentation_MB_per_s` (débit mesuré à l'horloge dans `SPIRA.build`, model.py, non modifiable ici) ; `results.jsonl` contient
+ `ticks_per_sec`, `eval_s`, `wall_s`, `peak_rss_mb` et `ckpt_sha256` (= sha du `cm.npz`). Critère retenu : sha256 canonique = tous les tableaux
+ (nom, dtype, forme, octets) avec ce seul champ de `meta` retiré, et `results.jsonl` sans ces 5 champs → **identique dans tous les scénarios**.
+ Tous les tableaux de poids, AM, sorties d'éval et précisions sont donc identiques octet pour octet.
+- **Taille / temps** : ckpt tiny (vocab 1024) = 40,8 Mo, sauvegarde (écriture + fsync + sha relu + rename + purge) moyenne 0,15 s, max 0,46 s
+ (50 ckpts). Production cm (n_state 6656, n_out 16 385) : **465,6 Mo calculés** depuis les formes (W_out 436,2 Mo, W_outG 16,8 Mo, W_in 10,5 Mo,
+ W_rec 1,0 Mo…). Banc disque à cette taille : écriture + fsync + relecture sha 0,72–0,79 s (3 essais). **Estimation** ckpt production ≈ 1–2 s
+ (non mesuré à cette taille : aucun entraînement lancé). Toutes les 30 min → surcoût < 0,1 %. Disque : 2 ckpts + 1 tmp ≈ 1,4 Go en pointe
+ (11 Go libres, 93 % utilisé). Le contenu RAM supplémentaire pendant la sauvegarde est borné par les blocs de 16 Mio de numpy (non mesuré en prod).
+
+## (B) Chien de garde v2 (run_guarded_v2.py)
+- Porte de lancement sur MemAvailable RÉEL : ≥ max(floor + pic, 5,2 Go) et lourds < 4, sinon 3. Job dans son groupe (setsid), nice 10.
+ Ne signale que ce groupe, et jamais après la récolte du leader (pas de PGID réutilisé). T11 : un processus témoin hors groupe survit.
+- **RSS du groupe** (somme VmRSS des PID de pgrp = groupe) > `--rss-cap` 3,5 Go → SIGUSR1 (arrêt propre, ckpt, 75) ; SIGKILL du groupe si pas sorti
+ après `--grace` (180 s).
+- **Plancher MemAvailable `--floor` = 4 000 000 000 o par défaut** (règle des 4 Go de Philippe-Antoine). Action par défaut (`--mode checkpoint`) :
+ arrêt propre → ckpt → 75 (perte ≤ 30 min de calcul au lieu de l'époque). La proposition Relay d'un plancher dur à 1,5 GiB violerait la règle ;
+ elle n'est PAS appliquée (Relay l'a retirée à 01 h 42) et ne le sera que sur oui explicite de Philippe-Antoine.
+- `--mode pause` (OPTION, OFF par défaut, décision utilisateur) : SIGSTOP du groupe sous le plancher ; SIGCONT quand MemAvailable ≥ plancher + 0,5 Go
+ pendant 60 s ; pause > 20 min → SIGCONT + arrêt propre (ckpt, 75). **La pause ne libère PAS la RSS du job (~0,95 Go en SNN) : elle n'arrête que
+ sa croissance et son CPU ; elle ne restaure pas la marge de 4 Go.** Seule la sortie (mode checkpoint) rend la mémoire.
+- `--hard-floor` (SIGKILL immédiat) : désactivé par défaut (0) ; aucune valeur choisie par Hashing.
+- Limites honnêtes : pendant l'arrêt propre le job vit encore ~1 tick + ~1–2 s de sauvegarde ; une chute aussi brutale que celle de 01 h 35
+ (−1,5 Go en 4 s) peut donc descendre encore sous le plancher avant la sortie ; l'OOM noyau reste possible si la chute dépasse la marge.
+ Un signal reçu avant l'installation du gestionnaire (~0,1 s au démarrage) tue le job (138/143, rien à sauver) ; la porte le traite en reprise.
+- TEST seulement : `SPIRA_WD_FAKE_MEMAVAIL_FILE` remplace MemAvailable pour la surveillance (jamais pour la porte), signalé en tête de journal.
+
+## (C) Tests (tous synthétiques ; `tests/run_tests.py` ; 26/26 PASS)
+Config : `--arm cm --snn-tokens 2000 --am-tokens 4000 --epochs 2 --maxpos 200 --windows seen,fresh_en --test-vocab-size 1024 --test-am-size 65536`
+sur `tiny600k.bin` (n_state 6656 comme la prod ; vocab réduit). Un process à la fois, nice 10, OMP=1, PYTHONHASHSEED=0, cap RSS de test 300 Mo
+(max mesuré 168,6 Mo ; 256 Mo pour T10 avec ballon). MemAvailable réel min pendant toute la série : 6,90 Go (≥ 5,2 Go ; garde 5,5 Go avant chaque job).
+- T0 : 2 runs continus — `cm__*.npz` identiques bruts ; `cm.npz`/`results.jsonl` diffèrent bruts (champs d'horloge, voir plus haut), identiques canoniques.
+- T1 : boucle v2 == `train_pass` original (poids, beta, précisions).
+- T2 arrêt mi-époque 1 (tick 737) ; T3 frontière d'époque ; T4 tick 1 ; T5 chaîne de 4 interruptions (1:300, 1:1999, 2:1, 2:1500) + ckpt tous les
+ 250 ticks (purge à 2) ; T6 après la dernière époque (AM+cal+éval refaites) → identiques canoniques, WEIGHTS et historique identiques.
+- T7 SIGTERM et SIGUSR1 réels mi-époque → ckpt + 75, reprise identique.
+- T8 refus : octet modifié 65, tronqué 65, sans sidecar 65, tronqué avec sidecar recalculé 65 (zip illisible), chemin absent 65,
+ auto + plus récent corrompu sans repli 65, autre config (epochs 3) 68 — tous avant build ; repli autorisé → précédent → identique.
+- T9 plancher simulé 3 999 999 999 o (< 4e9) → SIGUSR1 → ckpt + 75 → reprise identique.
+- T10 cap RSS groupe (cap 200 Mo, ballon test 150 Mo) → arrêt propre + ckpt + 75 → reprise sans ballon identique.
+- T11 enfant qui ignore SIGUSR1 → SIGKILL du groupe après la grâce (3 s) → 137 ; témoin hors groupe vivant.
+- T12 pause : état T sous le plancher, toujours T à plancher+0,3 Go, R après plancher+0,6 Go tenu 3 s ; run identique.
+- T13 pause > max → SIGCONT + ckpt + 75 → reprise identique. T14 porte de lancement fermée → 3, rien lancé.
+Les `ckpt_cm_*.npz` des tests ont été supprimés après la série (place disque : 1,9 Go) ; journaux, sidecars et rapport gardés.
+
+## (D) Porte brouillon `gate_cm_try4.sh` — rév. 0227 (audit Checker 02 h 25) — NON ARMÉE, NON LANCÉE, non exécutable
+Ancienne version : `gate_cm_try4.sh.pre0227` (sha d8b8dba1…, verdict Checker FAIL). Ordre des contrôles :
+1. `GO_TRY4_USER` absent → REFUS sur stderr, **aucun mkdir ni écriture** (P5). Le drapeau n'est qu'un garde-fou de procédure (P1) : tout process
+ de l'uid box peut le créer ; **un drapeau créé par un bot ne vaut pas le oui écrit de Philippe-Antoine. Hashing ne le crée jamais.**
+2. `HARD_FLOOR=0` : plancher dur (SIGKILL) **désactivé, passé explicitement** `--hard-floor 0` à la garde (G1). Toute valeur non nulle
+ (ex. 1,5 GiB = 1 610 612 736 o) → REFUS : c'est une décision de Philippe-Antoine (règle des 4 Go), oui écrit requis.
+3. mkdir ; `sha256sum -c SHA256SUMS` + entrées EXIGÉES pour `train_m8v1b_v2.py`, `run_guarded_v2.py`, `../code/verdict_M8v1b.py` (b3db0875…),
+ `../code/countmin.py` (caab5040…) (P6) ; re-vérifié avant chaque segment et avant le verdict ; `runs/ctl.npz` + `ctl__seen.npz` présents ;
+ aucune sortie cm (`cm.npz` OU `cm__*.npz` — l'ancien test `ls a b && …` ne refusait pas si `cm.npz` manquait mais `cm__*.npz` existait :
+ bogue trouvé par G4a, corrigé) ; `queue_postcm/DONE|SKIP/m8v1b_cm_try4` → RIEN À FAIRE, code 0.
+4. Attente (toutes les 60 s, motif dans `STATUS_try4`) jusqu'à : (a) **M8cp1 terminé** (P3) — aucun process dont la ligne de commande correspond à
+ `code_prose_v1_sample_reint\.bin|run_guarded_cp1\.sh|gate_m8cp1\.sh|wait_then_arm_cp1\.sh`, aucun des PID 1315671 / 1438809 / 1312959
+ vivant AVEC le nom attendu (un PID réutilisé par une autre commande ne compte pas), et `m8_cp1/STATUS` terminal (`FINI…` ou `ÉCHEC…`) ;
+ (b) **file post_cm** (P4, même code que `post_cm_diag.sh`) : `ORDER` absent/vide/invalide → attente ; tour seulement si `m8v1b_cm_try4` est le
+ premier job de ORDER sans DONE/SKIP ; `flock -x` sur `queue.lock` (fd 9), conditions re-vérifiées sous verrou, verrou tenu jusqu'à la fin
+ (hérité par la garde et l'entraîneur) ; (c) **RAM** (P2) : MemAvailable ≥ 4e9 + 3,5e9 = **7 500 000 000 o** et lourds < 4 (aussi passé
+ `--min-launch 7500000000` à la garde).
+5. Segment : `run_guarded_v2.py --floor 4000000000 --rss-cap 3500000000 --hard-floor 0 --mode checkpoint --grace 180` → `train_m8v1b_v2.py`
+ (args de l'essai 3) `--resume auto --allow-fallback`, plus `--fresh` **seulement tant qu'aucun ckpt n'a jamais été vu** (marqueur
+ `logs/try4_ckpt_seen`) : un dossier vidé ensuite donne 66 → ÉCHEC au lieu d'un redémarrage silencieux (G3).
+6. Codes : 0 → sha re-vérifiés, verdict figé, `DONE/m8v1b_cm_try4` écrit ; 3 → non compté ; 75 → reprise (≤ 12) ; 137/138/143 → reprise (≤ 3) ;
+ 65/66/68/73/74/autre → ÉCHEC, **pas de DONE**, verrou relâché, décision humaine. La porte n'envoie aucun signal (lecture `/proc` seulement).
+Tests (`tests/test_gate_try4.sh`, 29/29 PASS) : bash -n, porte non exécutable, 6 lignes `SANDBOX-SUBST` seulement substituées ; sans drapeau
+(rc 1, rien créé) ; HARD_FLOOR 1,5 GiB refusé ; countmin modifié / verdict absent de SHA256SUMS refusés ; sorties cm présentes refusées ; DONE →
+rien à faire ; leurre cmdline cp1 → attente ; leurre PID+nom → attente ; PID réutilisé → ignoré ; STATUS cp1 « EN COURS » → attente ; « ÉCHEC »
+→ passe ; ORDER absent / pas mon tour / invalide / tête SKIP → comportements attendus ; queue.lock tenu → attente ; RAM 7 499 998 208 o → attente,
+7 500 000 256 o → passe ; séquence 75,75,137,0 : `--fresh` au 1er segment seulement, args garde vérifiés, verrou tenu pendant chaque segment,
+verdict exécuté, DONE écrit, verrou relâché ; 66/74/65 → ÉCHEC sans DONE ; 4 kills → ÉCHEC ; code 3 non compté ; drapeau retiré → arrêt ;
+vraie `queue_postcm` inchangée, aucun drapeau/état réel créé. Garde et verdict y sont des scripts factices : **aucun entraînement**.
+
+## (E) Révision 0227 de `train_m8v1b_v2.py` (réserves Checker §5.2 / point 6)
+- Au démarrage : verrou exclusif `CK/.writer.lock` (sinon **73**) puis suppression des `.tmp` orphelins de CE bras (`ckpt__N.npz.tmp`,
+ `….sha256.tmp`, journalisée) — un `.tmp` de production ≈ 466 Mo, disque à 93 %. Autres fichiers non touchés.
+- Échec de sauvegarde (exception pendant écriture/sha/rename) : suppression du `.tmp`, du `.sha256.tmp`, et du `.npz` sans sidecar ; ckpts valides
+ conservés ; sortie **74**. Option TEST `--test-fail-save N` (hors clé meta) pour le simuler.
+- `--resume auto` sans aucun ckpt → **66** (avant tout build) sauf `--fresh` explicite (hors clé meta).
+- Tests `tests/run_tests_0227.py` 5/5 PASS (T15 .tmp nettoyés + fichiers étrangers gardés + reprise identique ; T16 66 puis `--fresh` identique ;
+ T17 74, aucun .tmp, ckpt 1 intact (sha OK), reprise identique ; T18 73 ; MemAvailable réel min ≥ 5,2 Go). Suite complète `run_tests.py`
+ relancée sur le nouveau code : 26/26 PASS (MemAvailable réel min 7,03 Go). Mathématiques inchangées (canonique, WEIGHTS, historique identiques).
+- `run_guarded_v2.py` NON modifié (53d23602…). Réserves Checker G2 (plancher = MemAvailable système, inhérent au but) et G3 (orphelins après sortie
+ du leader non tués/non comptés : corriger exigerait de signaler un PGID possiblement réutilisé ; sans effet ici, l'entraîneur est mono-process)
+ restent ouvertes, listées.
+
+## Décisions de Philippe-Antoine (non prises par Hashing)
+- Oui écrit pour l'essai 4 (puis création de `GO_TRY4_USER` par lui, ou sur son oui explicite) ; contenu de `queue_postcm/ORDER` (absent → la porte attend).
+- Plancher dur (`HARD_FLOOR`, 0 = off) : 1,5 GiB seulement sur son oui.
+- Audit §7.8 : `cal.scale` du ctl v1b = 0,028181870546416927 < 0,03 → le verdict M8v1b sera **NON MESURABLE quel que soit l'essai 4**, sauf décision
+ de sa part sur la plage de scale.
+
+## Codes de sortie
+0 fini · 75 arrêt propre reprenable · 65 ckpt refusé (intégrité) · 68 ckpt refusé (incompatible) · 66 `--resume` sans ckpt et sans `--fresh` ·
+73 dossier de ckpt verrouillé · 74 échec de sauvegarde (tmp nettoyés) · 2 usage · 3 porte fermée (garde) · 137 tué par la garde · 138/143 signal
+avant gestionnaire.
diff --git a/results/hashing/m8_v1b/v2_resume/SHA256SUMS b/results/hashing/m8_v1b/v2_resume/SHA256SUMS
new file mode 100644
index 0000000000000000000000000000000000000000..ac048a4d6489ac5e1ba0af251ea74d98cd2fb938
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/SHA256SUMS
@@ -0,0 +1,32 @@
+0ebbabd9f6565cf0aadd818ae1fafe416243f5d8addf18d78cef28234ae697be README.md
+66c55888a1d80c60724a699347ae562fa777c20272f24652540a6e42d96f695c train_m8v1b_v2.py
+53d23602a189dcd25b540922ef15ef76a4e0046bdbaab7285493288dd91fd540 run_guarded_v2.py
+58912fbb0d423956df89467f486433ab886b838f41f2f64644b67820dc770b78 gate_cm_try4.sh
+b3db0875b6e01d2c2192d9e307d337a3fb908f524f7be5e3a9a5b380eec7d7dc ../code/verdict_M8v1b.py
+caab50405e73eba7981f73a63fb1709139aed55383501c3e830e174cb02b8d3b ../code/countmin.py
+bce839fa23b1b942ef3bc6341a495b4b82066a051e6702539ecc6309e85213a3 train_v2_vs_orig.diff
+9ba5c13b2a5dbc0ba5b86b9369b0d46b94ffa2679c467cbe4c4694f04e9d21fa train_v2_0227.diff
+08f89b7b893aaf9f736c77a37c760f214b1978ab39c3ade52e4d572cab8fa89b gate_try4_0227.diff
+b2b12c8c6beb4b76954b6da99b0f273ca5eefad11268355786b8c3d420719e3c train_m8v1b.py.orig_ref
+f4bf377e601eca804a9383755ba863b3882c9b692624b0f21eb1e60c57076645 run_guarded.sh.orig_ref
+e598d2eb8f046b57bd34040154dedb237aeeca82373755d98bf2e27c831851f2 train_m8v1b_v2.py.pre0227
+d8b8dba1b51ef18e153eca204fff0a3308bbd9f7b6eed7351b5d348c24fd7d17 gate_cm_try4.sh.pre0227
+d7077225ac00e77250d13e1f4f9a34a73cae19491870734a6534d4f0ace25814 README.md.pre0227
+919c95ebf00f816d1becd75e2d28c1ec1ce19369449e3828411b8e73f5ca1505 SHA256SUMS.pre0227
+edb857d1cf1095dff51c7605ff120fdc404c77e72d3f6fd310b5fae664dd8406 train_v2_vs_orig.diff.pre0227
+9392ebb54c2a9b43de481a3f2be5e695531e93979fb23460373f07ba84af96f8 tests/run_tests.py
+3484c0cfc894d9e5dcf4bae4bd14ca81fd132a00358180500228dc411eecaaee tests/run_tests_0227.py
+3232bf66529f534f3068a99a20dbc764145ebdbe9a72e60277eca131e305046f tests/test_gate_try4.sh
+51324448e94a1faf85efda90dcdbdf673a3571734f7a79b1b9e70407cedb2f3a tests/orig_loop_ref.py
+1c071558ba299c17504cfe518ab6bedce490f7691fd83e7aaa149dbd7c51e240 tests/disk_bench.py
+a32988711f025193de3d4b96a24d0e0cc1629ffeb0de6501e07ce0fd25145039 tests/peakrun.py
+ba97c0891eee30a5d4825b1fb0bccb12bdf20036ed5be441eb3214ce402b62fd tests/test_report.json
+14c5704d5f75a485c4bc5bf98220b8a0013a27322c4758714774125c1fe08aa7 tests/run_tests.out
+e2fbb375edcb41cbc98d209c9b7c6c810464251d472c0ee6812922d08fb9f3a2 tests/test_report_0227.json
+25fd1e9b00c1324bc9919c89cec8774cc28e5029a43691fe1a46dcea68912838 tests/run_tests_0227.out
+8784fab2df7fb11926b72cbfe1602edefe9de877a261513861034cc2e2c6f0a7 tests/test_gate_try4.out
+ce941fa224835fb7313083875ac67e06ccbf09ea59c197b7b72ef71db0ab9036 tests/disk_bench.out
+9392ebb54c2a9b43de481a3f2be5e695531e93979fb23460373f07ba84af96f8 tests/run_tests.py.pre0227
+40b5b3dbafc81490b2de6d3ccbe49fd460ecf2579e7d899f737b43ed747ae8b9 tests/test_report.json.pre0227
+1a4466c80425f8b7762d6ee623b29f369e6e1a44aa99c0052cd1dbd860bff777 tests/run_tests.out.pre0227
+99e1b7ac41855d5de60e36f85a5857d36bf387bfbab7dc6ab6c8113ee96e60f2 test_data/tiny600k.bin
diff --git a/results/hashing/m8_v1b/v2_resume/gate_cm_try4.sh b/results/hashing/m8_v1b/v2_resume/gate_cm_try4.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b41338849edf8fd30a5e7a19237f09259c05d943
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/gate_cm_try4.sh
@@ -0,0 +1,123 @@
+#!/bin/bash
+# SPIRA Hashing — BROUILLON de porte « cm essai 4 » (M8 v1b) avec checkpoint/--resume. Révision 0227 (audit Checker 02 h 25 : P2–P6, G1–G3).
+# NON ARMÉE, JAMAIS LANCÉE par Hashing, non exécutable (chmod -x). Un essai 4 exige le OUI ÉCRIT de Philippe-Antoine.
+# Drapeau $V2/GO_TRY4_USER : jamais créé par ce script ni par un bot ; un drapeau créé par un bot ne vaut PAS le oui de Philippe-Antoine
+# (garde-fou de procédure seulement, cf. audit P1). Re-vérifié avant CHAQUE (re)lancement.
+# Ordre des contrôles :
+# 1. drapeau absent => REFUS (stderr seulement : AUCUN mkdir, AUCUNE écriture — P5) ;
+# 2. HARD_FLOOR doit valoir 0 (G1 : plancher dur DÉSACTIVÉ, passé explicitement à la garde) ; toute autre valeur (ex. 1,5 GiB) => REFUS :
+# décision de Philippe-Antoine requise (règle des 4 Go) ;
+# 3. puis seulement : mkdir logs/ et ckpt ; sha256sum -c SHA256SUMS (code v2 + ../code/verdict_M8v1b.py + ../code/countmin.py, entrées exigées — P6) ;
+# runs/ctl* présents ; aucune sortie cm dans runs/ ; DONE|SKIP/$JOB dans la file => rien à faire ;
+# 4. boucle d'attente (re-vérifiée avant chaque segment) :
+# a. M8cp1 (P3) : AUCUN travailleur ni porte cp1 vivant — par LIGNE DE COMMANDE (CP1_RE) ET par PID connus avec contrôle du nom
+# (1315671 ctl, 1438809 cm, 1312959 gate_m8cp1.sh ; un PID réutilisé par une autre commande ne compte pas) — ET STATUS cp1 terminal
+# (« FINI… » ou « ÉCHEC… ») ; le nombre de lourds n'est qu'un contrôle secondaire ;
+# b. file post_cm (P4, même mécanisme que post_cm_diag.sh) : ORDER absent/vide/invalide => ATTENTE ; tour seulement si $JOB est le premier
+# job de ORDER sans DONE/ ni SKIP/ ; flock -x sur queue.lock (fd 9), re-vérifié SOUS verrou, tenu jusqu'à la fin de la porte ;
+# DONE/$JOB écrit seulement si l'entraînement cm finit (code 0) et que le verdict figé a été exécuté ; échec => rien dans la file ;
+# c. RAM (P2) : MemAvailable >= NEED = FLOOR + RSSCAP = 7 500 000 000 o, et lourds < 4 ;
+# 5. segment : run_guarded_v2.py (--floor 4e9 --rss-cap 3,5e9 --hard-floor 0 --mode checkpoint --min-launch 7,5e9) -> train_m8v1b_v2.py,
+# mêmes args que l'essai 3, --resume auto --allow-fallback ; --fresh (départ à zéro autorisé) SEULEMENT tant qu'aucun ckpt n'a jamais été vu
+# (marqueur logs/try4_ckpt_seen) : sinon un dossier vidé donne 66 => ÉCHEC (G3) ; les .tmp orphelins sont nettoyés par l'entraîneur (G2).
+# Codes : 0 => verdict figé ; 3 => porte de la garde fermée, non compté ; 75 => reprise (<= RESUME_MAX) ; 137/138/143 => reprise (<= KILL_MAX) ;
+# 65/66/68/73/74/autres => ÉCHEC, décision humaine. Ce script n'envoie AUCUN signal à aucun processus (lecture /proc seulement).
+export TZ=America/Toronto OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0 PYTHONDONTWRITEBYTECODE=1
+S=/workspace/spira_shared # SANDBOX-SUBST
+D=$S/hashing_gen/m8_v1b; V2=$D/v2_resume; CP1=$S/hashing_gen/code_prose_v1/m8_cp1; QD=$S/queue_postcm
+PY=/workspace/SPIRA-venv/bin/python # SANDBOX-SUBST
+MEMINFO=/proc/meminfo # SANDBOX-SUBST
+CP1_RE='code_prose_v1_sample_reint\.bin|run_guarded_cp1\.sh|gate_m8cp1\.sh|wait_then_arm_cp1\.sh' # SANDBOX-SUBST
+CP1_PIDS="1315671:train_m8v1b.py 1438809:train_m8v1b.py 1312959:gate_m8cp1.sh" # SANDBOX-SUBST
+POLL_S=60 # SANDBOX-SUBST
+HARD_FLOOR=0 # G1 : 0 = plancher dur DÉSACTIVÉ (passé explicitement). Toute valeur non nulle exige le oui écrit de Philippe-Antoine ; la porte la refuse.
+JOB=m8v1b_cm_try4; GO=$V2/GO_TRY4_USER; ST=$V2/STATUS_try4; GL=$V2/logs/gate_cm_try4.log; CKD=$V2/ckpt_cm_try4; MARK=$V2/logs/try4_ckpt_seen
+FLOOR=4000000000; RSSCAP=3500000000; NEED=$((FLOOR + RSSCAP)); PEAK=2500000000; GRACE=180; RESUME_MAX=12; KILL_MAX=3
+NRES=0; NKILL=0; n=0; QLOCK_HELD=0
+if [ ! -e "$GO" ]; then echo "REFUS : $GO absent (oui écrit de Philippe-Antoine requis pour un essai 4) — rien créé, rien lancé" >&2; exit 1; fi
+if [ "$HARD_FLOOR" != 0 ]; then echo "REFUS : HARD_FLOOR=$HARD_FLOOR != 0 — tout plancher dur est une DÉCISION de Philippe-Antoine (règle des 4 Go)" >&2; exit 1; fi
+mkdir -p $V2/logs $CKD
+export TMPDIR=$D/tmp; mkdir -p $TMPDIR
+log(){ echo "$(date '+%F %H:%M:%S %Z') $*" >> $GL; }
+status(){ echo "$(date '+%F %H:%M:%S %Z') $* | resumes=$NRES kills=$NKILL segments=$n | gate pid $$" > $ST; }
+mem(){ awk '/MemAvailable/{print $2*1024}' $MEMINFO; }
+nheavy(){ ps -eo rss,comm | awk '$2 ~ /^python/ && $1>=500000' | wc -l; }
+cmdline(){ tr '\0' ' ' 2>/dev/null < /proc/$1/cmdline; }
+cp1_busy(){ # PIDs cp1 vivants (cmdline CP1_RE, ou PID connu dont la cmdline contient le nom attendu) ; lecture /proc seulement
+ local d p c out="" e
+ for d in /proc/[0-9]*; do p=${d#/proc/}; [ "$p" = "$$" ] && continue
+ c=$(cmdline $p) || continue; [ -n "$c" ] || continue
+ printf '%s' "$c" | grep -Eq -- "$CP1_RE" && out="$out $p"
+ done
+ for e in $CP1_PIDS; do p=${e%%:*}; c=$(cmdline $p) || continue
+ case "$c" in *"${e#*:}"*) case " $out " in *" $p "*) ;; *) out="$out $p";; esac;; esac
+ done; echo $out; }
+cp1_status_terminal(){ local s; s=$(cut -d' ' -f4- $CP1/STATUS 2>/dev/null); case "$s" in FINI*|ÉCHEC*) return 0;; esac; echo "${s:-STATUS cp1 illisible}"; return 1; }
+queue_head(){ # = post_cm_diag.sh : premier job de ORDER sans DONE/ ni SKIP/ ; code 1 = ORDER absent/vide ; code 2 = ligne invalide
+ local line n=0; [ -s $QD/ORDER ] || return 1
+ while IFS= read -r line || [ -n "$line" ]; do
+ line=${line%$'\r'}; line="${line#"${line%%[![:space:]]*}"}"; line="${line%"${line##*[![:space:]]}"}"
+ [ -z "$line" ] && continue; [ "${line:0:1}" = "#" ] && continue; n=$((n+1))
+ [[ $line =~ ^[A-Za-z0-9_][A-Za-z0-9_.-]*$ ]] || { echo "$line"; return 2; }
+ [ -e "$QD/DONE/$line" ] || [ -e "$QD/SKIP/$line" ] || { echo "$line"; return 0; }
+ done < $QD/ORDER
+ [ $n -gt 0 ] || return 1; echo ""; return 0; }
+queue_wait_msg(){
+ local h r; h=$(queue_head); r=$?
+ case $r in 1) echo "ORDER absent ou vide ($QD/ORDER) : attente de la décision de Philippe-Antoine"; return;;
+ 2) echo "ORDER invalide (ligne « $h »)"; return;; esac
+ [ "$h" = "$JOB" ] && return; [ -z "$h" ] && { echo "$JOB absent de ORDER (ou tous faits)"; return; }; echo "pas mon tour : tête de ORDER = $h"; }
+queue_release(){ [ $QLOCK_HELD = 1 ] && { flock -u 9; exec 9>&-; QLOCK_HELD=0; log "file : queue.lock relâché"; }; return 0; }
+trap queue_release EXIT
+ready(){ # "" si toutes les conditions (hors file) sont remplies, sinon le motif
+ local b s m nh
+ [ -e "$GO" ] || { echo "DRAPEAU_RETIRÉ"; return; }
+ b=$(cp1_busy); [ -n "$b" ] && { echo "M8cp1 vivant (PIDs$( for p in $b; do printf ' %s' $p; done))"; return; }
+ s=$(cp1_status_terminal) || { echo "STATUS M8cp1 non terminal : $s"; return; }
+ m=$(mem); nh=$(nheavy); { [ "$m" -ge $NEED ] && [ $nh -lt 4 ]; } || { echo "RAM MemAvailable=$m < $NEED (= plancher $FLOOR + cap $RSSCAP) ou lourds=$nh >= 4"; return; }
+}
+wait_turn(){ # revient avec toutes les conditions remplies ET queue.lock tenu (fd 9)
+ local w
+ while :; do
+ w=$(ready); [ "$w" = DRAPEAU_RETIRÉ ] && { log "drapeau retiré -> arrêt"; status "ARRÊT drapeau retiré"; exit 1; }
+ [ -n "$w" ] && { status "ATTENTE $w"; sleep $POLL_S; continue; }
+ if [ $QLOCK_HELD = 0 ]; then
+ w=$(queue_wait_msg); [ -n "$w" ] && { status "ATTENTE file : $w"; sleep $POLL_S; continue; }
+ exec 9>>$QD/queue.lock
+ if ! flock -x -w $POLL_S 9; then exec 9>&-; status "ATTENTE file : queue.lock tenu par un autre job"; continue; fi
+ w=$(queue_wait_msg); if [ -n "$w" ]; then flock -u 9; exec 9>&-; status "ATTENTE file : $w"; sleep $POLL_S; continue; fi
+ QLOCK_HELD=1; log "file : tour obtenu, queue.lock tenu, ORDER=$(grep -v '^ *#' $QD/ORDER | tr -s ' \n' ' ')"
+ fi
+ w=$(ready); [ -z "$w" ] && return 0 # re-vérifié SOUS verrou
+ [ "$w" = DRAPEAU_RETIRÉ ] && { log "drapeau retiré -> arrêt"; status "ARRÊT drapeau retiré"; exit 1; }
+ status "ATTENTE (verrou tenu) $w"; sleep $POLL_S
+ done; }
+log "ARMÉ pid=$$ sha256=$(sha256sum $0 | cut -c1-64) ; drapeau $GO présent ; plancher=$FLOOR cap=$RSSCAP need=$NEED hard_floor=$HARD_FLOOR (désactivé)"
+( cd $V2 && sha256sum -c --quiet SHA256SUMS ) >> $GL 2>&1 || { log "REFUS : SHA256SUMS ne correspond plus (code modifié depuis l'audit ?)"; status "REFUS SHA256SUMS"; exit 1; }
+for f in train_m8v1b_v2.py run_guarded_v2.py ../code/verdict_M8v1b.py ../code/countmin.py; do
+ grep -Eq "^[0-9a-f]{64} $f\$" $V2/SHA256SUMS || { log "REFUS : $f absent de SHA256SUMS (P6)"; status "REFUS SHA256SUMS incomplet ($f)"; exit 1; }; done
+for f in $D/runs/ctl.npz $D/runs/ctl__seen.npz; do [ -e $f ] || { log "REFUS $f absent"; status "REFUS $f absent"; exit 1; }; done
+for f in $D/runs/cm.npz $D/runs/cm__*.npz; do [ -e "$f" ] && { log "REFUS : sortie cm déjà présente ($f)"; status "REFUS sorties cm présentes"; exit 1; }; done
+if [ -e $QD/DONE/$JOB ] || [ -e $QD/SKIP/$JOB ]; then log "RIEN À FAIRE : $QD/DONE|SKIP/$JOB existe"; status "RIEN À FAIRE (DONE/SKIP $JOB)"; exit 0; fi
+while :; do
+ wait_turn
+ ( cd $V2 && sha256sum -c --quiet SHA256SUMS ) >> $GL 2>&1 || { log "REFUS : SHA256SUMS ne correspond plus"; status "REFUS SHA256SUMS"; exit 1; }
+ ls $CKD/ckpt_cm_*.npz.sha256 >/dev/null 2>&1 && : > $MARK
+ if [ -e $MARK ]; then R="--resume auto --allow-fallback"; else R="--resume auto --allow-fallback --fresh"; fi
+ n=$((n+1)); log "LANCE cm essai 4 segment $n MemAvailable=$(mem) need=$NEED $R"; status "EN COURS segment $n"
+ $PY $V2/run_guarded_v2.py --name m8v1b_cm_try4 --log $V2/logs/arm_cm_try4_seg$n.log --guard-log $V2/logs/guarded_v2.log \
+ --peak $PEAK --min-launch $NEED --floor $FLOOR --rss-cap $RSSCAP --hard-floor $HARD_FLOOR --grace $GRACE --mode checkpoint -- \
+ $PY -u $V2/train_m8v1b_v2.py --arm cm --data $D/sample/v1b_sample.bin --outdir $D/runs --ckpt-dir $CKD \
+ --snn-tokens 600000 --am-tokens 1200000 --epochs 2 --maxpos 4000 --windows seen,fc2,fresh_en,fresh_fr,test20k,test_v3,queries $R
+ e=$?; log "segment $n fin code $e"
+ ls $CKD/ckpt_cm_*.npz.sha256 >/dev/null 2>&1 && : > $MARK
+ case $e in
+ 0) ( cd $V2 && sha256sum -c --quiet SHA256SUMS ) >> $GL 2>&1 || { log "REFUS verdict : SHA256SUMS ne correspond plus"; status "ENTRAÎNEMENT FINI — verdict NON exécuté (sha)"; exit 1; }
+ status "VERDICT en cours"; nice -n 10 $PY -u $D/code/verdict_M8v1b.py > $V2/logs/verdict_M8v1b_try4_run.log 2>&1; v=$?
+ log "verdict code $v"; : > $QD/DONE/$JOB; log "file : DONE/$JOB écrit"; status "FINI verdict code $v ; DONE/$JOB écrit"; exit $v ;;
+ 3) n=$((n-1)); sleep $POLL_S ;;
+ 75) NRES=$((NRES+1)); [ $NRES -gt $RESUME_MAX ] && { status "ÉCHEC trop de reprises (pas de DONE)"; log "ÉCHEC reprises > $RESUME_MAX"; exit 1; }; sleep $POLL_S ;;
+ 137|138|143) NKILL=$((NKILL+1)); [ $NKILL -gt $KILL_MAX ] && { status "ÉCHEC trop de kills (pas de DONE)"; log "ÉCHEC kills > $KILL_MAX"; exit 1; }; sleep $POLL_S ;;
+ *) status "ÉCHEC code $e (65/68 ckpt refusé, 66 dossier ckpt vide, 73 verrou, 74 sauvegarde) — pas de DONE, décision humaine"; log "ÉCHEC code $e"; exit 1 ;;
+ esac
+done
diff --git a/results/hashing/m8_v1b/v2_resume/gate_try4_0227.diff b/results/hashing/m8_v1b/v2_resume/gate_try4_0227.diff
new file mode 100644
index 0000000000000000000000000000000000000000..94a4918fd48961e027d2b99b9d70ef0816346d1c
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/gate_try4_0227.diff
@@ -0,0 +1,160 @@
+--- gate_cm_try4.sh.pre0227 2026-10-25 01:57:13.335651802 -0400
++++ gate_cm_try4.sh 2026-10-25 02:37:24.631988942 -0400
+@@ -1,46 +1,123 @@
+ #!/bin/bash
+-# SPIRA Hashing — BROUILLON de porte « cm essai 4 » (M8 v1b) avec checkpoint/--resume. NON ARMÉE, JAMAIS LANCÉE par Hashing.
+-# Un essai 4 exige le OUI ÉCRIT de Philippe-Antoine. Ce script ne démarre RIEN tant que le drapeau $V2/GO_TRY4_USER n'existe pas
+-# (il ne le crée JAMAIS ; il le re-vérifie avant CHAQUE (re)lancement). Le bras ctl est déjà fait (runs/ctl*, essai 1, code 0).
+-# Bras cm : train_m8v1b_v2.py (mêmes maths, mêmes args que l'essai 3) sous run_guarded_v2.py :
+-# plancher MemAvailable 4 000 000 000 o (règle des 4 Go) -> checkpoint + sortie 75 ; cap RSS groupe 3,5 Go ; mode pause NON activé.
+-# checkpoint toutes les 30 min + fin d'époque ; 2 gardés dans $CKD.
+-# Sortie 75 (arrêt propre) => attendre la RAM puis relancer avec --resume auto (pas un nouvel essai ; max $RESUME_MAX reprises).
+-# Sortie 137 (tué après délai de grâce) ou 138/143 (signal reçu avant installation du gestionnaire, rien à sauver) => idem, reprise depuis le dernier ckpt valide (--allow-fallback), max $KILL_MAX.
+-# Sortie 65/68 (ckpt refusé) ou tout autre code => ÉCHEC, arrêt, décision humaine. Sortie 0 => verdict figé (code/verdict_M8v1b.py).
++# SPIRA Hashing — BROUILLON de porte « cm essai 4 » (M8 v1b) avec checkpoint/--resume. Révision 0227 (audit Checker 02 h 25 : P2–P6, G1–G3).
++# NON ARMÉE, JAMAIS LANCÉE par Hashing, non exécutable (chmod -x). Un essai 4 exige le OUI ÉCRIT de Philippe-Antoine.
++# Drapeau $V2/GO_TRY4_USER : jamais créé par ce script ni par un bot ; un drapeau créé par un bot ne vaut PAS le oui de Philippe-Antoine
++# (garde-fou de procédure seulement, cf. audit P1). Re-vérifié avant CHAQUE (re)lancement.
++# Ordre des contrôles :
++# 1. drapeau absent => REFUS (stderr seulement : AUCUN mkdir, AUCUNE écriture — P5) ;
++# 2. HARD_FLOOR doit valoir 0 (G1 : plancher dur DÉSACTIVÉ, passé explicitement à la garde) ; toute autre valeur (ex. 1,5 GiB) => REFUS :
++# décision de Philippe-Antoine requise (règle des 4 Go) ;
++# 3. puis seulement : mkdir logs/ et ckpt ; sha256sum -c SHA256SUMS (code v2 + ../code/verdict_M8v1b.py + ../code/countmin.py, entrées exigées — P6) ;
++# runs/ctl* présents ; aucune sortie cm dans runs/ ; DONE|SKIP/$JOB dans la file => rien à faire ;
++# 4. boucle d'attente (re-vérifiée avant chaque segment) :
++# a. M8cp1 (P3) : AUCUN travailleur ni porte cp1 vivant — par LIGNE DE COMMANDE (CP1_RE) ET par PID connus avec contrôle du nom
++# (1315671 ctl, 1438809 cm, 1312959 gate_m8cp1.sh ; un PID réutilisé par une autre commande ne compte pas) — ET STATUS cp1 terminal
++# (« FINI… » ou « ÉCHEC… ») ; le nombre de lourds n'est qu'un contrôle secondaire ;
++# b. file post_cm (P4, même mécanisme que post_cm_diag.sh) : ORDER absent/vide/invalide => ATTENTE ; tour seulement si $JOB est le premier
++# job de ORDER sans DONE/ ni SKIP/ ; flock -x sur queue.lock (fd 9), re-vérifié SOUS verrou, tenu jusqu'à la fin de la porte ;
++# DONE/$JOB écrit seulement si l'entraînement cm finit (code 0) et que le verdict figé a été exécuté ; échec => rien dans la file ;
++# c. RAM (P2) : MemAvailable >= NEED = FLOOR + RSSCAP = 7 500 000 000 o, et lourds < 4 ;
++# 5. segment : run_guarded_v2.py (--floor 4e9 --rss-cap 3,5e9 --hard-floor 0 --mode checkpoint --min-launch 7,5e9) -> train_m8v1b_v2.py,
++# mêmes args que l'essai 3, --resume auto --allow-fallback ; --fresh (départ à zéro autorisé) SEULEMENT tant qu'aucun ckpt n'a jamais été vu
++# (marqueur logs/try4_ckpt_seen) : sinon un dossier vidé donne 66 => ÉCHEC (G3) ; les .tmp orphelins sont nettoyés par l'entraîneur (G2).
++# Codes : 0 => verdict figé ; 3 => porte de la garde fermée, non compté ; 75 => reprise (<= RESUME_MAX) ; 137/138/143 => reprise (<= KILL_MAX) ;
++# 65/66/68/73/74/autres => ÉCHEC, décision humaine. Ce script n'envoie AUCUN signal à aucun processus (lecture /proc seulement).
+ export TZ=America/Toronto OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0 PYTHONDONTWRITEBYTECODE=1
+-D=/workspace/spira_shared/hashing_gen/m8_v1b; V2=$D/v2_resume; PY=/workspace/SPIRA-venv/bin/python
+-export TMPDIR=$D/tmp
+-GO=$V2/GO_TRY4_USER; ST=$V2/STATUS_try4; GL=$V2/logs/gate_cm_try4.log; CKD=$V2/ckpt_cm_try4
+-FLOOR=4000000000; PEAK=2500000000; MINL=5200000000; RSSCAP=3500000000; GRACE=180; RESUME_MAX=12; KILL_MAX=3
++S=/workspace/spira_shared # SANDBOX-SUBST
++D=$S/hashing_gen/m8_v1b; V2=$D/v2_resume; CP1=$S/hashing_gen/code_prose_v1/m8_cp1; QD=$S/queue_postcm
++PY=/workspace/SPIRA-venv/bin/python # SANDBOX-SUBST
++MEMINFO=/proc/meminfo # SANDBOX-SUBST
++CP1_RE='code_prose_v1_sample_reint\.bin|run_guarded_cp1\.sh|gate_m8cp1\.sh|wait_then_arm_cp1\.sh' # SANDBOX-SUBST
++CP1_PIDS="1315671:train_m8v1b.py 1438809:train_m8v1b.py 1312959:gate_m8cp1.sh" # SANDBOX-SUBST
++POLL_S=60 # SANDBOX-SUBST
++HARD_FLOOR=0 # G1 : 0 = plancher dur DÉSACTIVÉ (passé explicitement). Toute valeur non nulle exige le oui écrit de Philippe-Antoine ; la porte la refuse.
++JOB=m8v1b_cm_try4; GO=$V2/GO_TRY4_USER; ST=$V2/STATUS_try4; GL=$V2/logs/gate_cm_try4.log; CKD=$V2/ckpt_cm_try4; MARK=$V2/logs/try4_ckpt_seen
++FLOOR=4000000000; RSSCAP=3500000000; NEED=$((FLOOR + RSSCAP)); PEAK=2500000000; GRACE=180; RESUME_MAX=12; KILL_MAX=3
++NRES=0; NKILL=0; n=0; QLOCK_HELD=0
++if [ ! -e "$GO" ]; then echo "REFUS : $GO absent (oui écrit de Philippe-Antoine requis pour un essai 4) — rien créé, rien lancé" >&2; exit 1; fi
++if [ "$HARD_FLOOR" != 0 ]; then echo "REFUS : HARD_FLOOR=$HARD_FLOOR != 0 — tout plancher dur est une DÉCISION de Philippe-Antoine (règle des 4 Go)" >&2; exit 1; fi
++mkdir -p $V2/logs $CKD
++export TMPDIR=$D/tmp; mkdir -p $TMPDIR
+ log(){ echo "$(date '+%F %H:%M:%S %Z') $*" >> $GL; }
+-status(){ echo "$(date '+%F %H:%M:%S %Z') $* | resumes=$NRES kills=$NKILL | gate pid $$" > $ST; }
+-mem(){ awk '/MemAvailable/{print $2*1024}' /proc/meminfo; }
++status(){ echo "$(date '+%F %H:%M:%S %Z') $* | resumes=$NRES kills=$NKILL segments=$n | gate pid $$" > $ST; }
++mem(){ awk '/MemAvailable/{print $2*1024}' $MEMINFO; }
+ nheavy(){ ps -eo rss,comm | awk '$2 ~ /^python/ && $1>=500000' | wc -l; }
+-mkdir -p $V2/logs $CKD
+-if [ ! -e $GO ]; then echo "REFUS : $GO absent (oui écrit de Philippe-Antoine requis pour un essai 4)" >&2; log "REFUS drapeau absent"; exit 1; fi
+-for f in $D/runs/ctl.npz $D/runs/ctl__seen.npz $V2/SHA256SUMS; do [ -e $f ] || { log "REFUS $f absent"; exit 1; }; done
+-( cd $V2 && sha256sum -c --quiet SHA256SUMS ) || { log "REFUS : SHA256SUMS ne correspond plus (code modifié depuis l'audit ?)"; exit 1; }
+-ls $D/runs/cm.npz $D/runs/cm__*.npz >/dev/null 2>&1 && { log "REFUS : sorties cm déjà présentes dans runs/ (pas d'écrasement)"; exit 1; }
+-NRES=0; NKILL=0; n=0
+-log "ARMÉ pid=$$ drapeau $GO présent ; plancher=$FLOOR pic=$PEAK cap=$RSSCAP"
++cmdline(){ tr '\0' ' ' 2>/dev/null < /proc/$1/cmdline; }
++cp1_busy(){ # PIDs cp1 vivants (cmdline CP1_RE, ou PID connu dont la cmdline contient le nom attendu) ; lecture /proc seulement
++ local d p c out="" e
++ for d in /proc/[0-9]*; do p=${d#/proc/}; [ "$p" = "$$" ] && continue
++ c=$(cmdline $p) || continue; [ -n "$c" ] || continue
++ printf '%s' "$c" | grep -Eq -- "$CP1_RE" && out="$out $p"
++ done
++ for e in $CP1_PIDS; do p=${e%%:*}; c=$(cmdline $p) || continue
++ case "$c" in *"${e#*:}"*) case " $out " in *" $p "*) ;; *) out="$out $p";; esac;; esac
++ done; echo $out; }
++cp1_status_terminal(){ local s; s=$(cut -d' ' -f4- $CP1/STATUS 2>/dev/null); case "$s" in FINI*|ÉCHEC*) return 0;; esac; echo "${s:-STATUS cp1 illisible}"; return 1; }
++queue_head(){ # = post_cm_diag.sh : premier job de ORDER sans DONE/ ni SKIP/ ; code 1 = ORDER absent/vide ; code 2 = ligne invalide
++ local line n=0; [ -s $QD/ORDER ] || return 1
++ while IFS= read -r line || [ -n "$line" ]; do
++ line=${line%$'\r'}; line="${line#"${line%%[![:space:]]*}"}"; line="${line%"${line##*[![:space:]]}"}"
++ [ -z "$line" ] && continue; [ "${line:0:1}" = "#" ] && continue; n=$((n+1))
++ [[ $line =~ ^[A-Za-z0-9_][A-Za-z0-9_.-]*$ ]] || { echo "$line"; return 2; }
++ [ -e "$QD/DONE/$line" ] || [ -e "$QD/SKIP/$line" ] || { echo "$line"; return 0; }
++ done < $QD/ORDER
++ [ $n -gt 0 ] || return 1; echo ""; return 0; }
++queue_wait_msg(){
++ local h r; h=$(queue_head); r=$?
++ case $r in 1) echo "ORDER absent ou vide ($QD/ORDER) : attente de la décision de Philippe-Antoine"; return;;
++ 2) echo "ORDER invalide (ligne « $h »)"; return;; esac
++ [ "$h" = "$JOB" ] && return; [ -z "$h" ] && { echo "$JOB absent de ORDER (ou tous faits)"; return; }; echo "pas mon tour : tête de ORDER = $h"; }
++queue_release(){ [ $QLOCK_HELD = 1 ] && { flock -u 9; exec 9>&-; QLOCK_HELD=0; log "file : queue.lock relâché"; }; return 0; }
++trap queue_release EXIT
++ready(){ # "" si toutes les conditions (hors file) sont remplies, sinon le motif
++ local b s m nh
++ [ -e "$GO" ] || { echo "DRAPEAU_RETIRÉ"; return; }
++ b=$(cp1_busy); [ -n "$b" ] && { echo "M8cp1 vivant (PIDs$( for p in $b; do printf ' %s' $p; done))"; return; }
++ s=$(cp1_status_terminal) || { echo "STATUS M8cp1 non terminal : $s"; return; }
++ m=$(mem); nh=$(nheavy); { [ "$m" -ge $NEED ] && [ $nh -lt 4 ]; } || { echo "RAM MemAvailable=$m < $NEED (= plancher $FLOOR + cap $RSSCAP) ou lourds=$nh >= 4"; return; }
++}
++wait_turn(){ # revient avec toutes les conditions remplies ET queue.lock tenu (fd 9)
++ local w
++ while :; do
++ w=$(ready); [ "$w" = DRAPEAU_RETIRÉ ] && { log "drapeau retiré -> arrêt"; status "ARRÊT drapeau retiré"; exit 1; }
++ [ -n "$w" ] && { status "ATTENTE $w"; sleep $POLL_S; continue; }
++ if [ $QLOCK_HELD = 0 ]; then
++ w=$(queue_wait_msg); [ -n "$w" ] && { status "ATTENTE file : $w"; sleep $POLL_S; continue; }
++ exec 9>>$QD/queue.lock
++ if ! flock -x -w $POLL_S 9; then exec 9>&-; status "ATTENTE file : queue.lock tenu par un autre job"; continue; fi
++ w=$(queue_wait_msg); if [ -n "$w" ]; then flock -u 9; exec 9>&-; status "ATTENTE file : $w"; sleep $POLL_S; continue; fi
++ QLOCK_HELD=1; log "file : tour obtenu, queue.lock tenu, ORDER=$(grep -v '^ *#' $QD/ORDER | tr -s ' \n' ' ')"
++ fi
++ w=$(ready); [ -z "$w" ] && return 0 # re-vérifié SOUS verrou
++ [ "$w" = DRAPEAU_RETIRÉ ] && { log "drapeau retiré -> arrêt"; status "ARRÊT drapeau retiré"; exit 1; }
++ status "ATTENTE (verrou tenu) $w"; sleep $POLL_S
++ done; }
++log "ARMÉ pid=$$ sha256=$(sha256sum $0 | cut -c1-64) ; drapeau $GO présent ; plancher=$FLOOR cap=$RSSCAP need=$NEED hard_floor=$HARD_FLOOR (désactivé)"
++( cd $V2 && sha256sum -c --quiet SHA256SUMS ) >> $GL 2>&1 || { log "REFUS : SHA256SUMS ne correspond plus (code modifié depuis l'audit ?)"; status "REFUS SHA256SUMS"; exit 1; }
++for f in train_m8v1b_v2.py run_guarded_v2.py ../code/verdict_M8v1b.py ../code/countmin.py; do
++ grep -Eq "^[0-9a-f]{64} $f\$" $V2/SHA256SUMS || { log "REFUS : $f absent de SHA256SUMS (P6)"; status "REFUS SHA256SUMS incomplet ($f)"; exit 1; }; done
++for f in $D/runs/ctl.npz $D/runs/ctl__seen.npz; do [ -e $f ] || { log "REFUS $f absent"; status "REFUS $f absent"; exit 1; }; done
++for f in $D/runs/cm.npz $D/runs/cm__*.npz; do [ -e "$f" ] && { log "REFUS : sortie cm déjà présente ($f)"; status "REFUS sorties cm présentes"; exit 1; }; done
++if [ -e $QD/DONE/$JOB ] || [ -e $QD/SKIP/$JOB ]; then log "RIEN À FAIRE : $QD/DONE|SKIP/$JOB existe"; status "RIEN À FAIRE (DONE/SKIP $JOB)"; exit 0; fi
+ while :; do
+- [ -e $GO ] || { log "drapeau retiré -> arrêt"; status "ARRÊT drapeau retiré"; exit 1; }
+- m=$(mem); nh=$(nheavy); need=$(( FLOOR + PEAK )); [ $need -lt $MINL ] && need=$MINL
+- if [ $nh -ge 4 ] || [ $m -lt $need ]; then status "ATTENTE RAM MemAvailable=$m need=$need lourds=$nh"; sleep 60; continue; fi
+- n=$((n+1)); R="--resume auto --allow-fallback" # sans ckpt dans $CKD : départ à zéro (journalisé) ; sinon reprise du dernier valide
+- log "LANCE cm essai 4 segment $n MemAvailable=$m need=$need lourds=$nh $R"; status "EN COURS segment $n"
++ wait_turn
++ ( cd $V2 && sha256sum -c --quiet SHA256SUMS ) >> $GL 2>&1 || { log "REFUS : SHA256SUMS ne correspond plus"; status "REFUS SHA256SUMS"; exit 1; }
++ ls $CKD/ckpt_cm_*.npz.sha256 >/dev/null 2>&1 && : > $MARK
++ if [ -e $MARK ]; then R="--resume auto --allow-fallback"; else R="--resume auto --allow-fallback --fresh"; fi
++ n=$((n+1)); log "LANCE cm essai 4 segment $n MemAvailable=$(mem) need=$NEED $R"; status "EN COURS segment $n"
+ $PY $V2/run_guarded_v2.py --name m8v1b_cm_try4 --log $V2/logs/arm_cm_try4_seg$n.log --guard-log $V2/logs/guarded_v2.log \
+- --peak $PEAK --min-launch $MINL --floor $FLOOR --rss-cap $RSSCAP --grace $GRACE --mode checkpoint -- \
++ --peak $PEAK --min-launch $NEED --floor $FLOOR --rss-cap $RSSCAP --hard-floor $HARD_FLOOR --grace $GRACE --mode checkpoint -- \
+ $PY -u $V2/train_m8v1b_v2.py --arm cm --data $D/sample/v1b_sample.bin --outdir $D/runs --ckpt-dir $CKD \
+ --snn-tokens 600000 --am-tokens 1200000 --epochs 2 --maxpos 4000 --windows seen,fc2,fresh_en,fresh_fr,test20k,test_v3,queries $R
+ e=$?; log "segment $n fin code $e"
++ ls $CKD/ckpt_cm_*.npz.sha256 >/dev/null 2>&1 && : > $MARK
+ case $e in
+- 0) status "VERDICT en cours"; nice -n 10 $PY -u $D/code/verdict_M8v1b.py > $V2/logs/verdict_M8v1b_try4_run.log 2>&1; v=$?
+- log "verdict code $v"; status "FINI verdict code $v"; exit $v ;;
+- 3) n=$((n-1)); sleep 60 ;; # porte fermée au dernier moment : rien lancé
+- 75) NRES=$((NRES+1)); [ $NRES -gt $RESUME_MAX ] && { status "ÉCHEC trop de reprises"; log "ÉCHEC reprises > $RESUME_MAX"; exit 1; }; sleep 120 ;;
+- 137|138|143) NKILL=$((NKILL+1)); [ $NKILL -gt $KILL_MAX ] && { status "ÉCHEC trop de kills"; log "ÉCHEC kills > $KILL_MAX"; exit 1; }; sleep 120 ;;
+- *) status "ÉCHEC code $e (65/68 = ckpt refusé) — décision humaine"; log "ÉCHEC code $e"; exit 1 ;;
++ 0) ( cd $V2 && sha256sum -c --quiet SHA256SUMS ) >> $GL 2>&1 || { log "REFUS verdict : SHA256SUMS ne correspond plus"; status "ENTRAÎNEMENT FINI — verdict NON exécuté (sha)"; exit 1; }
++ status "VERDICT en cours"; nice -n 10 $PY -u $D/code/verdict_M8v1b.py > $V2/logs/verdict_M8v1b_try4_run.log 2>&1; v=$?
++ log "verdict code $v"; : > $QD/DONE/$JOB; log "file : DONE/$JOB écrit"; status "FINI verdict code $v ; DONE/$JOB écrit"; exit $v ;;
++ 3) n=$((n-1)); sleep $POLL_S ;;
++ 75) NRES=$((NRES+1)); [ $NRES -gt $RESUME_MAX ] && { status "ÉCHEC trop de reprises (pas de DONE)"; log "ÉCHEC reprises > $RESUME_MAX"; exit 1; }; sleep $POLL_S ;;
++ 137|138|143) NKILL=$((NKILL+1)); [ $NKILL -gt $KILL_MAX ] && { status "ÉCHEC trop de kills (pas de DONE)"; log "ÉCHEC kills > $KILL_MAX"; exit 1; }; sleep $POLL_S ;;
++ *) status "ÉCHEC code $e (65/68 ckpt refusé, 66 dossier ckpt vide, 73 verrou, 74 sauvegarde) — pas de DONE, décision humaine"; log "ÉCHEC code $e"; exit 1 ;;
+ esac
+ done
diff --git a/results/hashing/m8_v1b/v2_resume/run_guarded.sh.orig_ref b/results/hashing/m8_v1b/v2_resume/run_guarded.sh.orig_ref
new file mode 100644
index 0000000000000000000000000000000000000000..56eb83ed09346365ad2e0ebdfcd8a71d03d5e74b
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/run_guarded.sh.orig_ref
@@ -0,0 +1,23 @@
+#!/bin/bash
+# SPIRA Hashing — M8 v1b : lanceur garde pour UN job lourd ponctuel (recompte, smoke).
+# Usage : run_guarded.sh NAME PEAK_BYTES LOG -- CMD... Porte : MemAvailable >= 4.4 GiB + PEAK et >= 5.2 GB, lourds (python RSS>=500 Mo) < 4.
+# Pas d'attente : si la porte est fermée -> sortie 3 (rien lancé). Chien de garde 4.4 GiB : tue SEULEMENT le groupe de ce job.
+export TZ=America/Toronto OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONHASHSEED=0 TMPDIR=/workspace/spira_shared/hashing_gen/m8_v1b/tmp
+D=/workspace/spira_shared/hashing_gen/m8_v1b; NAME=$1; PEAK=$2; LOG=$3; shift 4; R=$D/logs/guarded.log
+FLOOR=4724464025 # 4.4 GiB
+log(){ echo "$(date '+%F %H:%M:%S %Z') [$NAME] $*" >> $R; }
+mem(){ awk '/MemAvailable/{print $2*1024}' /proc/meminfo; }
+heavy(){ ps -eo pid,rss,comm | awk '$3 ~ /^python/ && $2>=500000 {print $1}' | tr '\n' ' '; }
+m=$(mem); h=$(heavy); nh=$(echo $h | wc -w); need=$(( FLOOR + PEAK )); [ $need -lt 5200000000 ] && need=5200000000
+if [ $m -lt $need ] || [ $nh -ge 4 ]; then log "GATE CLOSED MemAvailable=${m}B need=${need}B heavy=$nh [$h]"; echo "GATE CLOSED" >&2; exit 3; fi
+log "GATE OK MemAvailable=${m}B need=${need}B heavy=$nh [$h] cmd=$*"
+setsid nice -n 10 "$@" > $LOG 2>&1 & P=$!; log "START pid=$P"
+minm=$m; maxr=0
+while kill -0 $P 2>/dev/null; do
+ m=$(mem); [ $m -lt $minm ] && minm=$m
+ r=$(ps -o rss= -g $P 2>/dev/null | awk '{s+=$1}END{print s+0}'); [ $r -gt $maxr ] && maxr=$r
+ echo "$(date +%s) $m $r" >> $LOG.mem
+ if [ $m -lt $FLOOR ]; then log "WATCHDOG MemAvailable=${m}B < 4.4GiB -> kill -TERM -$P (notre groupe seulement)"; kill -TERM -$P; sleep 5; kill -KILL -$P 2>/dev/null; fi
+ sleep 2
+done
+wait $P; e=$?; log "EXIT $e min_MemAvailable=${minm}B max_groupRSS=${maxr}kB"; exit $e
diff --git a/results/hashing/m8_v1b/v2_resume/run_guarded_v2.py b/results/hashing/m8_v1b/v2_resume/run_guarded_v2.py
new file mode 100644
index 0000000000000000000000000000000000000000..4c7427fdcff6133dba2269df8a7b409401baee19
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/run_guarded_v2.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python3
+"""SPIRA Hashing — chien de garde v2 pour UN job lourd (remplace code/run_guarded.sh pour le bras cm reprenable ; v1 non modifié).
+Usage : run_guarded_v2.py --name N --log LOG [options] -- CMD...
+ Porte de lancement (MemAvailable RÉEL) : >= floor + peak ET >= min-launch (5,2 Go), lourds (python RSS >= 500 Mo) < 4, sinon sortie 3.
+ Le job tourne dans SON groupe (setsid) à nice 10 ; le garde ne signale QUE ce groupe (jamais d'autre PID).
+ Toutes les --interval s :
+ - RSS du groupe (somme VmRSS des PID dont pgrp == notre groupe) > --rss-cap (3,5 Go) -> arrêt propre (SIGUSR1 : le job finit le
+ tick, checkpoint, sortie 75) ; s'il n'est pas sorti après --grace s -> SIGKILL du groupe.
+ - MemAvailable < --floor (défaut 4 000 000 000 o = règle des 4 Go de Philippe-Antoine) :
+ --mode checkpoint (DÉFAUT) : arrêt propre comme ci-dessus (perte <= 30 min) ;
+ --mode pause (OPTION, décision utilisateur) : SIGSTOP du groupe ; SIGCONT quand MemAvailable >= floor + --pause-margin (0,5 Go)
+ pendant --pause-hold s (60) ; si en pause > --pause-max s (1200) -> SIGCONT + arrêt propre (checkpoint, 75).
+ ATTENTION : la pause ne libère PAS la RSS du job ; elle stoppe seulement sa croissance. Elle ne restaure pas la marge de 4 Go.
+ - --hard-floor (défaut 0 = désactivé) : si > 0 et MemAvailable < hard-floor -> SIGKILL immédiat du groupe (aucune valeur imposée ici).
+ TEST SEULEMENT : env SPIRA_WD_FAKE_MEMAVAIL_FILE=fichier contenant un entier (octets) remplace MemAvailable POUR LA SURVEILLANCE
+ (jamais pour la porte de lancement) ; signalé en tête de journal.
+Code de sortie = celui du job (0, 75, 65, 68...), 137 si tué par le garde, 3 si porte fermée."""
+import os, sys, time, signal, subprocess, argparse, json
+ap = argparse.ArgumentParser()
+ap.add_argument("--name", required=True); ap.add_argument("--log", required=True); ap.add_argument("--guard-log", default=None)
+ap.add_argument("--peak", type=int, default=2_500_000_000); ap.add_argument("--min-launch", type=int, default=5_200_000_000)
+ap.add_argument("--floor", type=int, default=4_000_000_000); ap.add_argument("--rss-cap", type=int, default=3_500_000_000)
+ap.add_argument("--grace", type=float, default=180.0); ap.add_argument("--interval", type=float, default=2.0)
+ap.add_argument("--mode", choices=["checkpoint", "pause"], default="checkpoint")
+ap.add_argument("--pause-margin", type=int, default=500_000_000); ap.add_argument("--pause-hold", type=float, default=60.0)
+ap.add_argument("--pause-max", type=float, default=1200.0); ap.add_argument("--hard-floor", type=int, default=0)
+ap.add_argument("--max-heavy", type=int, default=4); ap.add_argument("--nice", type=int, default=10)
+ap.add_argument("cmd", nargs=argparse.REMAINDER)
+a = ap.parse_args(); cmd = a.cmd[1:] if a.cmd[:1] == ["--"] else a.cmd
+if not cmd: ap.error("commande manquante après --")
+GL = a.guard_log or os.path.join(os.path.dirname(os.path.abspath(a.log)), "guarded_v2.log")
+FAKE = os.environ.get("SPIRA_WD_FAKE_MEMAVAIL_FILE")
+def log(s):
+ with open(GL, "a") as f: f.write(f"{time.strftime('%F %H:%M:%S %Z')} [{a.name}] {s}\n")
+def real_mem():
+ for l in open("/proc/meminfo"):
+ if l.startswith("MemAvailable:"): return int(l.split()[1]) * 1024
+def watch_mem():
+ if FAKE:
+ try: return int(open(FAKE).read().strip())
+ except Exception: return real_mem()
+ return real_mem()
+def heavy():
+ r = []
+ for p in os.listdir("/proc"):
+ if not p.isdigit(): continue
+ try:
+ comm = open(f"/proc/{p}/comm").read().strip();
+ if not comm.startswith("python"): continue
+ for l in open(f"/proc/{p}/status"):
+ if l.startswith("VmRSS:") and int(l.split()[1]) >= 500_000: r.append(int(p))
+ except Exception: pass
+ return r
+def group_rss(pg):
+ """somme VmRSS (octets) des processus dont le pgrp == pg ; lit /proc/PID/stat (champ 5 après le comm entre parenthèses)."""
+ tot = 0; n = 0
+ for p in os.listdir("/proc"):
+ if not p.isdigit(): continue
+ try:
+ st = open(f"/proc/{p}/stat").read(); f = st[st.rindex(")") + 2:].split()
+ if int(f[2]) != pg: continue
+ for l in open(f"/proc/{p}/status"):
+ if l.startswith("VmRSS:"): tot += int(l.split()[1]) * 1024; n += 1; break
+ except Exception: pass
+ return tot, n
+def pstate(pid):
+ try: st = open(f"/proc/{pid}/stat").read(); return st[st.rindex(")") + 2]
+ except Exception: return "?"
+m = real_mem(); hv = heavy(); need = max(a.floor + a.peak, a.min_launch)
+if FAKE: log(f"!!! MODE TEST : MemAvailable de surveillance lu dans {FAKE} (porte de lancement = MemAvailable réel)")
+if m < need or len(hv) >= a.max_heavy:
+ log(f"GATE CLOSED MemAvailable={m}B need={need}B heavy={len(hv)} {hv}"); print("GATE CLOSED", file=sys.stderr); sys.exit(3)
+cfgs = {k: getattr(a, k) for k in ("floor", "rss_cap", "grace", "interval", "mode", "pause_margin", "pause_hold", "pause_max", "hard_floor")}
+log(f"GATE OK MemAvailable={m}B need={need}B heavy={len(hv)} cfg={json.dumps(cfgs)} cmd={' '.join(cmd)}")
+out = open(a.log, "wb")
+P = subprocess.Popen(["nice", "-n", str(a.nice)] + cmd, stdout=out, stderr=subprocess.STDOUT, start_new_session=True)
+PG = P.pid; log(f"START pid=pgid={PG}") # start_new_session => pgid == pid du leader ; tant qu'il n'est pas récolté, le pgid ne peut être réutilisé
+memf = open(a.log + ".mem", "a")
+def sig_group(s, why):
+ if P.poll() is None: # jamais de signal après récolte (pas de risque de PID/PGID réutilisé)
+ log(f"SIGNAL {signal.Signals(s).name} -> groupe {PG} ({why})"); os.killpg(PG, s)
+stop_sent = None; paused_at = None; above_since = None; killed = False; minm = m; maxr = 0; reason = None; npause = 0
+try:
+ while P.poll() is None:
+ now = time.monotonic(); mm = watch_mem(); r, nproc = group_rss(PG); minm = min(minm, mm); maxr = max(maxr, r)
+ state = "PAUSED" if paused_at is not None else ("STOPPING" if stop_sent is not None else "RUN")
+ memf.write(f"{int(time.time())} {mm} {r // 1024} {state} {pstate(PG)}\n"); memf.flush()
+ if a.hard_floor and mm < a.hard_floor:
+ reason = f"hard-floor {mm}<{a.hard_floor}"
+ if paused_at is not None: sig_group(signal.SIGCONT, "avant kill")
+ sig_group(signal.SIGKILL, reason); killed = True; break
+ if stop_sent is not None:
+ if now - stop_sent > a.grace:
+ reason = (reason or "") + f" ; pas sorti après {a.grace:.0f}s"; sig_group(signal.SIGKILL, reason); killed = True; break
+ elif paused_at is not None:
+ if mm >= a.floor + a.pause_margin:
+ above_since = above_since or now
+ if now - above_since >= a.pause_hold:
+ sig_group(signal.SIGCONT, f"MemAvailable={mm} >= floor+margin depuis {now-above_since:.0f}s (pause {now-paused_at:.0f}s)")
+ paused_at = None; above_since = None
+ else: above_since = None
+ if paused_at is not None and now - paused_at > a.pause_max:
+ reason = f"pause > {a.pause_max:.0f}s"; sig_group(signal.SIGCONT, reason); sig_group(signal.SIGUSR1, reason + " -> checkpoint")
+ paused_at = None; stop_sent = now
+ else:
+ if r > a.rss_cap:
+ reason = f"RSS groupe {r}B > cap {a.rss_cap}B ({nproc} proc)"; sig_group(signal.SIGUSR1, reason + " -> arrêt propre"); stop_sent = now
+ elif mm < a.floor:
+ if a.mode == "pause":
+ npause += 1; reason = f"MemAvailable {mm}B < floor {a.floor}B"; sig_group(signal.SIGSTOP, reason + " -> PAUSE"); paused_at = now; above_since = None
+ else:
+ reason = f"MemAvailable {mm}B < floor {a.floor}B"; sig_group(signal.SIGUSR1, reason + " -> arrêt propre (checkpoint)"); stop_sent = now
+ time.sleep(a.interval)
+finally:
+ if P.poll() is None and paused_at is not None: sig_group(signal.SIGCONT, "sortie du garde")
+e = P.wait(); e = 137 if killed and e < 0 else (128 - e if e < 0 else e)
+log(f"EXIT {e} reason={reason} pauses={npause} min_MemAvailable={minm}B max_groupRSS={maxr}B")
+sys.exit(e)
diff --git a/results/hashing/m8_v1b/v2_resume/tests/disk_bench.py b/results/hashing/m8_v1b/v2_resume/tests/disk_bench.py
new file mode 100644
index 0000000000000000000000000000000000000000..8327d813ba8db015cb92d4d835d2307180018e6c
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/tests/disk_bench.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+"""Banc disque : écrit N octets (taille estimée du ckpt cm production) par blocs de 16 Mio (RSS ~ 20 Mo), fsync, rename, relit pour sha256,
+puis supprime le fichier. Estime le temps de sauvegarde d'un ckpt production (np.savez écrit aussi par blocs de 16 Mio). Usage : disk_bench.py DIR N"""
+import os, sys, time, hashlib
+d, n = sys.argv[1], int(sys.argv[2]); p = f"{d}/bench.tmp"; buf = os.urandom(16 << 20); t0 = time.perf_counter()
+with open(p, "wb") as f:
+ w = 0
+ while w < n: k = min(len(buf), n - w); f.write(buf[:k]); w += k
+ f.flush(); t1 = time.perf_counter(); os.fsync(f.fileno())
+t2 = time.perf_counter(); os.replace(p, p + ".done"); h = hashlib.sha256()
+with open(p + ".done", "rb") as f:
+ while True:
+ b = f.read(8 << 20)
+ if not b: break
+ h.update(b)
+t3 = time.perf_counter(); os.remove(p + ".done")
+print(f"BENCH bytes={n} write_s={t1-t0:.2f} fsync_s={t2-t1:.2f} sha_readback_s={t3-t2:.2f} total_s={t3-t0:.2f}")
diff --git a/results/hashing/m8_v1b/v2_resume/tests/orig_loop_ref.py b/results/hashing/m8_v1b/v2_resume/tests/orig_loop_ref.py
new file mode 100644
index 0000000000000000000000000000000000000000..a78bdae9f51262cb5c19c483915df110bd90a172
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/tests/orig_loop_ref.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+"""Référence : boucle ORIGINALE (SpikingCore.train_pass non modifié, appelé comme dans code/train_m8v1b.py) sur la même config tiny ;
+compare les poids finaux octet pour octet avec le cm.npz produit par train_m8v1b_v2.py. Usage : orig_loop_ref.py DATA V2_OUTDIR"""
+import sys, os, json, hashlib, dataclasses
+sys.path.insert(0, "/workspace/spira_shared/hashing_gen/m8_v1b/code")
+import numpy as np
+from countmin import CMSPIRA, SPIRAConfig
+data = open(sys.argv[1], "rb").read(); od = sys.argv[2]
+cfg = SPIRAConfig(vocab_size=16384, d_in=1024, snn_tokens=2000, am_tokens=4000, epochs=2)
+cfg = dataclasses.replace(cfg, vocab_size=1024, am_size=65536)
+m = CMSPIRA.build_cm(data, cfg, log=lambda *x: None); m.prepare()
+hist = []
+for ep in range(cfg.epochs):
+ n = len(m._neurons)
+ res = m.core.train_pass(m._neurons[:n], m._cols[1:n + 1], log_every=10_000, log_fn=None, record_raster_from=None); res.pop("raster", None); hist.append(res)
+mm = m.am.m; ctx = m._am_ctx; m.am.write_stream(ctx, m._ids_train[mm:mm + len(ctx)].astype(np.uint64))
+z = np.load(f"{od}/cm.npz", allow_pickle=False)
+S = lambda x: hashlib.sha256(np.ascontiguousarray(x).tobytes()).hexdigest()
+out = {"W_rec": S(m.core.W_rec) == S(z["W_rec"]), "W_out": S(m.core.W_out) == S(z["W_out"]), "W_out_G": S(m.core.W_outG) == S(z["W_out_G"]),
+ "W_rec_sha": S(m.core.W_rec)[:16], "W_out_sha": S(m.core.W_out)[:16], "W_outG_sha": S(m.core.W_outG)[:16],
+ "acc": [h["accuracy"] for h in hist], "beta": [h["beta"] for h in hist], "acc_fast": [h["accuracy_fast_only"] for h in hist],
+ "acc_ema_final": [h["acc_ema_final"] for h in hist]}
+cs = json.loads(str(z["core_state"])); out["core_state_beta_equal"] = cs.get("beta") == m.core.beta
+print("ORIGREF " + json.dumps(out)); sys.exit(0 if out["W_rec"] and out["W_out"] and out["W_out_G"] and out["core_state_beta_equal"] else 1)
diff --git a/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/ckpt_v2_cm/ckpt_cm_000002.npz.sha256 b/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/ckpt_v2_cm/ckpt_cm_000002.npz.sha256
new file mode 100644
index 0000000000000000000000000000000000000000..c0f89bb6982a296ffd899633fbd3c5753f9526e9
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/ckpt_v2_cm/ckpt_cm_000002.npz.sha256
@@ -0,0 +1 @@
+c3f34a3ac9f78ec4e82b78413b01393b2ec3442aeb03192805b4ada5e939e823 ckpt_cm_000002.npz
diff --git a/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/ckpt_v2_cm/ckpt_cm_000003.npz.sha256 b/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/ckpt_v2_cm/ckpt_cm_000003.npz.sha256
new file mode 100644
index 0000000000000000000000000000000000000000..36571258eee497ebf8318e1ca98f0334638dbfcc
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/ckpt_v2_cm/ckpt_cm_000003.npz.sha256
@@ -0,0 +1 @@
+e5fe8d8da99fe8db65fddbd1ac7afca58e34ca9febb3b55f778fa0c0272d59c5 ckpt_cm_000003.npz
diff --git a/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/ckpt_v2_cm/notes.txt b/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/ckpt_v2_cm/notes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ed42439626b0ab5fa899cb67d36160b7fb731121
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/ckpt_v2_cm/notes.txt
@@ -0,0 +1 @@
+étranger
\ No newline at end of file
diff --git a/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/results.jsonl b/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/results.jsonl
new file mode 100644
index 0000000000000000000000000000000000000000..549cc07ff1eb3486bb198840dcac41a3782bbb46
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/results.jsonl
@@ -0,0 +1,2 @@
+{"arm": "cm", "window": "seen", "snn_tokens": 2000, "am_tokens": 4000, "epochs": 2, "ticks_per_epoch": [2000, 2000], "n": 200, "fused_invocab_pct": 100.0, "fused_all_pct": 98.5, "snn_invocab_pct": 80.769, "cal": {"scale": 1.1398528509655237, "sigma_fast": 0.07079241770386993, "sigma_slow": 0.06210662862658501}, "data_sha256": "99e1b7ac41855d5de60e36f85a5857d36bf387bfbab7dc6ab6c8113ee96e60f2", "read": {"n_patches_train": 127227, "n_snn": 2000, "n_am": 4000, "snn_bytes_read": 8930, "am_bytes_read": 17499, "data_bytes": 600000, "ept_fit_bytes": 600000, "ept_calib_bytes": [2000000, 600000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.017, 0.0775], "ticks_per_sec": [283.43161229530614, 293.7617974096897], "eval_s": 1.1, "peak_rss_mb": 161.6, "ckpt_sha256": "b2a089c470e85a0ad6a6c0d94896de1b543834dfac02190f7f796f78768218df", "wall_s": 19.3}
+{"arm": "cm", "window": "fresh_en", "snn_tokens": 2000, "am_tokens": 4000, "epochs": 2, "ticks_per_epoch": [2000, 2000], "n": 200, "fused_invocab_pct": 0.0, "fused_all_pct": 0.0, "snn_invocab_pct": 0.0, "cal": {"scale": 1.1398528509655237, "sigma_fast": 0.07079241770386993, "sigma_slow": 0.06210662862658501}, "data_sha256": "99e1b7ac41855d5de60e36f85a5857d36bf387bfbab7dc6ab6c8113ee96e60f2", "read": {"n_patches_train": 127227, "n_snn": 2000, "n_am": 4000, "snn_bytes_read": 8930, "am_bytes_read": 17499, "data_bytes": 600000, "ept_fit_bytes": 600000, "ept_calib_bytes": [2000000, 600000], "fusion_calib_bytes": 60000, "whole_sample_used_for": "segmentation, vocabulaire top-V, registre, co-occurrences PPMI des neurones CM"}, "n_state": 6656, "train_acc": [0.017, 0.0775], "ticks_per_sec": [283.43161229530614, 293.7617974096897], "eval_s": 0.7, "peak_rss_mb": 161.6, "ckpt_sha256": "b2a089c470e85a0ad6a6c0d94896de1b543834dfac02190f7f796f78768218df", "wall_s": 20.0}
diff --git a/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/rss_cm.tsv b/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/rss_cm.tsv
new file mode 100644
index 0000000000000000000000000000000000000000..8fdd137fc1ebd299d768a082f1f1f5a6b2c0a53c
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/tests/out0227/T15_tmp/rss_cm.tsv
@@ -0,0 +1,3 @@
+1792910787 0.0 35780 load 0
+1792910791 0.0 35704 load 0
+1792910801 10.0 109596 snn_ep2 0
diff --git a/results/hashing/m8_v1b/v2_resume/tests/out0227/T16_empty/ckpt_v2_cm/ckpt_cm_000001.npz.sha256 b/results/hashing/m8_v1b/v2_resume/tests/out0227/T16_empty/ckpt_v2_cm/ckpt_cm_000001.npz.sha256
new file mode 100644
index 0000000000000000000000000000000000000000..3b0d3416c8288059c5f40096ac5ed4ea58c4734b
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/tests/out0227/T16_empty/ckpt_v2_cm/ckpt_cm_000001.npz.sha256
@@ -0,0 +1 @@
+248acc719143e63edf0bb4619724592ee5b4314db8120cbc56b55c9d7a9d072c ckpt_cm_000001.npz
diff --git a/results/hashing/m8_v1b/v2_resume/tests/out0227/T16_empty/ckpt_v2_cm/ckpt_cm_000002.npz.sha256 b/results/hashing/m8_v1b/v2_resume/tests/out0227/T16_empty/ckpt_v2_cm/ckpt_cm_000002.npz.sha256
new file mode 100644
index 0000000000000000000000000000000000000000..6b15a9bc119573b13615331d265e03bda22d74b4
--- /dev/null
+++ b/results/hashing/m8_v1b/v2_resume/tests/out0227/T16_empty/ckpt_v2_cm/ckpt_cm_000002.npz.sha256
@@ -0,0 +1 @@
+fb0fcbe7dbc7a623a9d4094e44f790caa6e7fb157e37101e94f7605f35f4c5ec ckpt_cm_000002.npz