thefinalboss commited on
Commit
1f68faa
·
verified ·
1 Parent(s): 1855527

results/hashing: SPIRA Hashing scripts, reports, artefacts (final push) (part 6)

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. results/hashing/covb_v3_eval/v42/verdict_v42.py +76 -0
  2. results/hashing/covb_v3_eval/verdict_covb_v42.py +61 -0
  3. results/hashing/dg_need_r1/DG_NEED.diff +11 -0
  4. results/hashing/dg_need_r1/DG_NEED.md +34 -0
  5. results/hashing/dg_need_r1/SHA256SUMS +4 -0
  6. results/hashing/dg_need_r1/run_C_B.copy_r3.sh +105 -0
  7. results/hashing/dg_need_r1/run_C_B.dgneed_proposed.sh +105 -0
  8. results/hashing/gap_vs_size/REPORT.md +27 -0
  9. results/hashing/gap_vs_size/SHA256SUMS +3 -0
  10. results/hashing/gap_vs_size/gap_vs_size.py +42 -0
  11. results/hashing/gap_vs_size/results.json +175 -0
  12. results/hashing/gen_copy_recount/code/copy_recount.py +184 -0
  13. results/hashing/gen_copy_recount/code/run_wrapped.py +11 -0
  14. results/hashing/gen_copy_recount/relay_entry.md +40 -0
  15. results/hashing/gen_kit_check_r1/REPORT.md +33 -0
  16. results/hashing/gen_kit_check_r1/SHA256SUMS +4 -0
  17. results/hashing/gen_kit_check_r1/SHA256SUMS_v3 +7 -0
  18. results/hashing/gen_kit_check_r1/SHA256SUMS_v3b_20261031 +7 -0
  19. results/hashing/gen_kit_check_r1/gen_kit_check_result.json +200 -0
  20. results/hashing/gen_kit_check_r1/gen_kit_check_v2.py +32 -0
  21. results/hashing/gen_kit_check_r1/gen_kit_check_v3.py +88 -0
  22. results/hashing/gen_kit_check_r1/gen_kit_check_v3_result.json +277 -0
  23. results/hashing/gen_kit_check_r1/gen_kit_check_v3b.py +88 -0
  24. results/hashing/gen_kit_check_r1/relay_entry_debut.md +4 -0
  25. results/hashing/gen_kit_check_r1/relay_entry_v3_debut.md +4 -0
  26. results/hashing/gen_kit_check_r1/relay_entry_v3_fin.md +5 -0
  27. results/hashing/go_package_missing_r1/MISSING_DECISIONS.md +81 -0
  28. results/hashing/go_package_missing_r1/SHA256SUMS +1 -0
  29. results/hashing/hf_pushed.txt +4 -0
  30. results/hashing/leak16_baseline_recount/SHA256SUMS +6 -0
  31. results/hashing/leak16_baseline_recount/hf_ready/README.md +24 -0
  32. results/hashing/leak16_baseline_recount/hf_ready/SHA256SUMS +4 -0
  33. results/hashing/leak16_baseline_recount/hf_ready/recount_leak16.py +58 -0
  34. results/hashing/leak16_baseline_recount/hf_ready/recount_leak16_stream.py +59 -0
  35. results/hashing/leak16_baseline_recount/hf_ready/results_counts.json +297 -0
  36. results/hashing/leak16_baseline_recount/leakcheck_hf.py +24 -0
  37. results/hashing/leak16_baseline_recount/recount_leak16.py +58 -0
  38. results/hashing/leak16_baseline_recount/recount_leak16_stream.py +59 -0
  39. results/hashing/leak16_baseline_recount/results.json +523 -0
  40. results/hashing/leak16_baseline_recount/results_stream.json +523 -0
  41. results/hashing/leak16_reconcile_r3/REPORT.md +27 -0
  42. results/hashing/leak16_reconcile_r3/SHA256SUMS +5 -0
  43. results/hashing/leak16_reconcile_r3/recount.py +35 -0
  44. results/hashing/leak16_reconcile_r3/recount_r3.json +90 -0
  45. results/hashing/leak16_reconcile_r3/ref_8w.json +45 -0
  46. results/hashing/leak16_reconcile_r3/selfcheck_r2.json +102 -0
  47. results/hashing/lever1/STATUS +2 -0
  48. results/hashing/lever1/manifest_broad_gutenberg_v1.json +126 -0
  49. results/hashing/lever1/verify_bg1.json +101 -0
  50. results/hashing/lever1/verify_v3.py +37 -0
results/hashing/covb_v3_eval/v42/verdict_v42.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Checker 24 oct. 09 h 3x (Toronto) — verdict de rétention v4.2 (correctif méthodologique ; verdict_v41.py CONSERVÉ tel quel, non modifié).
3
+ Problème v4.1 (signalé Hashing/Relay 09 h 27, confirmé par Checker) : tokenizers différents ⇒ les spans (tgt_start, tgt_len) IDENTIQUES entre bras ne
4
+ sont qu'un sous-ensemble biaisé (m8_v3 vs old_ref : 565/8000 fc2, 2 494/20 000 test20k, 2 895/20 000 test_v3) et les taux affichés étaient NON APPARIÉS
5
+ (fc2 : 11,50 → 14,45 non apparié, alors que sur les spans communs 5,66 → 0,71).
6
+ Méthode v4.2 (segmentation commune FIGÉE par fenêtre et par paire, en octets) :
7
+ - frontières de chaque bras = début/fin de ses patches cibles (tgt_start/tgt_len, contigus) ; frontières COMMUNES = intersection, restreinte à la
8
+ plage d'octets couverte par les deux bras ; unité = [c_k, c_{k+1}) ; chaque unité est pavée exactement par des patches entiers de chaque bras.
9
+ - unité réussie pour un bras ssi TOUS ses patches dans l'unité sont fused_hit (ou m9g_hit pour v2b) ; unité gardée ssi TOUS les patches des DEUX bras
10
+ y sont in-vocab (in-vocab pour les deux bras) ET aucun octet exclu par le masque propre (union des masques stricts des corpus des deux bras ;
11
+ patch exclu ssi E[s:s+l].any(), règle ctx64+span des masques).
12
+ - fichier de spans figé : verdicts_v42/spans/<BASE><suf>__<TAG>__<w>.npz (unit_start, unit_len) + sha256 enregistré dans le json.
13
+ - McNemar exact sur les unités appariées ; taux APPARIÉS (hits/unités) rapportés à côté ; bootstrap par blocs de 64 unités, 2 000 tirages, seed 777 (indicatif).
14
+ - Identité : si les deux bras ont la même segmentation (ex. old_ref fused vs old_ref v2b), unités = patches et discordants == v4.1 (testé).
15
+ Règle : RETENU ssi aucune perte significative (p<0,05) sur aucune fenêtre (fc2, fresh_en, fresh_fr, test20k, test_v3, queries) ET ≥ 1 gain significatif
16
+ sur une fenêtre fraîche propre (queries exclu des gains frais). seen jamais apparié (octets différents par corpus). neither_code / freshcode exclus.
17
+ Usage : verdict_v42.py TAG BASE [SUFFIX KEY] (ex. old_ref __v2b m9g_hit) → verdicts_v42/<TAG>__vs_<BASE><suf>.json/.md"""
18
+ import os, sys, json, math, hashlib, numpy as np
19
+ D = os.path.dirname(os.path.abspath(__file__)); H = os.environ.get("HITS", f"{D}/hits_v4"); OUTD = os.environ.get("OUTD", f"{D}/verdicts_v42")
20
+ FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"]; VW = FRESH + ["queries"]
21
+ tag, base = sys.argv[1], sys.argv[2]; suf = sys.argv[3] if len(sys.argv) > 3 else ""; kref = sys.argv[4] if len(sys.argv) > 4 else "fused_hit"
22
+ MASKS = {"corpus_v3": f"{D}/clean_masks/corpus_v3_full_0450.npz", "broad_local_v1": f"{D}/clean_masks/broad_gutenberg_v1_2134.npz",
23
+ "broad_gutenberg_v1": f"{D}/clean_masks/broad_gutenberg_v1_2134.npz", "corpus_diverse_v1": f"{D}/clean_masks/broad_gutenberg_v1_2134.npz"}
24
+ def corpus_of(t):
25
+ for l in open(f"{D}/jobs_v4.tsv"):
26
+ f = l.rstrip("\n").split("\t")
27
+ if len(f) >= 3 and f[0] == t: return f[2]
28
+ def binp(b, c):
29
+ 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)
30
+ def sha(*a): h = hashlib.sha256(); [h.update(np.ascontiguousarray(x).tobytes()) for x in a]; return h.hexdigest()
31
+ def units(A, B, E, ka, kb):
32
+ assert str(A["window_sha256"]) == str(B["window_sha256"]), "octets différents"
33
+ def arm(Z): s = Z["tgt_start"].astype(np.int64); l = Z["tgt_len"].astype(np.int64); assert np.all(s[1:] == s[:-1] + l[:-1]); return s, s + l
34
+ sa, ea = arm(A); sb, eb = arm(B); lo, hi = max(sa[0], sb[0]), min(ea[-1], eb[-1])
35
+ c = np.intersect1d(np.concatenate([sa, ea[-1:]]), np.concatenate([sb, eb[-1:]])); c = c[(c >= lo) & (c <= hi)]
36
+ us, ue = c[:-1], c[1:]
37
+ def agg(s, e, ok): # unité vraie ssi tous les patches du bras dans l'unité sont ok
38
+ m = (s >= c[0]) & (e <= c[-1]); k = np.searchsorted(c, s[m], side="right") - 1; u = np.ones(len(us), bool); np.logical_and.at(u, k, ok[m]); return u
39
+ iva, ivb = A["invocab"].astype(bool), B["invocab"].astype(bool)
40
+ ha = agg(sa, ea, A[ka].astype(bool) & iva); hb = agg(sb, eb, B[kb].astype(bool) & ivb)
41
+ keep = agg(sa, ea, iva) & agg(sb, eb, ivb)
42
+ ce = np.concatenate([[0], np.cumsum(E.astype(np.int64))]); clean = (ce[ue] - ce[us]) == 0 # E déjà dilaté (ctx64+span)
43
+ keep &= clean
44
+ return us[keep], (ue - us)[keep], ha[keep], hb[keep], {"n_units_all": int(len(us)), "n_units_kept": int(keep.sum()), "excluded_mask": int((~clean).sum()), "byte_range": [int(lo), int(hi)]}
45
+ def boot(x, y, blk=64, nb=2000, seed=777):
46
+ n = len(x) // blk
47
+ if n < 2: return None
48
+ d = y[:n * blk].reshape(n, blk).mean(1) - x[:n * blk].reshape(n, blk).mean(1); bs = d[np.random.default_rng(seed).integers(0, n, (nb, n))].mean(1)
49
+ return [100 * float(d.mean()), *(100 * np.percentile(bs, [2.5, 97.5])).tolist()]
50
+ ld = lambda t, w, s="": np.load(f"{H}/{t}__{w}{s}.npz")
51
+ mk = sorted({MASKS[c] for c in (corpus_of(tag), corpus_of(base)) if c in MASKS}); MZ = [np.load(m) for m in mk]
52
+ os.makedirs(f"{OUTD}/spans", exist_ok=True); R = {}
53
+ for w in VW:
54
+ A, B = ld(base, w, suf), ld(tag, w); E = np.zeros(int(B["window_bytes"]), bool)
55
+ for M in MZ: assert str(M[f"sha__bench_{w}"]) == str(B["window_sha256"]); E |= M[f"bench_{w}__excl"]
56
+ us, ul, x, y, info = units(A, B, E, kref, "fused_hit")
57
+ sp = f"{OUTD}/spans/{base}{suf}__{tag}__{w}.npz"; np.savez(sp, unit_start=us, unit_len=ul); sh = sha(us, ul)
58
+ ro, co = int((x & ~y).sum()), int((~x & y).sum()); p = binp(ro, co); n = len(x)
59
+ R[w] = {"units": n, **info, "spans_file": os.path.relpath(sp, D), "spans_sha256": sh, "ref_hits": int(x.sum()), "cand_hits": int(y.sum()),
60
+ "paired_rate_ref_pct": 100 * float(x.mean()) if n else None, "paired_rate_cand_pct": 100 * float(y.mean()) if n else None,
61
+ "ref_only": ro, "cand_only": co, "p_mcnemar_exact": p, "sig_gain": bool(p < 0.05 and co > ro), "sig_loss": bool(p < 0.05 and ro > co),
62
+ "boot_units64_delta_ci95_pct": boot(x, y)}
63
+ L = [w for w in VW if R[w]["sig_loss"]]; G = [w for w in FRESH if R[w]["sig_gain"]]
64
+ dec = "RETENU" if (not L and G) else "NON RETENU"
65
+ out = {"tag": tag, "base": base + suf, "base_key": kref, "method": "v4.2 segmentation commune figée (frontières communes, in-vocab deux bras, masque propre union)",
66
+ "masks": mk, "windows": R, "losses": L, "gains_fresh": G, "gains_queries": [w for w in ["queries"] if R[w]["sig_gain"]], "decision": dec,
67
+ "script_sha256": hashlib.sha256(open(os.path.abspath(__file__), "rb").read()).hexdigest()}
68
+ f = lambda v: "—" if v is None else f"{v:.2f}"
69
+ rows = [f"# Verdict v4.2 (apparié, segmentation commune figée) — {tag} contre {base}{suf} ({kref})", "", f"**{dec}** (pertes : {', '.join(L) or 'aucune'} ; gains frais : {', '.join(G) or 'aucun'})", "",
70
+ "| fenêtre | unités appariées (gardées/toutes) | taux APPARIÉ réf % | taux APPARIÉ cand % | ref_only | cand_only | p McNemar exact | DÉCISION | bootstrap Δ % [IC95] blocs 64 unités (indicatif) | sha256 spans (16) |", "|---|---|---|---|---|---|---|---|---|---|"]
71
+ for w in VW:
72
+ r = R[w]; b = r["boot_units64_delta_ci95_pct"]; d = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
73
+ rows.append(f"| {w}{' (à part)' if w == 'queries' else ''} | {r['units']}/{r['n_units_all']} | {f(r['paired_rate_ref_pct'])} | {f(r['paired_rate_cand_pct'])} | {r['ref_only']} | {r['cand_only']} | {r['p_mcnemar_exact']:.2g} | {d} | {'—' if b is None else f'{b[0]:+.2f} [{b[1]:+.2f} ; {b[2]:+.2f}]'} | {r['spans_sha256'][:16]} |")
74
+ rows += ["", f"Masques propres (union des corpus des deux bras) : {', '.join(os.path.basename(m) for m in mk) or 'aucun'}. Unités = segments entre frontières de patch COMMUNES aux deux bras ; unité gardée ssi tous ses patches sont in-vocab dans les DEUX bras et aucun octet exclu ; unité réussie ssi tous ses patches sont des hits. neither_code/freshcode exclus ; seen non apparié."]
75
+ open(f"{OUTD}/{tag}__vs_{base}{suf}.md", "w").write("\n".join(rows) + "\n"); json.dump(out, open(f"{OUTD}/{tag}__vs_{base}{suf}.json", "w"), indent=1)
76
+ print("\n".join(rows))
results/hashing/covb_v3_eval/verdict_covb_v42.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """SPIRA Hashing 24 oct. 2026 ~09 h 39 (Toronto) — verdict APPARIÉ v4.2 pour cov b (PRINCIPAL), via une COPIE OCTET-IDENTIQUE de
3
+ checker/scale/verdict_v42.py (v42/verdict_v42.py, sha256 vérifié ci-dessous ; aucun fichier Checker modifié).
4
+ La copie lit, relativement à son propre dossier v42/ : jobs_v4.tsv (copie de checker/scale/jobs_v4.tsv + 2 lignes Hashing ajoutées à la fin :
5
+ covb_broad → broad_local_v1, covb_v3 → corpus_v3 ; vérifiées à l'exécution) et clean_masks/ (copies des masques Checker, sha dans COPIES.sha256).
6
+ Hits : HITS = dossier de mise en scène <out>/hits/ (copies figées : hits cov b + hits de référence Checker hits_v4, sha256 consignés).
7
+ Méthode = verdict_v42.py tel quel : segmentation commune figée par fenêtre et par paire, unités in-vocab dans les DEUX bras, masque propre union,
8
+ taux APPARIÉS + McNemar exact ; bootstrap blocs 64 unités (indicatif). seen jamais apparié : seen_snn rapporté à part (trained_frac ≥ 0,99).
9
+ Usage : verdict_covb_v42.py TAG CAND_HITS_DIR OUTDIR REF[,REF...] (REF = tag ou tag:SUFFIX:KEY, ex. old_ref:__v2b:m9g_hit)
10
+ Sortie : OUTDIR/verdicts/<TAG>__vs_<REF>.json/.md (écrits par la copie) + OUTDIR/v42_<TAG>.json (résumé)."""
11
+ import os, sys, json, shutil, hashlib, subprocess, resource
12
+ D = os.path.dirname(os.path.abspath(__file__)); V = f"{D}/v42"
13
+ CHK_SHA = "a055feaa96f5f1344332bf46678929385a4c5c595e51bf8949dd6592c55d5687" # checker/scale/verdict_v42.py lu le 24 oct. 09 h 35
14
+ CHV4 = "/workspace/spira_shared/checker/scale/hits_v4"
15
+ VW = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3", "queries"]
16
+ LOCAL_JOBS = {"covb_broad": "broad_local_v1", "covb_v3": "corpus_v3"}
17
+ def fsha(p): h = hashlib.sha256(); h.update(open(p, "rb").read()); return h.hexdigest()
18
+ def main(tag, cand_dir, out, refs):
19
+ assert fsha(f"{V}/verdict_v42.py") == CHK_SHA, "copie verdict_v42.py modifiée"
20
+ jt = {l.split("\t")[0]: l.split("\t")[2] for l in open(f"{V}/jobs_v4.tsv").read().splitlines() if l.count("\t") >= 2}
21
+ for t, c in LOCAL_JOBS.items(): assert jt.get(t) == c, f"jobs_v4.tsv local : {t} → {jt.get(t)} ≠ {c}"
22
+ H = f"{out}/hits"; O = f"{out}/verdicts"; os.makedirs(H, exist_ok=True); os.makedirs(O, exist_ok=True)
23
+ S = {"tag": tag, "method": "v4.2 Checker (copie octet-identique, sha " + CHK_SHA[:16] + "…)", "copied_hits_sha256": {}, "refs": {}}
24
+ for w in VW:
25
+ src = f"{cand_dir}/{tag}__{w}.npz"
26
+ if os.path.exists(src): shutil.copyfile(src, f"{H}/{tag}__{w}.npz"); S["copied_hits_sha256"][f"{tag}__{w}"] = fsha(src)
27
+ miss_c = [w for w in VW if not os.path.exists(f"{H}/{tag}__{w}.npz")]
28
+ if miss_c: S["status"] = f"hits candidat manquants : {miss_c} → pas de verdict apparié"; return S
29
+ for r in refs:
30
+ base, suf, key = (r.split(":") + ["", "fused_hit"])[:3] if ":" in r else (r, "", "fused_hit")
31
+ name = base + suf; e = {"base": base, "suffix": suf, "key": key}
32
+ srcs = {w: f"{CHV4}/{base}__{w}{suf}.npz" for w in VW}; miss = [w for w, p in srcs.items() if not os.path.exists(p)]
33
+ if miss: e["status"] = f"ABSENT (hits {name} manquants : {miss})"; S["refs"][name] = e; continue
34
+ for w, p in srcs.items(): shutil.copyfile(p, f"{H}/{base}__{w}{suf}.npz"); S["copied_hits_sha256"][f"{base}__{w}{suf}"] = fsha(p)
35
+ cmd = [sys.executable, f"{V}/verdict_v42.py", tag, base] + ([suf, key] if suf else [])
36
+ env = dict(os.environ, HITS=H, OUTD=O)
37
+ p = subprocess.run(cmd, env=env, capture_output=True, text=True)
38
+ if p.returncode != 0: e["status"] = "ÉCHEC verdict_v42 : " + p.stderr.strip()[-400:]; S["refs"][name] = e; continue
39
+ j = json.load(open(f"{O}/{tag}__vs_{name}.json")); assert j["script_sha256"] == CHK_SHA
40
+ e.update({"status": "OK", "decision": j["decision"], "losses": j["losses"], "gains_fresh": j["gains_fresh"], "masks": [os.path.basename(m) for m in j["masks"]],
41
+ "json": os.path.relpath(f"{O}/{tag}__vs_{name}.json", D), "md": os.path.relpath(f"{O}/{tag}__vs_{name}.md", D), "windows": j["windows"]})
42
+ S["refs"][name] = e
43
+ S["peak_rss_mb_children"] = resource.getrusage(resource.RUSAGE_CHILDREN).ru_maxrss / 1024
44
+ return S
45
+ def md(S, primary):
46
+ f = lambda v: "—" if v is None else f"{v:.2f}"
47
+ L = []
48
+ for name, e in S["refs"].items():
49
+ star = " (DÉCISION PRINCIPALE)" if name == primary else ""
50
+ if e["status"] != "OK": L += [f"### contre {name}{star} — {e['status']}", ""]; continue
51
+ L += [f"### contre {name}{star} : **{e['decision']}** (pertes : {', '.join(e['losses']) or 'aucune'} ; gains frais : {', '.join(e['gains_fresh']) or 'aucun'} ; masques union : {', '.join(e['masks']) or 'aucun'})", "",
52
+ "| fenêtre | unités gardées/toutes | taux APPARIÉ réf % | taux APPARIÉ cand (cov b) % | ref_only | cand_only | p McNemar exact | décision | bootstrap Δ % [IC95] (indicatif) | sha256 spans (16) |", "|---|---|---|---|---|---|---|---|---|---|"]
53
+ for w in VW:
54
+ r = e["windows"][w]; b = r["boot_units64_delta_ci95_pct"]; d = "GAIN" if r["sig_gain"] else ("PERTE" if r["sig_loss"] else "n.s.")
55
+ L.append(f"| {w}{' (à part)' if w == 'queries' else ''} | {r['units']}/{r['n_units_all']} | {f(r['paired_rate_ref_pct'])} | {f(r['paired_rate_cand_pct'])} | {r['ref_only']} | {r['cand_only']} | {r['p_mcnemar_exact']:.2g} | {d} | {'—' if b is None else f'{b[0]:+.2f} [{b[1]:+.2f} ; {b[2]:+.2f}]'} | {r['spans_sha256'][:16]} |")
56
+ L.append("")
57
+ return "\n".join(L)
58
+ if __name__ == "__main__":
59
+ tag, cand, out, refs = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4].split(",")
60
+ S = main(tag, cand, out, refs); json.dump(S, open(f"{out}/v42_{tag}.json", "w"), indent=1, ensure_ascii=False)
61
+ print(json.dumps({k: (v.get("decision"), v.get("status")) for k, v in S.get("refs", {}).items()}, ensure_ascii=False)); print(S.get("status", ""))
results/hashing/dg_need_r1/DG_NEED.diff ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ --- run_C_B.copy_r3.sh 2026-10-31 08:20:03.872285075 -0700
2
+ +++ run_C_B.dgneed_proposed.sh 2026-10-31 08:20:29.000135782 -0700
3
+ @@ -5,7 +5,7 @@
4
+ set -euo pipefail
5
+ S=/workspace/spira_shared; H=$S/checker/recount/v1d_sample_nobroad; RUN=$H/run_C_B; C=$S/spira_m8/v1c/code
6
+ PY=/workspace/SPIRA-venv/bin/python; DG=$S/hashing_gen/proposed_disk_guard_runC/disk_guard.py
7
+ -DG_MIN=1000000000; DG_NEED=2500000000 # arrêt propre si libre < 1,0 Go ; lancement exigé à ≥ 1,0 + 2,5 Go (empreinte keep=1 ≈ 2,4 Go)
8
+ +DG_MIN=1000000000; DG_NEED=2600000000 # arrêt propre si libre < 1,0 Go ; lancement exigé à ≥ 1,0 + 2,6 Go (keep=1 cas haut mesuré 2 525,2 Mo + marge 74,8 Mo ; dg_need_r1)
9
+ EV=$S/checker/recount/m8_v1d_eval_prep/eval_m8_v1d_seen_fresh_r4.py
10
+ GO=$H/GO_RUN_C_B_PHILIPPE_ANTOINE
11
+ export OMP_NUM_THREADS=1 PYTHONDONTWRITEBYTECODE=1 TMPDIR=$RUN/tmp
results/hashing/dg_need_r1/DG_NEED.md ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # DG_NEED — valeur minimale justifiée (dg_need_r1, à sec, 31 oct. 2026 08:20 heure de Vancouver)
2
+ Cible : checker/recount/runC_ready/proposed_r3/run_C_B.proposed_r3.sh (sha a7611e25…, re-vérifié 08:20) l.8 `DG_NEED=2500000000`, porte l.83 : libre ≥ DG_MIN + DG_NEED.
3
+
4
+ ## Tailles réelles (octets, Mo = 10^6 o)
5
+ | poste (keep 1) | source mesurée | Mo |
6
+ |---|---|---|
7
+ | pré-cal ckpt ctl | v1c_ctl_data ckpt 188 664 992 o | 188,665 |
8
+ | pré-cal ckpt cm | ckpt cm pré-cal v1c 465 569 968 o (max des 2) | 465,570 |
9
+ | principal ckpt ctl | idem ctl | 188,665 |
10
+ | principal ctl.npz | m8_cp1/runs 197 909 389 o (mandataire) | 197,909 |
11
+ | principal ckpt cm | idem cm | 465,570 |
12
+ | principal cm.npz | m8_cp1/runs 446 137 688 o (mandataire) | 446,138 |
13
+ | **sous-total persistant** | | **1 952,52** |
14
+ | pic de rotation keep+1 (1 ckpt cm transitoire) | | 465,57 |
15
+ | évals/logs/TMPDIR/génération, cas haut DISK_BUDGET_r2 (e9d12cb6) | 5 + 2 + 100 + 0 | 107,1 |
16
+ | **minimum justifié (cas haut)** | | **2 525,2** |
17
+
18
+ ## Marge et incertitude
19
+ - ctl ×2, ctl.npz, cm.npz : mandataires non mesurés sur le run C (≈ 1 021 Mo), ±5 % → ±51 Mo. Les ckpt cm (931 Mo) sont mesurés au format exact.
20
+ - TMPDIR 100 Mo est déjà un majorant (le code n'écrit pas dans TMPDIR, cf. audit_r17).
21
+ - Dérive concurrente mesurée : 4 646 850 560 o (06:21) → 4 625 047 552 o (08:20), soit −21,8 Mo en ≈ 2 h ≈ 11 Mo/h ; ≈ 370 Mo sur 33 h. Ce n'est pas à la charge de DG_NEED : DG_MIN (1 Go) assure l'arrêt propre et reprenable (exit 75).
22
+ - **Proposition : DG_NEED = 2 600 000 000** (2 525,2 + 51 incertitude + 23,8 arrondi), porte = 3,60 Go.
23
+ - Variante prudente (dérive incluse) : 2 970 000 000, porte = 3,97 Go.
24
+
25
+ ## Tranchage du 3,03 Go
26
+ 3,03 Go = DISK_BUDGET r1 avec TMPDIR 500 Mo + évals 100 Mo, hypothèses réfutées (audit_r17). Il n'y a **aucune justification à le reprendre**. Le 3,02 Go « haut » de CHECKLIST r3 repose sur la même hypothèse : à corriger. L'actuel 2,5 Go est **inférieur de 25,2 Mo** au cas haut mesuré (FAIL marginal).
27
+
28
+ ## df actuel
29
+ 08:20 heure de Vancouver : 4 625 047 552 o libres, 97 %, disque 136 782 041 088 o. Relay dit « ~4,4 Go » : c'est **≈ 4,63 Go** (≈ 4,31 Gio, d'où probablement le 4,4).
30
+
31
+ ## Keep 1 possible ?
32
+ Oui. Porte 3,60 Go → marge 1,03 Go. Variante 3,97 Go → marge 0,66 Go. Fin de run estimée : libre ≈ 4,625 − 2,53 − 0,37 de dérive ≈ 1,73 Go, au-dessus de DG_MIN. Keep 2 (+931 Mo de cm et +377 de ctl) : ≈ 3,83 Go, plus 1 Go de DG_MIN = 4,83 Go > 4,63 Go → **impossible**.
33
+
34
+ Correctif proposé (NON appliqué) : DG_NEED.diff sur la copie run_C_B.copy_r3.sh → run_C_B.dgneed_proposed.sh (l.8, valeur et commentaire ; bash -n OK).
results/hashing/dg_need_r1/SHA256SUMS ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ c37805a5f3c7b70e592b0c277d07f0a3bb37c9e9acb8bcd7f4bce5a58e6ab266 DG_NEED.md
2
+ b17f04126beccad4bf2838788bf4cf0892e7228afc8578e7d58c7ff64f9d123a DG_NEED.diff
3
+ a7611e258bb98225ae22c337570eb39876b898a844fce8cb923dc631e626dbb7 run_C_B.copy_r3.sh
4
+ 2478d901fe37365b600985737336f585778af0ca5b6a589dc4e83e8c5608105f run_C_B.dgneed_proposed.sh
results/hashing/dg_need_r1/run_C_B.copy_r3.sh ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # SPIRA Checker — M8 v1d, option C (pré-cal à budget complet) sur l'échantillon B. PRÉPARÉ, NON LANCÉ. CANDIDAT NON ADOPTÉ.
3
+ # Ne fait RIEN sans le fichier GO signé par Philippe-Antoine (le Checker ne le crée jamais). Tout écart de sha => sortie 3.
4
+ # Aucun code d'entraînement modifié : appelle spira_m8/v1c/code/{run_guarded_v2,train_m8v1c,freeze_scale}.py et eval r4 tels quels.
5
+ set -euo pipefail
6
+ S=/workspace/spira_shared; H=$S/checker/recount/v1d_sample_nobroad; RUN=$H/run_C_B; C=$S/spira_m8/v1c/code
7
+ PY=/workspace/SPIRA-venv/bin/python; DG=$S/hashing_gen/proposed_disk_guard_runC/disk_guard.py
8
+ DG_MIN=1000000000; DG_NEED=2500000000 # arrêt propre si libre < 1,0 Go ; lancement exigé à ≥ 1,0 + 2,5 Go (empreinte keep=1 ≈ 2,4 Go)
9
+ EV=$S/checker/recount/m8_v1d_eval_prep/eval_m8_v1d_seen_fresh_r4.py
10
+ GO=$H/GO_RUN_C_B_PHILIPPE_ANTOINE
11
+ export OMP_NUM_THREADS=1 PYTHONDONTWRITEBYTECODE=1 TMPDIR=$RUN/tmp
12
+ die(){ echo "REFUS: $*" >&2; exit 3; }
13
+ # 1) porte : GO signé, qui doit citer le sha de CE script
14
+ [ -f "$GO" ] || die "pas de $GO (oui écrit de Philippe-Antoine requis)"
15
+ ME=$(sha256sum "$0" | cut -d' ' -f1)
16
+ grep -q "^OUI Philippe-Antoine Robert" "$GO" || die "GO non signé « OUI Philippe-Antoine Robert »"
17
+ grep -q "run_C_B.sh $ME" "$GO" || die "GO ne cite pas run_C_B.sh $ME"
18
+ # 2) shas vérifiés au démarrage
19
+ while read -r h f; do
20
+ [ -f "$f" ] || die "absent : $f"; [ "$(sha256sum "$f" | cut -d' ' -f1)" = "$h" ] || die "sha ≠ : $f"
21
+ done <<L
22
+ b7404e88146b1f80572a8d5a41c50075e61f29e3e4088a16e5111dac94c75609 $H/v1d_nobroad_B.bin
23
+ 992d20aa8a447efb16b90b6693414bb20def980e089f6e8a2db51e23ad99068b $H/precal_prefix_nobroad_B.bin
24
+ 903970c3319a2770432565ecf5a8616bf3ae34c4f8384669221a93ab998833e5 $S/hashing_gen/corpus_diverse_v1d/train.bin
25
+ b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3 $S/broad/freshcode_v2.bin
26
+ 67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a $S/spira_m7/windows/fresh_en.bin
27
+ 875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715 $S/spira_m7/windows/fresh_fr.bin
28
+ ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22 $S/spira_m7/windows/test20k.bin
29
+ a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84 $S/corpus_v3/test.bin
30
+ 5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706 $S/spira_m7/windows/queries.bin
31
+ 1c6f64b44403932905b2f3ffee80db90de9b979e8d27441d6e58b3cd85a28bc1 $C/run_guarded_v2.py
32
+ 4049327ca9882c7baccd3f106a0b6ea4a58335990a6cfda24e39be530157ada7 $C/train_m8v1c.py
33
+ dafc1de2654fdf3171ed8284994442d9b1efc8a8ee005715478e723cb4c9ba48 $C/freeze_scale.py
34
+ 8fc571577fdd48c99e0c070d175f4544a21b4084d99896ea390de626e156fe77 $EV
35
+ 363c16c9f3b135a8671d3d79eb6760437e8e1b1da7462083227d424dad4f5ff1 $S/hashing_gen/proposed_disk_guard_runC/disk_guard.py
36
+ 889c603f0d17cb54060951bcf4c4f9b8c9ebd9e52b392c70209bbb9755d797d9 /usr/bin/python3.13
37
+ 81c5998fb4c64b7be806cb85fbcff8bd9393b8c9fa55918bbe69d552183d019f $S/checker/recount/runC_ready/proposed_r3/pkg_freeze.txt
38
+ cddb0099ff51c991b2d2a19ac82d3d347f336749f75655bb38ab50077b088f1f /workspace/SPIRA/python/spira/__init__.py
39
+ d8222aabb3d4617bdce64977f38c454f69615c8681cb1652e9f44c36bf7a1c04 /workspace/SPIRA/python/spira/ept.py
40
+ f26903e19cd92963e84d6271fc296d4998c4b364ce28be712241236391c2ab02 /workspace/SPIRA/python/spira/hashing.py
41
+ e48148a81b0cce703ffa25327c1db228939323f88d5b945a25cf88f6fec91d78 /workspace/SPIRA/python/spira/hippocampus.py
42
+ 81021ea0bebd1a1743e2b4f232a825c532db56b9cee2f59df401b8b1df24d6ab /workspace/SPIRA/python/spira/model.py
43
+ beabae44a2833b29288f8dd8c5b20c7e688d96b790570d3d35ae2ead810478a3 /workspace/SPIRA/python/spira/spiking.py
44
+ 09295a80660f17925ae23765ce8cbd7ff7ceae968d5f2f89349f1cb74c0b9e11 /workspace/SPIRA-venv/lib/python3.13/site-packages/numpy/__init__.py
45
+ 344c87cc95d8d56eb4addbefe63e798107e1ab2b32141097dd5623ebe166f7ba /workspace/SPIRA-venv/lib/python3.13/site-packages/numpy/version.py
46
+ 405abe5c8f52c1d15b71bafbd155693237b6e1742bc598638b7fc0626bcc1576 /workspace/SPIRA-venv/lib/python3.13/site-packages/numpy/_core/_multiarray_umath.cpython-313-x86_64-linux-gnu.so
47
+ f15d9f7f32bd87fc0082e3d4eb46304b0fafbfd27bae712811c0bae20cf3d563 /workspace/SPIRA-venv/lib/python3.13/site-packages/numpy/linalg/_umath_linalg.cpython-313-x86_64-linux-gnu.so
48
+ caab50405e73eba7981f73a63fb1709139aed55383501c3e830e174cb02b8d3b $S/hashing_gen/m8_v1b/code/countmin.py
49
+ 7d9ed224012184b19723c0254982878bc0a56102ef4722dd3d443ed6486869c1 $S/checker/windows_v2.py
50
+ e2c8cd1deabc228faed302bebdb81bf8d10405df63e393b4a8ddb6152401c10e $S/checker/eval_ref_v3.py
51
+ 56efcbc6c12f71221ddfb8d57b5e3fbb29d9b054cc363aa062fa1e396639bb7e $S/checker/scale/bench_common.py
52
+ aeba27c3c695987bba722f725035aa2fbe6f69be82a527c06dac6d56eabc4c64 $S/checker/recount/m8_v1d_eval_prep/stats_m8_v1d.py
53
+ 29e6d015a08b97a19d6f05721e09cdd7f6bf852b8e26c9f24bbe3f2cdc1ef7ca $S/checker/recount/m8_v1d_eval_prep/leak16_m8_v1d.py
54
+ 71b577724fe46d2f221415dc7ceac2c063cfa412f98a1d8c02ee525fc9f25c02 $S/checker/recount/v1d_sample_nobroad/masks_B/selfcheck_dedup64_norm.json
55
+ b2ec9f64d6f6ba594f330fa7b1da0b6aaf39b8fd4a257a2edd5583d1eab10e22 $S/checker/recount/v1d_sample_nobroad/masks_B/selfcheck_dedup64_raw.json
56
+ 7ac2ea01c4454ce739c0a900e8c60fad2b676dbc4be29a7414eee3be7bb83135 $S/checker/recount/v1d_sample_nobroad/masks_B/selfcheck_masks_norm.npz
57
+ 7ac2ea01c4454ce739c0a900e8c60fad2b676dbc4be29a7414eee3be7bb83135 $S/checker/recount/v1d_sample_nobroad/masks_B/selfcheck_masks_raw.npz
58
+ e2cde9351b8ffff8f357d8c850c722d87a3d0e45839f84a12d8deea4f9620d0d $S/checker/recount/v1d_sample_nobroad/masks_B/selfcheck_train_ranges_norm.npz
59
+ e2cde9351b8ffff8f357d8c850c722d87a3d0e45839f84a12d8deea4f9620d0d $S/checker/recount/v1d_sample_nobroad/masks_B/selfcheck_train_ranges_raw.npz
60
+ 1b1075619cfee614e6173342ae65377eb7b7720a555394bc94e90f8db870fd58 $S/hashing_gen/corpus_diverse_v1d/SHA256SUMS
61
+ 1350f86f2a839e0552be4135a7cc0a60723bcdd4e10ef4a260f6300788fd42ac $S/hashing_gen/corpus_diverse_v1d/build.log
62
+ c0e97baf10dfd7c0353b0db156b3f875cc432d954e3281ee77dbb7d7bd7479cb $S/hashing_gen/corpus_diverse_v1d/build_v1d.py
63
+ cace49cb7b37a57ae2d7a1959a5972560dcf529d1690640be183a4f5197a4f48 $S/hashing_gen/corpus_diverse_v1d/lcs_kcode_broad.json
64
+ a91a17f7a9c254d925150f989de09ec0583cc027336bdb6be47cdf343ae7ad37 $S/hashing_gen/corpus_diverse_v1d/lcs_kcode_broad.py
65
+ 89e34682bc7a850f713c22bd3777c7c5c5fa4696b8a0d039711b1dafb0c0cda6 $S/hashing_gen/corpus_diverse_v1d/manifest.json
66
+ 52e1b9464caa1b727f05ae4c88c923b701b8a67b552032aa3bdb3f862d723e6c $S/hashing_gen/corpus_diverse_v1d/manifest_r2.json
67
+ 6fd789c63f37f60c177b0b865da4a4670a6276f53543361cb23abf1d3cc82090 $S/hashing_gen/corpus_diverse_v1d/selfcheck_dedup64.py
68
+ fb628ea5f77477dcac9e275c37d437f6091f57a2468f9f4ec7ef11a2bc637632 $S/hashing_gen/corpus_diverse_v1d/selfcheck_dedup64_norm.json
69
+ 2b3b7c5b96c3e84df5073a76e16219f86bd912bb209c0a3fd5cb9515322b9410 $S/hashing_gen/corpus_diverse_v1d/selfcheck_dedup64_raw.json
70
+ cefc96926246eddb33824c6941e21bb4201970bccf2fcb3389624178c528cbe8 $S/hashing_gen/corpus_diverse_v1d/selfcheck_masks_norm.npz
71
+ cefc96926246eddb33824c6941e21bb4201970bccf2fcb3389624178c528cbe8 $S/hashing_gen/corpus_diverse_v1d/selfcheck_masks_raw.npz
72
+ cb87b2bb5c93a49be1284cd3311fb48a4e3fe2ce2a62c8105ffbbbd579ddbc53 $S/hashing_gen/corpus_diverse_v1d/selfcheck_norm.log
73
+ f9276bf52c87cf3194058e0d91190a2b909e327ec6ea77217c6c23ac368258a7 $S/hashing_gen/corpus_diverse_v1d/selfcheck_raw.log
74
+ 4d14b14a2aea0a1b24afd228d4cc3a396264989553730e05e6b39b75234bca4b $S/hashing_gen/corpus_diverse_v1d/selfcheck_train_ranges_norm.npz
75
+ 4d14b14a2aea0a1b24afd228d4cc3a396264989553730e05e6b39b75234bca4b $S/hashing_gen/corpus_diverse_v1d/selfcheck_train_ranges_raw.npz
76
+ L
77
+ [ "$(readlink -f "$PY")" = /usr/bin/python3.13 ] || die "interpréteur ≠ /usr/bin/python3.13"
78
+ [ "$($PY -c 'import importlib.metadata as m; print(chr(10).join(sorted(f"{d.name}=={d.version}" for d in m.distributions())))' | sha256sum | cut -d' ' -f1)" = "$(sha256sum < $S/checker/recount/runC_ready/proposed_r3/pkg_freeze.txt | cut -d' ' -f1)" ] || die "paquets ≠ pkg_freeze.txt"
79
+ [ -f $S/spira_m8/GO_CHECKER_DEDUP_V1D ] || die "drapeau GO_CHECKER_DEDUP_V1D absent (exigé par eval r4)"
80
+ MA=$(awk '/MemAvailable/{print $2*1024}' /proc/meminfo); [ "$MA" -ge 6500000000 ] || die "MemAvailable $MA < 6,5 Go"
81
+ [ ! -e "$RUN/precal/PRECAL_HORS_BORNES.json" ] || die "pré-cal déjà hors bornes : NON MESURABLE, pas de relance"
82
+ mkdir -p "$RUN"/{precal,runs,eval,logs,tmp}
83
+ FREE=$(df -B1 --output=avail "$RUN" | tail -1); [ "$FREE" -ge $((DG_MIN+DG_NEED)) ] || die "disque libre $FREE < $((DG_MIN+DG_NEED))"
84
+ G(){ local n=$1; shift; nice -n 10 $PY $C/run_guarded_v2.py --name "$n" --log "$RUN/logs/$n.log" --guard-log "$RUN/logs/guard_$n.log" \
85
+ --peak 2500000000 --min-launch 5200000000 --floor 4000000000 --rss-cap 3500000000 --mode checkpoint --max-heavy 4 --nice 10 -- $PY $DG --path $RUN --min-free $DG_MIN --poll 30 --marker $RUN/logs/DISK_LOW_$n.json -- "$@"; }
86
+ # 3) pré-cal C, budget complet, séquentielle (ctl puis cm), préfixe B, sans fenêtre
87
+ for A in ctl cm; do
88
+ [ -f "$RUN/precal/precal_$A.json" ] || G precal_$A $PY $C/train_m8v1c.py --arm $A --data $H/precal_prefix_nobroad_B.bin \
89
+ --outdir $RUN/precal/out_$A --ckpt-dir $RUN/precal/ckpt_$A --resume auto --fresh --ckpt-keep 1 \
90
+ --snn-tokens 600000 --am-tokens 1200000 --epochs 2 --windows "" --no-save --precal-out $RUN/precal/precal_$A.json
91
+ done
92
+ # 4) gel : sortie 10 => PRECAL_HORS_BORNES, arrêt (NON MESURABLE, pas de sauvetage)
93
+ set +e; $PY $C/freeze_scale.py $RUN/precal; rc=$?; set -e
94
+ [ $rc -eq 0 ] || { echo "freeze_scale rc=$rc : NON MESURABLE, arrêt"; exit 10; }
95
+ # 5) runs principaux, budget égal, échantillon B
96
+ for A in ctl cm; do
97
+ [ -f "$RUN/runs/$A/$A.npz" ] || G main_$A $PY $C/train_m8v1c.py --arm $A --data $H/v1d_nobroad_B.bin --outdir $RUN/runs/$A \
98
+ --resume auto --fresh --ckpt-keep 1 --snn-tokens 600000 --am-tokens 1200000 --epochs 2 --maxpos 4000 --frozen-scale-json $RUN/precal/FROZEN_SCALE.json
99
+ done
100
+ # 6) éval r4 (leak16 diagnostic seul)
101
+ G eval_r4 $PY $EV --ref $RUN/runs/ctl/ctl.npz --cand $RUN/runs/cm/cm.npz --ref-arm ctl --cand-arm cm \
102
+ --data $H/v1d_nobroad_B.bin --data-sha256 b7404e88146b1f80572a8d5a41c50075e61f29e3e4088a16e5111dac94c75609 \
103
+ --snn-tokens 600000 --frozen-scale $RUN/precal/FROZEN_SCALE.json --corpus-sc $S/hashing_gen/corpus_diverse_v1d \
104
+ --sample-sc $H/masks_B --flag-dedup $S/spira_m8/GO_CHECKER_DEDUP_V1D --outdir $RUN/eval --maxpos 4000
105
+ echo FIN
results/hashing/dg_need_r1/run_C_B.dgneed_proposed.sh ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # SPIRA Checker — M8 v1d, option C (pré-cal à budget complet) sur l'échantillon B. PRÉPARÉ, NON LANCÉ. CANDIDAT NON ADOPTÉ.
3
+ # Ne fait RIEN sans le fichier GO signé par Philippe-Antoine (le Checker ne le crée jamais). Tout écart de sha => sortie 3.
4
+ # Aucun code d'entraînement modifié : appelle spira_m8/v1c/code/{run_guarded_v2,train_m8v1c,freeze_scale}.py et eval r4 tels quels.
5
+ set -euo pipefail
6
+ S=/workspace/spira_shared; H=$S/checker/recount/v1d_sample_nobroad; RUN=$H/run_C_B; C=$S/spira_m8/v1c/code
7
+ PY=/workspace/SPIRA-venv/bin/python; DG=$S/hashing_gen/proposed_disk_guard_runC/disk_guard.py
8
+ DG_MIN=1000000000; DG_NEED=2600000000 # arrêt propre si libre < 1,0 Go ; lancement exigé à ≥ 1,0 + 2,6 Go (keep=1 cas haut mesuré 2 525,2 Mo + marge 74,8 Mo ; dg_need_r1)
9
+ EV=$S/checker/recount/m8_v1d_eval_prep/eval_m8_v1d_seen_fresh_r4.py
10
+ GO=$H/GO_RUN_C_B_PHILIPPE_ANTOINE
11
+ export OMP_NUM_THREADS=1 PYTHONDONTWRITEBYTECODE=1 TMPDIR=$RUN/tmp
12
+ die(){ echo "REFUS: $*" >&2; exit 3; }
13
+ # 1) porte : GO signé, qui doit citer le sha de CE script
14
+ [ -f "$GO" ] || die "pas de $GO (oui écrit de Philippe-Antoine requis)"
15
+ ME=$(sha256sum "$0" | cut -d' ' -f1)
16
+ grep -q "^OUI Philippe-Antoine Robert" "$GO" || die "GO non signé « OUI Philippe-Antoine Robert »"
17
+ grep -q "run_C_B.sh $ME" "$GO" || die "GO ne cite pas run_C_B.sh $ME"
18
+ # 2) shas vérifiés au démarrage
19
+ while read -r h f; do
20
+ [ -f "$f" ] || die "absent : $f"; [ "$(sha256sum "$f" | cut -d' ' -f1)" = "$h" ] || die "sha ≠ : $f"
21
+ done <<L
22
+ b7404e88146b1f80572a8d5a41c50075e61f29e3e4088a16e5111dac94c75609 $H/v1d_nobroad_B.bin
23
+ 992d20aa8a447efb16b90b6693414bb20def980e089f6e8a2db51e23ad99068b $H/precal_prefix_nobroad_B.bin
24
+ 903970c3319a2770432565ecf5a8616bf3ae34c4f8384669221a93ab998833e5 $S/hashing_gen/corpus_diverse_v1d/train.bin
25
+ b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3 $S/broad/freshcode_v2.bin
26
+ 67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a $S/spira_m7/windows/fresh_en.bin
27
+ 875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715 $S/spira_m7/windows/fresh_fr.bin
28
+ ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22 $S/spira_m7/windows/test20k.bin
29
+ a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84 $S/corpus_v3/test.bin
30
+ 5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706 $S/spira_m7/windows/queries.bin
31
+ 1c6f64b44403932905b2f3ffee80db90de9b979e8d27441d6e58b3cd85a28bc1 $C/run_guarded_v2.py
32
+ 4049327ca9882c7baccd3f106a0b6ea4a58335990a6cfda24e39be530157ada7 $C/train_m8v1c.py
33
+ dafc1de2654fdf3171ed8284994442d9b1efc8a8ee005715478e723cb4c9ba48 $C/freeze_scale.py
34
+ 8fc571577fdd48c99e0c070d175f4544a21b4084d99896ea390de626e156fe77 $EV
35
+ 363c16c9f3b135a8671d3d79eb6760437e8e1b1da7462083227d424dad4f5ff1 $S/hashing_gen/proposed_disk_guard_runC/disk_guard.py
36
+ 889c603f0d17cb54060951bcf4c4f9b8c9ebd9e52b392c70209bbb9755d797d9 /usr/bin/python3.13
37
+ 81c5998fb4c64b7be806cb85fbcff8bd9393b8c9fa55918bbe69d552183d019f $S/checker/recount/runC_ready/proposed_r3/pkg_freeze.txt
38
+ cddb0099ff51c991b2d2a19ac82d3d347f336749f75655bb38ab50077b088f1f /workspace/SPIRA/python/spira/__init__.py
39
+ d8222aabb3d4617bdce64977f38c454f69615c8681cb1652e9f44c36bf7a1c04 /workspace/SPIRA/python/spira/ept.py
40
+ f26903e19cd92963e84d6271fc296d4998c4b364ce28be712241236391c2ab02 /workspace/SPIRA/python/spira/hashing.py
41
+ e48148a81b0cce703ffa25327c1db228939323f88d5b945a25cf88f6fec91d78 /workspace/SPIRA/python/spira/hippocampus.py
42
+ 81021ea0bebd1a1743e2b4f232a825c532db56b9cee2f59df401b8b1df24d6ab /workspace/SPIRA/python/spira/model.py
43
+ beabae44a2833b29288f8dd8c5b20c7e688d96b790570d3d35ae2ead810478a3 /workspace/SPIRA/python/spira/spiking.py
44
+ 09295a80660f17925ae23765ce8cbd7ff7ceae968d5f2f89349f1cb74c0b9e11 /workspace/SPIRA-venv/lib/python3.13/site-packages/numpy/__init__.py
45
+ 344c87cc95d8d56eb4addbefe63e798107e1ab2b32141097dd5623ebe166f7ba /workspace/SPIRA-venv/lib/python3.13/site-packages/numpy/version.py
46
+ 405abe5c8f52c1d15b71bafbd155693237b6e1742bc598638b7fc0626bcc1576 /workspace/SPIRA-venv/lib/python3.13/site-packages/numpy/_core/_multiarray_umath.cpython-313-x86_64-linux-gnu.so
47
+ f15d9f7f32bd87fc0082e3d4eb46304b0fafbfd27bae712811c0bae20cf3d563 /workspace/SPIRA-venv/lib/python3.13/site-packages/numpy/linalg/_umath_linalg.cpython-313-x86_64-linux-gnu.so
48
+ caab50405e73eba7981f73a63fb1709139aed55383501c3e830e174cb02b8d3b $S/hashing_gen/m8_v1b/code/countmin.py
49
+ 7d9ed224012184b19723c0254982878bc0a56102ef4722dd3d443ed6486869c1 $S/checker/windows_v2.py
50
+ e2c8cd1deabc228faed302bebdb81bf8d10405df63e393b4a8ddb6152401c10e $S/checker/eval_ref_v3.py
51
+ 56efcbc6c12f71221ddfb8d57b5e3fbb29d9b054cc363aa062fa1e396639bb7e $S/checker/scale/bench_common.py
52
+ aeba27c3c695987bba722f725035aa2fbe6f69be82a527c06dac6d56eabc4c64 $S/checker/recount/m8_v1d_eval_prep/stats_m8_v1d.py
53
+ 29e6d015a08b97a19d6f05721e09cdd7f6bf852b8e26c9f24bbe3f2cdc1ef7ca $S/checker/recount/m8_v1d_eval_prep/leak16_m8_v1d.py
54
+ 71b577724fe46d2f221415dc7ceac2c063cfa412f98a1d8c02ee525fc9f25c02 $S/checker/recount/v1d_sample_nobroad/masks_B/selfcheck_dedup64_norm.json
55
+ b2ec9f64d6f6ba594f330fa7b1da0b6aaf39b8fd4a257a2edd5583d1eab10e22 $S/checker/recount/v1d_sample_nobroad/masks_B/selfcheck_dedup64_raw.json
56
+ 7ac2ea01c4454ce739c0a900e8c60fad2b676dbc4be29a7414eee3be7bb83135 $S/checker/recount/v1d_sample_nobroad/masks_B/selfcheck_masks_norm.npz
57
+ 7ac2ea01c4454ce739c0a900e8c60fad2b676dbc4be29a7414eee3be7bb83135 $S/checker/recount/v1d_sample_nobroad/masks_B/selfcheck_masks_raw.npz
58
+ e2cde9351b8ffff8f357d8c850c722d87a3d0e45839f84a12d8deea4f9620d0d $S/checker/recount/v1d_sample_nobroad/masks_B/selfcheck_train_ranges_norm.npz
59
+ e2cde9351b8ffff8f357d8c850c722d87a3d0e45839f84a12d8deea4f9620d0d $S/checker/recount/v1d_sample_nobroad/masks_B/selfcheck_train_ranges_raw.npz
60
+ 1b1075619cfee614e6173342ae65377eb7b7720a555394bc94e90f8db870fd58 $S/hashing_gen/corpus_diverse_v1d/SHA256SUMS
61
+ 1350f86f2a839e0552be4135a7cc0a60723bcdd4e10ef4a260f6300788fd42ac $S/hashing_gen/corpus_diverse_v1d/build.log
62
+ c0e97baf10dfd7c0353b0db156b3f875cc432d954e3281ee77dbb7d7bd7479cb $S/hashing_gen/corpus_diverse_v1d/build_v1d.py
63
+ cace49cb7b37a57ae2d7a1959a5972560dcf529d1690640be183a4f5197a4f48 $S/hashing_gen/corpus_diverse_v1d/lcs_kcode_broad.json
64
+ a91a17f7a9c254d925150f989de09ec0583cc027336bdb6be47cdf343ae7ad37 $S/hashing_gen/corpus_diverse_v1d/lcs_kcode_broad.py
65
+ 89e34682bc7a850f713c22bd3777c7c5c5fa4696b8a0d039711b1dafb0c0cda6 $S/hashing_gen/corpus_diverse_v1d/manifest.json
66
+ 52e1b9464caa1b727f05ae4c88c923b701b8a67b552032aa3bdb3f862d723e6c $S/hashing_gen/corpus_diverse_v1d/manifest_r2.json
67
+ 6fd789c63f37f60c177b0b865da4a4670a6276f53543361cb23abf1d3cc82090 $S/hashing_gen/corpus_diverse_v1d/selfcheck_dedup64.py
68
+ fb628ea5f77477dcac9e275c37d437f6091f57a2468f9f4ec7ef11a2bc637632 $S/hashing_gen/corpus_diverse_v1d/selfcheck_dedup64_norm.json
69
+ 2b3b7c5b96c3e84df5073a76e16219f86bd912bb209c0a3fd5cb9515322b9410 $S/hashing_gen/corpus_diverse_v1d/selfcheck_dedup64_raw.json
70
+ cefc96926246eddb33824c6941e21bb4201970bccf2fcb3389624178c528cbe8 $S/hashing_gen/corpus_diverse_v1d/selfcheck_masks_norm.npz
71
+ cefc96926246eddb33824c6941e21bb4201970bccf2fcb3389624178c528cbe8 $S/hashing_gen/corpus_diverse_v1d/selfcheck_masks_raw.npz
72
+ cb87b2bb5c93a49be1284cd3311fb48a4e3fe2ce2a62c8105ffbbbd579ddbc53 $S/hashing_gen/corpus_diverse_v1d/selfcheck_norm.log
73
+ f9276bf52c87cf3194058e0d91190a2b909e327ec6ea77217c6c23ac368258a7 $S/hashing_gen/corpus_diverse_v1d/selfcheck_raw.log
74
+ 4d14b14a2aea0a1b24afd228d4cc3a396264989553730e05e6b39b75234bca4b $S/hashing_gen/corpus_diverse_v1d/selfcheck_train_ranges_norm.npz
75
+ 4d14b14a2aea0a1b24afd228d4cc3a396264989553730e05e6b39b75234bca4b $S/hashing_gen/corpus_diverse_v1d/selfcheck_train_ranges_raw.npz
76
+ L
77
+ [ "$(readlink -f "$PY")" = /usr/bin/python3.13 ] || die "interpréteur ≠ /usr/bin/python3.13"
78
+ [ "$($PY -c 'import importlib.metadata as m; print(chr(10).join(sorted(f"{d.name}=={d.version}" for d in m.distributions())))' | sha256sum | cut -d' ' -f1)" = "$(sha256sum < $S/checker/recount/runC_ready/proposed_r3/pkg_freeze.txt | cut -d' ' -f1)" ] || die "paquets ≠ pkg_freeze.txt"
79
+ [ -f $S/spira_m8/GO_CHECKER_DEDUP_V1D ] || die "drapeau GO_CHECKER_DEDUP_V1D absent (exigé par eval r4)"
80
+ MA=$(awk '/MemAvailable/{print $2*1024}' /proc/meminfo); [ "$MA" -ge 6500000000 ] || die "MemAvailable $MA < 6,5 Go"
81
+ [ ! -e "$RUN/precal/PRECAL_HORS_BORNES.json" ] || die "pré-cal déjà hors bornes : NON MESURABLE, pas de relance"
82
+ mkdir -p "$RUN"/{precal,runs,eval,logs,tmp}
83
+ FREE=$(df -B1 --output=avail "$RUN" | tail -1); [ "$FREE" -ge $((DG_MIN+DG_NEED)) ] || die "disque libre $FREE < $((DG_MIN+DG_NEED))"
84
+ G(){ local n=$1; shift; nice -n 10 $PY $C/run_guarded_v2.py --name "$n" --log "$RUN/logs/$n.log" --guard-log "$RUN/logs/guard_$n.log" \
85
+ --peak 2500000000 --min-launch 5200000000 --floor 4000000000 --rss-cap 3500000000 --mode checkpoint --max-heavy 4 --nice 10 -- $PY $DG --path $RUN --min-free $DG_MIN --poll 30 --marker $RUN/logs/DISK_LOW_$n.json -- "$@"; }
86
+ # 3) pré-cal C, budget complet, séquentielle (ctl puis cm), préfixe B, sans fenêtre
87
+ for A in ctl cm; do
88
+ [ -f "$RUN/precal/precal_$A.json" ] || G precal_$A $PY $C/train_m8v1c.py --arm $A --data $H/precal_prefix_nobroad_B.bin \
89
+ --outdir $RUN/precal/out_$A --ckpt-dir $RUN/precal/ckpt_$A --resume auto --fresh --ckpt-keep 1 \
90
+ --snn-tokens 600000 --am-tokens 1200000 --epochs 2 --windows "" --no-save --precal-out $RUN/precal/precal_$A.json
91
+ done
92
+ # 4) gel : sortie 10 => PRECAL_HORS_BORNES, arrêt (NON MESURABLE, pas de sauvetage)
93
+ set +e; $PY $C/freeze_scale.py $RUN/precal; rc=$?; set -e
94
+ [ $rc -eq 0 ] || { echo "freeze_scale rc=$rc : NON MESURABLE, arrêt"; exit 10; }
95
+ # 5) runs principaux, budget égal, échantillon B
96
+ for A in ctl cm; do
97
+ [ -f "$RUN/runs/$A/$A.npz" ] || G main_$A $PY $C/train_m8v1c.py --arm $A --data $H/v1d_nobroad_B.bin --outdir $RUN/runs/$A \
98
+ --resume auto --fresh --ckpt-keep 1 --snn-tokens 600000 --am-tokens 1200000 --epochs 2 --maxpos 4000 --frozen-scale-json $RUN/precal/FROZEN_SCALE.json
99
+ done
100
+ # 6) éval r4 (leak16 diagnostic seul)
101
+ G eval_r4 $PY $EV --ref $RUN/runs/ctl/ctl.npz --cand $RUN/runs/cm/cm.npz --ref-arm ctl --cand-arm cm \
102
+ --data $H/v1d_nobroad_B.bin --data-sha256 b7404e88146b1f80572a8d5a41c50075e61f29e3e4088a16e5111dac94c75609 \
103
+ --snn-tokens 600000 --frozen-scale $RUN/precal/FROZEN_SCALE.json --corpus-sc $S/hashing_gen/corpus_diverse_v1d \
104
+ --sample-sc $H/masks_B --flag-dedup $S/spira_m8/GO_CHECKER_DEDUP_V1D --outdir $RUN/eval --maxpos 4000
105
+ echo FIN
results/hashing/gap_vs_size/REPORT.md ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Écart vu/frais vs taille du corpus — diagnostic léger (Hashing)
2
+ Lecture seule de résultats existants (gap_vs_size.py → results.json). Aucun entraînement, aucune éval relancée, pic RSS 18 Mo, nice 10. Métrique : fused_invocab_pct ; écart = seen − moyenne(fc2, fresh_en, fresh_fr, test20k, test_v3), neither_code exclu.
3
+
4
+ | run | train (o) | sha train | octets lus SNN | seen | moy. frais (n fen.) | écart |
5
+ |---|---|---|---|---|---|---|
6
+ | v1b ctl | 35 128 951 | 9ea562e4 | 2 791 343 | 98,440 | 2,012 (5) | 96,428 |
7
+ | v1c ctl | 35 948 296 | 3d8b6181 | 2 706 257 | 93,183 | 3,999 (5) | 89,184 |
8
+ | old_ref (plain) | 12 468 350 | e12b6586 | non trouvé | 98,330 | 4,440 (5) | 93,890 |
9
+ | broad14_ref (plain) | 34 835 257 | eda07017 | non trouvé | 91,934 | 4,786 (4) | 87,148 |
10
+ | m8_broad14 (cm) | 34 835 257 | eda07017 | non trouvé | 91,819 | 6,444 (4) | 85,376 |
11
+ | m8_v3 (cm) | 93 284 487 | aabd912d | non trouvé | 91,945 | 5,773 (5) | 86,172 |
12
+ | bg1_m8 (cm) | 290 810 502 | 5af6398f | 2 211 450 | 8,990* | 7,714 (4) | 1,276* |
13
+
14
+ Sources : v1b hashing_gen/m8_v1b/runs/results.jsonl (5a722834), v1c spira_m8/v1c_ctl_data/runs/results.jsonl (6d6898f5), broad checker/scale/results_v4.jsonl (lecture seule ; sha dans results.json), snn bg1 = checker/scale/cm_bg1d_m8.cov.json. run_iii ratio_ckpt : non utilisé (points précal 60k ticks, aucune éval fraîche).
15
+
16
+ ## Comparabilité — variables confondantes
17
+ 1. **La taille n'est pas l'axe réel** : v1b et v1c sont entraînés sur des échantillons de ~35 Mo (corpus pleins 530 Mo et 503 Mo), et le SNN ne lit que ~2,7–2,8 Mo dans tous les runs mesurés (budget fixe 600k ticks SNN / 1,2M AM, 2 époques). Augmenter le corpus ne change pas ce qui est lu, seulement la composition et le vocabulaire.
18
+ 2. **v1b vs v1c** : même budget, même code de train/éval, même n=4000 → comparables entre eux ; mais taille quasi identique (+2,3 %) : l'écart −7,2 pt est un effet de **composition**, pas de taille.
19
+ 3. **Famille broad** : autre script d'éval (eval_bench_v4 / v4.x de Checker, n=8000/20000), test20k masqué (None) pour broad14/bg1 → 4 fenêtres, bras mélangés (plain vs cm), calibration différente → **non comparable** à v1b/v1c en niveau.
20
+ 4. **bg1_m8*** : seen = tranche SNN 32 stratifiée, pas la fenêtre mémorisée → l'écart 1,3 n'a pas le même sens ; exclu de la pente.
21
+ 5. Réserve test20k : version « old » ce0526c6 non revérifiée par fichier.
22
+
23
+ ## Pente
24
+ Seuls points vraiment comparables : v1b/v1c → 2 points à la même taille, **pente non définie**. Indicatif, famille broad (old_ref, m8_broad14, m8_v3 ; 3 points, bras mélangés) : −8,9 pt par décade de taille, IC 95 % [−85,7 ; +67,9] (ddl = 1). Franchement : **pas de pente exploitable**.
25
+
26
+ ## Prédiction v1d (903970c3, 503 053 492 o)
27
+ **Non prédictible.** Le run v1d ne lirait lui aussi qu'un échantillon (B b7404e88) avec le même budget SNN ; la taille n'est donc pas une variable explicative mesurée. v1d = v1c moins 247 656 o de code : le plus proche analogue est v1c (89,2), mais rien dans ces données ne permet d'en tirer un intervalle défendable.
results/hashing/gap_vs_size/SHA256SUMS ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ 210fd2b49a369c9d9ab3cb1f4bd94f09f9d25603a7b3a9b8e3269c8882210c0f gap_vs_size.py
2
+ 5e5d0c9f1348f65005086d9f7538db3a4c242f383acc362365a3c22c520548cd results.json
3
+ 87a562090deb3f28d237af3b7d13bd43776ca4cc18c0c5bcb1d09277e67944c5 REPORT.md
results/hashing/gap_vs_size/gap_vs_size.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Diagnostic léger écart vu/frais vs taille corpus — lecture de résultats existants uniquement."""
2
+ import json, hashlib, os, resource, math
3
+ S = "/workspace/spira_shared"
4
+ FRESH = ["fc2", "fresh_en", "fresh_fr", "test20k", "test_v3"] # neither_code exclu
5
+ def sha(p, cache={}):
6
+ h = hashlib.sha256()
7
+ with open(p, "rb") as f:
8
+ for b in iter(lambda: f.read(1 << 20), b""): h.update(b)
9
+ return h.hexdigest()
10
+ def fsha(p): return hashlib.sha256(open(p, "rb").read()).hexdigest()
11
+ rows = []
12
+ # famille M8 eval intégrée au trainer (n=4000, fused_invocab_pct)
13
+ for name, f in [("v1b ctl", "hashing_gen/m8_v1b/runs/results.jsonl"), ("v1c ctl", "spira_m8/v1c_ctl_data/runs/results.jsonl")]:
14
+ L = {x["window"]: x for x in map(json.loads, open(f"{S}/{f}"))}
15
+ s = L["seen"]; fr = [L[w]["fused_invocab_pct"] for w in FRESH]
16
+ rows.append(dict(run=name, famille="M8 trainer-eval n=4000", src=f, src_sha=fsha(f"{S}/{f}"),
17
+ train_bytes=s["read"]["data_bytes"], train_sha=s["data_sha256"], snn_bytes=s["read"]["snn_bytes_read"],
18
+ snn_ticks=s["snn_tokens"], am_ticks=s["am_tokens"], epochs=s["epochs"], n_state=s["n_state"],
19
+ seen=s["fused_invocab_pct"], fresh=dict(zip(FRESH, fr)), n_fresh=5, fresh_mean=sum(fr) / 5))
20
+ # famille broad (fermée) — eval_bench_v4 et variante de Checker, n=8000/20000
21
+ f = "checker/scale/results_v4.jsonl"; L = [json.loads(x) for x in open(f"{S}/{f}") if x.strip()]
22
+ corp = {"old_local_v1": "broad/old_local_v1/train.bin", "broad_local_v1": "broad/broad_local_v1/train.bin",
23
+ "corpus_v3": "corpus_v3/train.bin", "broad_gutenberg_v1": "broad/broad_gutenberg_v1/train.bin"}
24
+ snn_known = {"bg1_m8": 2211450} # checker/scale/cm_bg1d_m8.cov.json snn.bytes_covered
25
+ for tag in ["old_ref", "broad14_ref", "m8_broad14", "m8_v3", "bg1_m8"]:
26
+ W = {x["window"]: x for x in L if x["tag"] == tag}; x0 = W["seen"]; p = f"{S}/{corp[x0['corpus']]}"
27
+ fr = {w: W[w]["fused_invocab_pct"] for w in FRESH}; ok = [v for v in fr.values() if v is not None]
28
+ rows.append(dict(run=tag, famille=f"broad {x0['script'].replace('.', '_')} kind={x0['kind']}", src=f, src_sha=fsha(f"{S}/{f}"),
29
+ train_bytes=os.path.getsize(p), train_sha=sha(p), snn_bytes=snn_known.get(tag), seen=x0["fused_invocab_pct"],
30
+ n_seen=x0["n_positions"], fresh=fr, n_fresh=len(ok), fresh_mean=sum(ok) / len(ok)))
31
+ for r in rows: r["gap"] = r["seen"] - r["fresh_mean"]
32
+ # pente descriptive : points broad eval_bench, seen = fenêtre mémorisée (bg1 exclu : seen = tranche SNN 32)
33
+ pts = [(math.log10(r["train_bytes"]), r["gap"]) for r in rows if r["run"] in ("old_ref", "m8_broad14", "m8_v3")]
34
+ n = len(pts); mx = sum(a for a, _ in pts) / n; my = sum(b for _, b in pts) / n
35
+ sxx = sum((a - mx) ** 2 for a, _ in pts); b = sum((a - mx) * (c - my) for a, c in pts) / sxx
36
+ res = sum((c - my - b * (a - mx)) ** 2 for a, c in pts); se = math.sqrt(res / (n - 2) / sxx); t = 12.706 # t_0.975, ddl 1
37
+ slope = dict(points=["old_ref", "m8_broad14", "m8_v3"], x="log10(octets train)", n=n, slope_pt_per_decade=b, se=se,
38
+ ci95=[b - t * se, b + t * se], note="3 points, ddl=1, bras mélangés (plain/cm), indicatif seulement")
39
+ out = dict(rows=rows, slope=slope, v1d="non prédictible", peak_rss_kB=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)
40
+ json.dump(out, open("results.json", "w"), indent=1, ensure_ascii=False)
41
+ for r in rows: print(f"{r['run']:12} {r['train_bytes']:>11} {r['train_sha'][:8]} snn={r['snn_bytes']} seen={r['seen']:.3f} fresh={r['fresh_mean']:.3f} (n={r['n_fresh']}) gap={r['gap']:.3f}")
42
+ print(slope, out["peak_rss_kB"])
results/hashing/gap_vs_size/results.json ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "rows": [
3
+ {
4
+ "run": "v1b ctl",
5
+ "famille": "M8 trainer-eval n=4000",
6
+ "src": "hashing_gen/m8_v1b/runs/results.jsonl",
7
+ "src_sha": "5a7228343cf792b292d9b048f2f4df1867129d6deba8473bb79462f48ec732f8",
8
+ "train_bytes": 35128951,
9
+ "train_sha": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
10
+ "snn_bytes": 2791343,
11
+ "snn_ticks": 600000,
12
+ "am_ticks": 1200000,
13
+ "epochs": 2,
14
+ "n_state": 2560,
15
+ "seen": 98.44,
16
+ "fresh": {
17
+ "fc2": 4.684,
18
+ "fresh_en": 1.606,
19
+ "fresh_fr": 1.638,
20
+ "test20k": 1.256,
21
+ "test_v3": 0.875
22
+ },
23
+ "n_fresh": 5,
24
+ "fresh_mean": 2.0118,
25
+ "gap": 96.4282
26
+ },
27
+ {
28
+ "run": "v1c ctl",
29
+ "famille": "M8 trainer-eval n=4000",
30
+ "src": "spira_m8/v1c_ctl_data/runs/results.jsonl",
31
+ "src_sha": "6d6898f5dbdf643622cb03ea82ec60a311afa1f0d3b69df0bf0599b1927efb38",
32
+ "train_bytes": 35948296,
33
+ "train_sha": "3d8b6181cbffb27e360758267e1084197dccad82ae05b868691758e1cf72eed4",
34
+ "snn_bytes": 2706257,
35
+ "snn_ticks": 600000,
36
+ "am_ticks": 1200000,
37
+ "epochs": 2,
38
+ "n_state": 2560,
39
+ "seen": 93.183,
40
+ "fresh": {
41
+ "fc2": 7.852,
42
+ "fresh_en": 3.415,
43
+ "fresh_fr": 2.654,
44
+ "test20k": 3.343,
45
+ "test_v3": 2.731
46
+ },
47
+ "n_fresh": 5,
48
+ "fresh_mean": 3.999,
49
+ "gap": 89.18400000000001
50
+ },
51
+ {
52
+ "run": "old_ref",
53
+ "famille": "broad eval_bench_v4 kind=plain",
54
+ "src": "checker/scale/results_v4.jsonl",
55
+ "src_sha": "57a6c85bf9befc7bd9ab5053c0fdb67c63d6c5e23e6af168c7c41b220bcebac8",
56
+ "train_bytes": 12468350,
57
+ "train_sha": "e12b658625da3b7bacf84c68f82a7dbc53e196ccfdda0c7fc1d4ad46285ded54",
58
+ "snn_bytes": null,
59
+ "seen": 98.33,
60
+ "n_seen": 8000,
61
+ "fresh": {
62
+ "fc2": 11.504,
63
+ "fresh_en": 3.395,
64
+ "fresh_fr": 0.283,
65
+ "test20k": 2.9,
66
+ "test_v3": 4.117
67
+ },
68
+ "n_fresh": 5,
69
+ "fresh_mean": 4.4398,
70
+ "gap": 93.8902
71
+ },
72
+ {
73
+ "run": "broad14_ref",
74
+ "famille": "broad eval_bench_v4 kind=plain",
75
+ "src": "checker/scale/results_v4.jsonl",
76
+ "src_sha": "57a6c85bf9befc7bd9ab5053c0fdb67c63d6c5e23e6af168c7c41b220bcebac8",
77
+ "train_bytes": 34835257,
78
+ "train_sha": "eda07017a87f2b7bbd55c5c2ea23032bf70a38ae7ad75167523228738f2391a1",
79
+ "snn_bytes": null,
80
+ "seen": 91.934,
81
+ "n_seen": 8000,
82
+ "fresh": {
83
+ "fc2": 8.456,
84
+ "fresh_en": 5.167,
85
+ "fresh_fr": 2.717,
86
+ "test20k": null,
87
+ "test_v3": 2.804
88
+ },
89
+ "n_fresh": 4,
90
+ "fresh_mean": 4.786,
91
+ "gap": 87.148
92
+ },
93
+ {
94
+ "run": "m8_broad14",
95
+ "famille": "broad eval_bench_v4_1 kind=cm",
96
+ "src": "checker/scale/results_v4.jsonl",
97
+ "src_sha": "57a6c85bf9befc7bd9ab5053c0fdb67c63d6c5e23e6af168c7c41b220bcebac8",
98
+ "train_bytes": 34835257,
99
+ "train_sha": "eda07017a87f2b7bbd55c5c2ea23032bf70a38ae7ad75167523228738f2391a1",
100
+ "snn_bytes": null,
101
+ "seen": 91.819,
102
+ "n_seen": 8000,
103
+ "fresh": {
104
+ "fc2": 14.315,
105
+ "fresh_en": 5.105,
106
+ "fresh_fr": 3.054,
107
+ "test20k": null,
108
+ "test_v3": 3.3
109
+ },
110
+ "n_fresh": 4,
111
+ "fresh_mean": 6.4435,
112
+ "gap": 85.3755
113
+ },
114
+ {
115
+ "run": "m8_v3",
116
+ "famille": "broad eval_bench_v4_1 kind=cm",
117
+ "src": "checker/scale/results_v4.jsonl",
118
+ "src_sha": "57a6c85bf9befc7bd9ab5053c0fdb67c63d6c5e23e6af168c7c41b220bcebac8",
119
+ "train_bytes": 93284487,
120
+ "train_sha": "aabd912d1bce05d84122039e4f7e059f7bbb6bd6b448367b91bbf1e9fa75249c",
121
+ "snn_bytes": null,
122
+ "seen": 91.945,
123
+ "n_seen": 8000,
124
+ "fresh": {
125
+ "fc2": 14.451,
126
+ "fresh_en": 5.546,
127
+ "fresh_fr": 2.035,
128
+ "test20k": 3.555,
129
+ "test_v3": 3.276
130
+ },
131
+ "n_fresh": 5,
132
+ "fresh_mean": 5.7726,
133
+ "gap": 86.1724
134
+ },
135
+ {
136
+ "run": "bg1_m8",
137
+ "famille": "broad eval_bench_v4_1 kind=cm",
138
+ "src": "checker/scale/results_v4.jsonl",
139
+ "src_sha": "57a6c85bf9befc7bd9ab5053c0fdb67c63d6c5e23e6af168c7c41b220bcebac8",
140
+ "train_bytes": 290810502,
141
+ "train_sha": "5af6398fc853bce270e430f8336fc2b136318c2e762ead19e92f5d180de083f2",
142
+ "snn_bytes": 2211450,
143
+ "seen": 8.99,
144
+ "n_seen": 8000,
145
+ "fresh": {
146
+ "fc2": 13.507,
147
+ "fresh_en": 4.287,
148
+ "fresh_fr": 8.778,
149
+ "test20k": null,
150
+ "test_v3": 4.283
151
+ },
152
+ "n_fresh": 4,
153
+ "fresh_mean": 7.71375,
154
+ "gap": 1.27625
155
+ }
156
+ ],
157
+ "slope": {
158
+ "points": [
159
+ "old_ref",
160
+ "m8_broad14",
161
+ "m8_v3"
162
+ ],
163
+ "x": "log10(octets train)",
164
+ "n": 3,
165
+ "slope_pt_per_decade": -8.90395666592213,
166
+ "se": 6.042748616229554,
167
+ "ci95": [
168
+ -85.68312058373485,
169
+ 67.87520725189057
170
+ ],
171
+ "note": "3 points, ddl=1, bras mélangés (plain/cm), indicatif seulement"
172
+ },
173
+ "v1d": "non prédictible",
174
+ "peak_rss_kB": 17972
175
+ }
results/hashing/gen_copy_recount/code/copy_recount.py ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """SPIRA Hashing — recomptage INDÉPENDANT de la copie du train (claim Checker 25 oct. 00 h 06). Lecture seule.
3
+ Code écrit de zéro (n'importe rien de checker/). Pour chaque requête q (génération, ou contrôle held-out) :
4
+ m(i) = longueur du plus long préfixe de q[i:] présent dans le train (exact, si >= 16 ; sinon 0).
5
+ Méthode : fenêtres de 16 o de toutes les requêtes -> hash polynomial 64 bits (numpy) -> tableau trié ; train lu en
6
+ blocs de 2 Mio + chevauchement 256 o (> 200 = longueur max de requête + 16) ; chaque hit est VÉRIFIÉ par comparaison
7
+ octet à octet (LCP vectorisé), donc aucune fausse détection par collision.
8
+ cov>=k = part des octets de q couverts par un intervalle [i, i+m(i)) avec m(i) >= k (= union des k-fenêtres présentes).
9
+ Générations : checker/gen/samples/<tag>__<dec>__<p>.txt, partie après '\\n\\nGÉNÉRÉ:\\n', lue newline='' (octets exacts),
10
+ U+FFFD = octets perdus à l'écriture (decode 'replace') -> coupure ; dénominateurs : 'known' (octets connus, comme Checker)
11
+ et '200' (n_bytes publié, octets perdus comptés non couverts).
12
+ Contrôles held-out : (a) les 7 vraies continuations (cont_hex de prompts_v1.json) ; (b) 100 tranches de 200 o tirées
13
+ (seed 0) dans test.bin du corpus du modèle. Aucune donnée d'éval écrite en sortie (comptes et offsets seulement)."""
14
+ import os, sys, json, hashlib, time, resource
15
+ import numpy as np
16
+ S = "/workspace/spira_shared"; G = f"{S}/checker/gen"; OUTD = f"{S}/hashing_gen/gen_copy_recount/out"
17
+ MODELS = {"old_ref": ("old_local_v1", f"{S}/broad/old_local_v1"), "bg1_m8": ("broad_gutenberg_v1", f"{S}/broad/broad_gutenberg_v1")}
18
+ W, CH, OV, MAXQ = 16, 2 << 20, 256, 200
19
+ RSS_CAP_KB = 280 * 1024
20
+ BASE = np.uint64(1099511628211)
21
+ POW = [np.uint64(1)]
22
+ for _ in range(W - 1): POW.append(POW[-1] * BASE)
23
+ POW = POW[::-1] # coefficient de b[t] = BASE^(W-1-t)
24
+
25
+ def rss_kb():
26
+ for l in open("/proc/self/status"):
27
+ if l.startswith("VmRSS:"): return int(l.split()[1])
28
+ def guard():
29
+ r = rss_kb()
30
+ if r > RSS_CAP_KB: print("ABANDON RSS", r, "kB", flush=True); sys.exit(3)
31
+ return r
32
+ def fsha(p):
33
+ h = hashlib.sha256()
34
+ with open(p, "rb") as f:
35
+ for b in iter(lambda: f.read(4 << 20), b""): h.update(b)
36
+ return h.hexdigest()
37
+ def whash(a): # a: uint8 array ; renvoie hash des fenêtres a[j:j+W], j = 0..len-W
38
+ n = len(a) - W + 1
39
+ if n <= 0: return np.zeros(0, np.uint64)
40
+ h = np.zeros(n, np.uint64)
41
+ with np.errstate(over="ignore"):
42
+ for t in range(W): h += a[t:t + n].astype(np.uint64) * POW[t]
43
+ return h
44
+
45
+ def load_queries(tag, cname, cdir):
46
+ Q = [] # dict(kind, key, segs[list[bytes]], n_fffd, n_bytes_pub)
47
+ rows = [json.loads(l) for l in open(f"{G}/results_gen_v1.jsonl")]
48
+ for r in rows:
49
+ if r["tag"] != tag: continue
50
+ assert r["corpus"] == cname, (r["corpus"], cname)
51
+ fn = f"{G}/samples/{tag}__{r['decoding']}__{r['prompt']}.txt"
52
+ s = open(fn, encoding="utf-8", errors="strict", newline="").read()
53
+ parts = s.split("\n\nGÉNÉRÉ:\n")
54
+ assert len(parts) == 2 and s.endswith("\n"), fn
55
+ gt = parts[1][:-1]
56
+ Q.append({"kind": "gen_" + r["decoding"], "key": r["prompt"], "segs": [x.encode("utf-8") for x in gt.split("\ufffd")],
57
+ "n_fffd": gt.count("\ufffd"), "n_pub": r["n_bytes"], "pub_longest": r["longest_copy"],
58
+ "file_sha256": hashlib.sha256(open(fn, "rb").read()).hexdigest()})
59
+ for p in json.load(open(f"{G}/prompts_v1.json")):
60
+ cb = bytes.fromhex(p["cont_hex"])[:MAXQ]
61
+ Q.append({"kind": "heldout_cont", "key": p["name"], "segs": [cb], "n_fffd": 0, "n_pub": len(cb)})
62
+ tb = f"{cdir}/test.bin"; n = os.path.getsize(tb); rng = np.random.default_rng(0)
63
+ offs = sorted(int(x) for x in rng.integers(0, n - MAXQ, size=100))
64
+ with open(tb, "rb") as f:
65
+ for o in offs:
66
+ f.seek(o); Q.append({"kind": "heldout_test", "key": f"off{o}", "segs": [f.read(MAXQ)], "n_fffd": 0, "n_pub": MAXQ})
67
+ return Q
68
+
69
+ def scan(train_path, Q):
70
+ # tables des requêtes : concat de tous les segments, séparés (pas de fenêtre à cheval)
71
+ segs = [(qi, si, sb) for qi, q in enumerate(Q) for si, sb in enumerate(q["segs"])]
72
+ starts = []; hs = []; seglen = []
73
+ for k, (qi, si, sb) in enumerate(segs):
74
+ a = np.frombuffer(sb, np.uint8); h = whash(a)
75
+ 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))
76
+ seglen.append(len(sb))
77
+ H = np.concatenate(hs) if hs else np.zeros(0, np.uint64); P = np.concatenate(starts).astype(np.int64)
78
+ order = np.argsort(H, kind="stable"); H = H[order]; P = P[order]
79
+ Uh, ustart = np.unique(H, return_index=True); uend = np.append(ustart[1:], len(H))
80
+ # requête paddée (-1) en int16 pour LCP
81
+ QB = np.full((len(segs), MAXQ + 1), -1, np.int16)
82
+ for k, (_, _, sb) in enumerate(segs): QB[k, :len(sb)] = np.frombuffer(sb, np.uint8)
83
+ M = np.zeros((len(segs), MAXQ), np.int32); MOFF = np.full((len(segs), MAXQ), -1, np.int64)
84
+ nhits = 0; peak = 0; t0 = time.time(); nver = [0, 0]
85
+ with open(train_path, "rb") as f:
86
+ pos = 0; tail = b""
87
+ while True:
88
+ blk = f.read(CH); last = not blk or len(blk) < CH
89
+ if not blk and not tail: break
90
+ buf = tail + blk; base = pos - len(tail)
91
+ a = np.frombuffer(buf, np.uint8)
92
+ h = whash(a)
93
+ lim = len(h) if last else max(0, len(a) - OV) # débuts traités dans ce bloc
94
+ h = h[:lim]
95
+ idx = np.searchsorted(Uh, h); idx[idx >= len(Uh)] = 0
96
+ hit = np.nonzero(Uh[idx] == h)[0]
97
+ del h
98
+ if len(hit):
99
+ ap = np.append(a.astype(np.int16), np.full(MAXQ + 1, -2, np.int16)); d = np.arange(MAXQ + 1)
100
+ SL = np.asarray(seglen, np.int64)
101
+ for h0 in range(0, len(hit), 4000):
102
+ hh = hit[h0:h0 + 4000]; u = idx[hh]; cnt = uend[u] - ustart[u]
103
+ tp = np.repeat(hh, cnt)
104
+ qrow = np.repeat(ustart[u], cnt) + (np.arange(int(cnt.sum())) - np.repeat(np.cumsum(cnt) - cnt, cnt))
105
+ sk = P[qrow, 0]; si = P[qrow, 1]
106
+ keep = M[sk, si] < (SL[sk] - si) # position déjà saturée : inutile
107
+ tp, sk, si = tp[keep], sk[keep], si[keep]; nhits += len(tp)
108
+ for b0 in range(0, len(tp), 8000):
109
+ t_ = tp[b0:b0 + 8000]; k_ = sk[b0:b0 + 8000]; i_ = si[b0:b0 + 8000]
110
+ tb_ = ap[t_[:, None] + d[None, :]]
111
+ qb_ = QB[k_[:, None], np.minimum(i_[:, None] + d[None, :], MAXQ)]
112
+ lcp = np.argmin((tb_ == qb_) & (qb_ >= 0), axis=1).astype(np.int32)
113
+ del tb_, qb_
114
+ ok = lcp >= W; nver[0] += int(len(lcp)); nver[1] += int((~ok).sum())
115
+ lcp, key, off = lcp[ok], (k_ * MAXQ + i_)[ok], (base + t_)[ok]
116
+ o = np.argsort(lcp, kind="stable"); lcp, key, off = lcp[o], key[o], off[o]
117
+ better = lcp > M.reshape(-1)[key]
118
+ M.reshape(-1)[key[better]] = lcp[better]; MOFF.reshape(-1)[key[better]] = off[better]
119
+ del ap
120
+ peak = max(peak, guard())
121
+ pos += len(blk); tail = buf[-OV:] if not last else b""
122
+ if last: break
123
+ if (pos // CH) % 16 == 0: print(f" {pos/1e6:.0f} Mo, {time.time()-t0:.0f} s, hits {nhits}, rss {rss_kb()} kB", flush=True)
124
+ print(' vérifiés', nver[0], 'collisions rejetées', nver[1], flush=True)
125
+ return segs, seglen, M, MOFF, nhits, peak, pos
126
+
127
+ def summarize(Q, segs, seglen, M, MOFF):
128
+ for q in Q: q.update({"cov": {16: 0, 32: 0, 64: 0}, "longest": 0, "longest_train_off": -1, "known": 0})
129
+ for k, (qi, si, sb) in enumerate(segs):
130
+ q = Q[qi]; n = seglen[k]; q["known"] += n
131
+ for thr in (16, 32, 64):
132
+ c = np.zeros(n, bool)
133
+ for i in range(n):
134
+ L = int(M[k, i])
135
+ if L >= thr: c[i:i + L] = True
136
+ q["cov"][thr] += int(c.sum())
137
+ j = int(np.argmax(M[k, :n])) if n else 0
138
+ if n and M[k, j] > q["longest"]: q["longest"] = int(M[k, j]); q["longest_train_off"] = int(MOFF[k, j])
139
+ for q in Q:
140
+ q["cov_known"] = {t: q["cov"][t] / max(q["known"], 1) for t in q["cov"]}
141
+ q["cov_200"] = {t: q["cov"][t] / q["n_pub"] for t in q["cov"]}
142
+
143
+ def boot(x, B=10000, seed=0):
144
+ x = np.asarray(x, float); rng = np.random.default_rng(seed)
145
+ mm = x[rng.integers(0, len(x), (B, len(x)))].mean(1)
146
+ return [float(x.mean()), float(np.percentile(mm, 2.5)), float(np.percentile(mm, 97.5))]
147
+
148
+ def brute_check(train_path, Q, segs, M): # contrôle croisé exact (old_ref seulement : train entier en RAM, 12 Mo)
149
+ T = open(train_path, "rb").read(); bad = 0; n = 0
150
+ for k, (qi, si, sb) in enumerate(segs):
151
+ if not Q[qi]["kind"].startswith("gen"): continue
152
+ for i in range(len(sb)):
153
+ lo = 0
154
+ while i + lo < len(sb) and sb[i:i + lo + 1] in T: lo += 1
155
+ want = lo if lo >= W else 0; n += 1; bad += int(want != M[k, i])
156
+ del T; return {"positions": n, "mismatch": bad}
157
+
158
+ if __name__ == "__main__":
159
+ t00 = time.time(); res = {"script_sha256": hashlib.sha256(open(__file__, "rb").read()).hexdigest(), "models": {}}
160
+ for tag, (cname, cdir) in MODELS.items():
161
+ tp = f"{cdir}/train.bin"; man = None
162
+ Q = load_queries(tag, cname, cdir)
163
+ print(tag, "requêtes", len(Q), flush=True)
164
+ segs, seglen, M, MOFF, nhits, peak, nread = scan(tp, Q)
165
+ summarize(Q, segs, seglen, M, MOFF)
166
+ bc = brute_check(tp, Q, segs, M) if tag == "old_ref" else None
167
+ guard()
168
+ out = {"corpus": cname, "train": {"path": tp, "bytes": os.path.getsize(tp), "bytes_read": nread, "sha256": fsha(tp)},
169
+ "test_bin_sha256": fsha(f"{cdir}/test.bin"), "hits16": nhits, "peak_vmrss_kB_scan": peak, "brute_check": bc,
170
+ "per_query": [{k: v for k, v in q.items() if k != "segs"} for q in Q], "agg": {}}
171
+ for kind in ("gen_fused", "gen_v2b", "heldout_cont", "heldout_test"):
172
+ qs = [q for q in Q if q["kind"] == kind]; ag = {"n": len(qs)}
173
+ for den in ("cov_known", "cov_200"):
174
+ for t in (16, 32, 64): ag[f"{den}_{t}"] = boot([q[den][t] for q in qs])
175
+ ag["longest_max"] = max(q["longest"] for q in qs); ag["longest_mean"] = float(np.mean([q["longest"] for q in qs]))
176
+ p5 = [q for q in qs if q["key"] in ("en1", "en2", "fr1", "fr2", "code")]
177
+ if kind.startswith("gen"): ag["cov_known_32_P5_mean"] = float(np.mean([q["cov_known"][32] for q in p5]))
178
+ out["agg"][kind] = ag
179
+ res["models"][tag] = out
180
+ print(tag, json.dumps(out["agg"], indent=None)[:3000], "brute", bc, flush=True)
181
+ del Q, segs, M, MOFF
182
+ res["elapsed_s"] = round(time.time() - t00, 1); res["ru_maxrss_kB_self"] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
183
+ json.dump(res, open(f"{OUTD}/copy_recount.json", "w"), indent=1, ensure_ascii=False)
184
+ print("FINI", res["elapsed_s"], "s", flush=True)
results/hashing/gen_copy_recount/code/run_wrapped.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Wrapper parent : lance le script en enfant (nice 10, OMP=1, PYTHONHASHSEED=0), mesure le pic RSS de l'enfant via wait4/getrusage."""
3
+ import os, sys, subprocess, json, time
4
+ D = os.path.dirname(os.path.abspath(__file__)); OUT = os.path.join(D, "..", "out")
5
+ env = dict(os.environ, OMP_NUM_THREADS="1", OPENBLAS_NUM_THREADS="1", MKL_NUM_THREADS="1", PYTHONHASHSEED="0", TMPDIR=os.path.abspath(OUT))
6
+ t0 = time.time()
7
+ with open(os.path.join(OUT, "copy_recount.log"), "w") as lg:
8
+ p = subprocess.Popen(["nice", "-n", "10", sys.executable, os.path.join(D, "copy_recount.py")], stdout=lg, stderr=subprocess.STDOUT, env=env)
9
+ _, status, ru = os.wait4(p.pid, 0)
10
+ r = {"exit_status": os.waitstatus_to_exitcode(status), "child_peak_rss_kB_getrusage": ru.ru_maxrss, "elapsed_s": round(time.time() - t0, 1)}
11
+ json.dump(r, open(os.path.join(OUT, "copy_recount.mem.json"), "w")); print(r)
results/hashing/gen_copy_recount/relay_entry.md ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ ## 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)
3
+
4
+ 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).
5
+
6
+ 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.
7
+
8
+ Corpus vérifiés (jobs_v4.tsv, colonne corpus du jsonl, meta.train_bytes des ckpt) :
9
+ - old_ref → old_local_v1/train.bin, 12 468 350 o (sha e12b6586…) ;
10
+ - bg1_m8 → broad_gutenberg_v1/train.bin, 290 810 502 o (sha 5af6398f…).
11
+
12
+ 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.
13
+
14
+ v2b, 7 générations, moyenne [IC95 bootstrap, 10 000 tirages, seed 0] :
15
+ - 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 %.
16
+ - 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 %.
17
+
18
+ Fused :
19
+ - old_ref : cov≥32 = 27,3 % [8,8 ; 47,8], max 123 o ;
20
+ - bg1_m8 : cov≥32 = 56,5 % [26,5 ; 83,2], max 189 o.
21
+
22
+ Témoin held-out (comptes seulement) :
23
+ - 7 vraies continuations : cov≥32 = 2,3 % [0 ; 6,9], max 32 o (les deux modèles).
24
+ - 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.
25
+
26
+ Comparaison avec Checker, par génération (28) :
27
+ - longest_copy, cov≥32, octets connus et offset : **IDENTIQUES** sur 25/28.
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**.
29
+ - 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.
30
+ - 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**.
31
+ - Plus longue copie 196 o : **IDENTIQUE**.
32
+
33
+ Verdict : la copie du train en v2b est **CONFIRMÉE**. Le témoin held-out est à 2–9 %, contre environ 84 % pour v2b.
34
+
35
+ Réserves :
36
+ - n = 7 par modèle, donc des IC larges.
37
+ - old_ref v2b/fr1 donne 88 contre 89 publié : l'octet perdu au U+FFFD ne peut pas être reconstruit depuis les samples.
38
+ - 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).
39
+
40
+ Lu/appliqué — SPIRA Hashing
results/hashing/gen_kit_check_r1/REPORT.md ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # gen_kit_check_r1 — kit de test de génération : figé et caviardé (contrôle statique, test NON lancé)
2
+ Aucun texte de prompt n'est cité ici, ni dans gen_kit_check_result.json.
3
+
4
+ ## Figé : PASS
5
+ | objet | sha attendu | sha mesuré |
6
+ |---|---|---|
7
+ | PREDECL_gen_test_runC_r1.md | e451dfc7 | e451dfc7 |
8
+ | gen_kit_r2_result.json | 026dc89f | 026dc89f (gen_test_kit_r2/SHA256SUMS -c OK) |
9
+ | gen_prompts.py | 57fed6cb | 57fed6cb |
10
+ | gen_prompts_manifest.json | 70acee7b | 70acee7b |
11
+ | NEVER_PUSH/prompts_and_cont.bin | ca47ea80 | ca47ea80 |
12
+
13
+ - 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.
14
+ - gen_test/SHA256SUMS (23 lignes) : -c OK.
15
+
16
+ ## Caviardé : PASS sur le périmètre demandé
17
+ - Méthode : gen_kit_check_v2.py, PID 1171344, nice 19, 434,3 s, maxrss 39,9 Mo.
18
+ - 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.
19
+ - Pour chaque fichier : recherche des 200 o exacts et des 169 sous-chaînes de 32 o, pour chaque prompt et chaque continuation.
20
+ - Hors périmètre : NEVER_PUSH*, broad/, binaires .bin/.npz/.npy, venv.
21
+ - Relais, rapports, hf_ready, web/public : **0 hit**.
22
+ - 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.
23
+ - 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 :
24
+ - test_v3 : 200 o exacts dans corpus_v3/raw/pg1184.txt, prompt et continuation ;
25
+ - fresh_en : 107/169 et 96/169 dans pg5200.txt et metamorphosis.txt ;
26
+ - test20k_old : 107/169 et 97/169 dans frankenstein.txt et pg84.txt ;
27
+ - quelques sous-chaînes isolées (1 à 7) dans d'autres livres.
28
+ - **Fait nouveau** : fresh_en recoupe un texte Gutenberg ancien (Metamorphosis). « fresh » ne veut donc pas dire « postérieur ».
29
+
30
+ ## Erreurs de ma part
31
+ - 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.
32
+ - Un 1er lancement de la v2 a échoué (SyntaxError) avant tout calcul.
33
+ - py_compile a créé un __pycache__ dans mon dossier ; je l'ai supprimé.
results/hashing/gen_kit_check_r1/SHA256SUMS ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ e0ebfd9292c4191d0957704da14db58e7ab7b3514a54c837005e9c2809d8014c gen_kit_check_v2.py
2
+ 017d085a748e1e984c0490172abd813203906a6647b9c3396373b47d1549aa48 gen_kit_check_result.json
3
+ d3cc43bf4e16b379cb341f655316b6eb9a728ca44d6070dbbdcc03e5e2ca1499 run.log
4
+ e65221b52abfed9b13b56ac3a8498f52fc0e5ecaca0c93b155c2baedc231ee1a REPORT.md
results/hashing/gen_kit_check_r1/SHA256SUMS_v3 ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ e0ebfd9292c4191d0957704da14db58e7ab7b3514a54c837005e9c2809d8014c gen_kit_check_v2.py
2
+ e01d2f2a2110a2d8803cf8f74cb5d978bc63b7a9fd602ec20177b1e3a4fda42b gen_kit_check_v3.py
3
+ 79be901c5fa010885b4d2f88a357cf16e89f1f3d4b1b88b7612423feb70cec2d gen_kit_check_v3b.py
4
+ da94f7ae45b171d7a366fa5bf2154b62ebd58fd53576201966a9c11427750a2c gen_kit_check_v3_result.json
5
+ c1b083d49a82ffbf880a81f945ab88a9d71896b5a140071007aaa61a51286f4d run_v3.log
6
+ 898a0d9be827c190615c82241f6e5550875bd8293ef61597b74b5a87a5fb7327 selftest_v3.sh
7
+ bc6a8f1e930501b240e1f7f5a5156deb54d678893bacb4d96c7e879a5e2921d4 selftest_v3_result.txt
results/hashing/gen_kit_check_r1/SHA256SUMS_v3b_20261031 ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ e0ebfd9292c4191d0957704da14db58e7ab7b3514a54c837005e9c2809d8014c gen_kit_check_v2.py
2
+ e01d2f2a2110a2d8803cf8f74cb5d978bc63b7a9fd602ec20177b1e3a4fda42b gen_kit_check_v3.py
3
+ 79be901c5fa010885b4d2f88a357cf16e89f1f3d4b1b88b7612423feb70cec2d gen_kit_check_v3b.py
4
+ da94f7ae45b171d7a366fa5bf2154b62ebd58fd53576201966a9c11427750a2c gen_kit_check_v3_result.json
5
+ c1b083d49a82ffbf880a81f945ab88a9d71896b5a140071007aaa61a51286f4d run_v3.log
6
+ 898a0d9be827c190615c82241f6e5550875bd8293ef61597b74b5a87a5fb7327 selftest_v3.sh
7
+ bc6a8f1e930501b240e1f7f5a5156deb54d678893bacb4d96c7e879a5e2921d4 selftest_v3_result.txt
results/hashing/gen_kit_check_r1/gen_kit_check_result.json ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "sha": {
3
+ "gen_prompts.py": "57fed6cb540f5fb1c91f23a62d96a5c9c9587030e60bf9b4685eede5438ac029",
4
+ "gen_prompts_manifest.json": "70acee7babde01f77e53d3691c40d4cafae3e55c3d7043e1966de36a9320c2d9",
5
+ "NEVER_PUSH/prompts_and_cont.bin": "ca47ea802b09312c1419563a28fe1e2ccab13df1511bf339c8008183dce47902",
6
+ "checker/recount/runC_ready/PREDECL_gen_test_runC_r1.md": "e451dfc7978bd92ada40b45e7c4efc94776555722e2b42a47b74fb1db5dfa66a",
7
+ "checker/recount/runC_ready/gen_test_kit_r2/gen_kit_r2_result.json": "026dc89f20c58833790ffca86b74572f12f933e7cb2145f703b12649e99aeb9d"
8
+ },
9
+ "items": [
10
+ {
11
+ "window": "fc2",
12
+ "window_sha_ok": true,
13
+ "prompt_sha_ok": true,
14
+ "cont_sha_ok": true,
15
+ "prompt_sha": "faf784ed0e85331ff8db7cb0caf356543ed1c3e02134a76429677347d4167192"
16
+ },
17
+ {
18
+ "window": "fresh_en",
19
+ "window_sha_ok": true,
20
+ "prompt_sha_ok": true,
21
+ "cont_sha_ok": true,
22
+ "prompt_sha": "54cdebf119f3f390226922515f3ebce66cc549062caeb2ed3df6ffee7babfa16"
23
+ },
24
+ {
25
+ "window": "fresh_fr",
26
+ "window_sha_ok": true,
27
+ "prompt_sha_ok": true,
28
+ "cont_sha_ok": true,
29
+ "prompt_sha": "90d5ab55d2729276b0eb6084625a1ef7ab9bb6fe7e282f34f71672798927942f"
30
+ },
31
+ {
32
+ "window": "test20k_old",
33
+ "window_sha_ok": true,
34
+ "prompt_sha_ok": true,
35
+ "cont_sha_ok": true,
36
+ "prompt_sha": "01f4169450cd9eaf617e1f7c2f5d6f1c07f58f255ac6df1ab35791cd4d8f50ec"
37
+ },
38
+ {
39
+ "window": "test_v3",
40
+ "window_sha_ok": true,
41
+ "prompt_sha_ok": true,
42
+ "cont_sha_ok": true,
43
+ "prompt_sha": "b97f1cf219ca6cf62798e6c1df03a4dd5ff7bd01c015e9202e66aa9fcbcc99e1"
44
+ }
45
+ ],
46
+ "fichiers_scannes": 55386,
47
+ "octets_scannes": 947372343,
48
+ "ignores_gt20Mo": [
49
+ [
50
+ "/workspace/spira_shared/checker/recount/diverse_dedup_1509/sha_manifest_corpora_FULL_LOCAL.json",
51
+ 44891889
52
+ ],
53
+ [
54
+ "/workspace/spira_shared/corpus_gutenberg_v2/pg_catalog.csv",
55
+ 21263721
56
+ ],
57
+ [
58
+ "/workspace/SPIRA/web/public/spira_deploy.json",
59
+ 29063956
60
+ ]
61
+ ],
62
+ "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",
63
+ "hits": [
64
+ {
65
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg1184.txt",
66
+ "window": "test_v3",
67
+ "seg": "prompt",
68
+ "full200": true,
69
+ "sub32_hits_sur_169": 169
70
+ },
71
+ {
72
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg1184.txt",
73
+ "window": "test_v3",
74
+ "seg": "cont",
75
+ "full200": true,
76
+ "sub32_hits_sur_169": 169
77
+ },
78
+ {
79
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg5200.txt",
80
+ "window": "fresh_en",
81
+ "seg": "prompt",
82
+ "full200": false,
83
+ "sub32_hits_sur_169": 107
84
+ },
85
+ {
86
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg5200.txt",
87
+ "window": "fresh_en",
88
+ "seg": "cont",
89
+ "full200": false,
90
+ "sub32_hits_sur_169": 96
91
+ },
92
+ {
93
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/frankenstein.txt",
94
+ "window": "test20k_old",
95
+ "seg": "prompt",
96
+ "full200": false,
97
+ "sub32_hits_sur_169": 107
98
+ },
99
+ {
100
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/frankenstein.txt",
101
+ "window": "test20k_old",
102
+ "seg": "cont",
103
+ "full200": false,
104
+ "sub32_hits_sur_169": 97
105
+ },
106
+ {
107
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/metamorphosis.txt",
108
+ "window": "fresh_en",
109
+ "seg": "prompt",
110
+ "full200": false,
111
+ "sub32_hits_sur_169": 107
112
+ },
113
+ {
114
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/metamorphosis.txt",
115
+ "window": "fresh_en",
116
+ "seg": "cont",
117
+ "full200": false,
118
+ "sub32_hits_sur_169": 96
119
+ },
120
+ {
121
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg83.txt",
122
+ "window": "test_v3",
123
+ "seg": "prompt",
124
+ "full200": false,
125
+ "sub32_hits_sur_169": 2
126
+ },
127
+ {
128
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg203.txt",
129
+ "window": "test_v3",
130
+ "seg": "prompt",
131
+ "full200": false,
132
+ "sub32_hits_sur_169": 6
133
+ },
134
+ {
135
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg200.txt",
136
+ "window": "fresh_en",
137
+ "seg": "cont",
138
+ "full200": false,
139
+ "sub32_hits_sur_169": 3
140
+ },
141
+ {
142
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg90.txt",
143
+ "window": "test_v3",
144
+ "seg": "cont",
145
+ "full200": false,
146
+ "sub32_hits_sur_169": 1
147
+ },
148
+ {
149
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg82.txt",
150
+ "window": "test_v3",
151
+ "seg": "prompt",
152
+ "full200": false,
153
+ "sub32_hits_sur_169": 6
154
+ },
155
+ {
156
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg415.txt",
157
+ "window": "test_v3",
158
+ "seg": "prompt",
159
+ "full200": false,
160
+ "sub32_hits_sur_169": 2
161
+ },
162
+ {
163
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg84.txt",
164
+ "window": "test20k_old",
165
+ "seg": "prompt",
166
+ "full200": false,
167
+ "sub32_hits_sur_169": 107
168
+ },
169
+ {
170
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg84.txt",
171
+ "window": "test20k_old",
172
+ "seg": "cont",
173
+ "full200": false,
174
+ "sub32_hits_sur_169": 97
175
+ },
176
+ {
177
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg308.txt",
178
+ "window": "test_v3",
179
+ "seg": "cont",
180
+ "full200": false,
181
+ "sub32_hits_sur_169": 2
182
+ },
183
+ {
184
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg344.txt",
185
+ "window": "test_v3",
186
+ "seg": "cont",
187
+ "full200": false,
188
+ "sub32_hits_sur_169": 2
189
+ },
190
+ {
191
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg164.txt",
192
+ "window": "test_v3",
193
+ "seg": "cont",
194
+ "full200": false,
195
+ "sub32_hits_sur_169": 7
196
+ }
197
+ ],
198
+ "secondes": 434.3,
199
+ "maxrss_Mo": 39.91015625
200
+ }
results/hashing/gen_kit_check_r1/gen_kit_check_v2.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Vérif statique du kit de génération (figé + caviardé). N'affiche ni n'écrit aucun texte de prompt : seulement chemins, sha, compteurs."""
2
+ import os, json, hashlib, time, resource
3
+ T0 = time.perf_counter(); S = "/workspace/spira_shared/"; G = S + "checker/recount/gen_test/"
4
+ sha = lambda b: hashlib.sha256(b).hexdigest()
5
+ man = json.load(open(G + "gen_prompts_manifest.json")); R = {"sha": {}, "items": []}
6
+ 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())
7
+ 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())
8
+ P = []
9
+ for it in man["items"]:
10
+ w = open(S + it["path"], "rb").read(); p = w[it["start"]:it["start"] + 200]; c = w[it["start"] + 200:it["start"] + 400]
11
+ 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"]})
12
+ P.append((it["window"], p, c))
13
+ 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")
14
+ roots = [S, "/workspace/SPIRA/web/public"]; hits = []; n = 0; skipped = []; nbytes = 0
15
+ for root in roots:
16
+ for dp, dn, fn in os.walk(root):
17
+ dn[:] = [d for d in dn if not d.startswith(EXCL_DIR) and d not in ("broad", "__pycache__", ".git")]
18
+ for f in fn:
19
+ fp = os.path.join(dp, f)
20
+ if "site-packages" in fp or "/venv" in fp or "/.venv" in fp: continue
21
+ if not (f.endswith(TXT) or "hf_ready" in fp or root != S or f == "spira_relay.md"): continue
22
+ try: sz = os.path.getsize(fp)
23
+ except OSError: continue
24
+ if sz > 20 << 20: skipped.append([fp, sz]); continue
25
+ b = open(fp, "rb").read(); n += 1; nbytes += sz
26
+ for wname, p, c in P:
27
+ for kind, t in (("prompt", p), ("cont", c)):
28
+ full = t in b; k32 = sum(1 for i in range(0, 169) if t[i:i + 32] in b)
29
+ if full or k32: hits.append({"file": fp, "window": wname, "seg": kind, "full200": full, "sub32_hits_sur_169": k32})
30
+ 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})
31
+ json.dump(R, open(os.path.dirname(os.path.abspath(__file__)) + "/gen_kit_check_result.json", "w"), indent=1)
32
+ print(n, len(hits), len(skipped), R["secondes"])
results/hashing/gen_kit_check_r1/gen_kit_check_v3.py ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """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).
3
+ N'affiche ni n'écrit aucun texte de prompt : seulement chemins, sha, compteurs. v2 (e0ebfd92) inchangé.
4
+ rc : 0 = PASS ; 3 = FAIL ; 2 = analyse impossible.
5
+ Règles :
6
+ - 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.
7
+ - 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 ;
8
+ un hit est TOLÉRÉ seulement sous un préfixe de corpus source déclaré (--source-prefix) ; tout autre hit → FAIL.
9
+ - périmètre : fichiers texte (TXT) + tout fichier sous hf_ready ou sous une racine publique (--public-root) ; EXCL_SUFFIX appliqué partout
10
+ 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.
11
+ Limite déclarée : broad/ et /tmp ne sont pas lus."""
12
+ import os, sys, json, hashlib, time, resource, argparse
13
+ T0 = time.perf_counter(); sha = lambda b: hashlib.sha256(b).hexdigest()
14
+ S = "/workspace/spira_shared/"; G = S + "checker/recount/gen_test/"
15
+ ap = argparse.ArgumentParser()
16
+ ap.add_argument("--data-root", default=S)
17
+ ap.add_argument("--manifest", default=G + "gen_prompts_manifest.json")
18
+ ap.add_argument("--expect", default=json.dumps({
19
+ G + "gen_prompts.py": "57fed6cb540f5fb1c91f23a62d96a5c9c9587030e60bf9b4685eede5438ac029",
20
+ G + "gen_prompts_manifest.json": "70acee7babde01f77e53d3691c40d4cafae3e55c3d7043e1966de36a9320c2d9",
21
+ G + "NEVER_PUSH/prompts_and_cont.bin": "ca47ea802b09312c1419563a28fe1e2ccab13df1511bf339c8008183dce47902",
22
+ S + "checker/recount/runC_ready/PREDECL_gen_test_runC_r1.md": "e451dfc7978bd92ada40b45e7c4efc94776555722e2b42a47b74fb1db5dfa66a",
23
+ S + "checker/recount/runC_ready/gen_test_kit_r2/gen_kit_r2_result.json": "026dc89f20c58833790ffca86b74572f12f933e7cb2145f703b12649e99aeb9d"}))
24
+ ap.add_argument("--blob", default=G + "NEVER_PUSH/prompts_and_cont.bin")
25
+ ap.add_argument("--n-items", type=int, default=5)
26
+ ap.add_argument("--scan-root", action="append")
27
+ ap.add_argument("--public-root", action="append")
28
+ ap.add_argument("--source-prefix", action="append")
29
+ ap.add_argument("--out", required=True)
30
+ a = ap.parse_args()
31
+ scan_roots = a.scan_root or [S]; pub_roots = a.public_root or ["/workspace/SPIRA/web/public"]
32
+ src_pfx = a.source_prefix or [S + "corpus_v3/raw/", S + "corpus_gutenberg/", S + "corpus_gutenberg_v2/raw/"]
33
+ TXT = (".md", ".json", ".txt", ".log", ".csv", ".diff", ".py", ".sh", ".yaml", ".yml", ".html")
34
+ EXCL_SUFFIX = (".bin", ".npz", ".npy", ".pt", ".ckpt", ".safetensors", ".lock")
35
+ SKIP_DIR = ("NEVER_PUSH", "broad", ".git", "__pycache__", "venv", ".venv", "site-packages")
36
+ R = {"version": "v3", "rc": 2, "verdict": None, "erreur": None}
37
+ def fin(rc, err=None):
38
+ R["rc"] = rc; R["erreur"] = err; R["verdict"] = {0: "PASS", 3: "FAIL"}.get(rc, "ANALYSE IMPOSSIBLE")
39
+ R["secondes"] = round(time.perf_counter() - T0, 1); R["maxrss_Mo"] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024
40
+ try: json.dump(R, open(a.out, "w"), indent=1)
41
+ except Exception as e: print("sortie impossible", e, file=sys.stderr); sys.exit(2)
42
+ 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)
43
+ try:
44
+ exp = json.loads(a.expect); man = json.load(open(a.manifest)); blob = open(a.blob, "rb").read()
45
+ except Exception as e: fin(2, f"lecture impossible : {e}")
46
+ fails = []
47
+ R["kit_sha"] = {}
48
+ for f, e in exp.items():
49
+ try: h = sha(open(f, "rb").read())
50
+ except Exception as x: fin(2, f"fichier du kit absent : {f}")
51
+ ok = h.startswith(e); R["kit_sha"][f] = {"sha": h, "attendu": e, "ok": ok}
52
+ if not ok: fails.append("kit_sha:" + f)
53
+ if man.get("blob_sha256") != sha(blob): fails.append("blob_sha_manifeste")
54
+ items = man.get("items", [])
55
+ if len(items) != a.n_items: fails.append(f"n_items {len(items)}≠{a.n_items}")
56
+ P = []; R["items"] = []
57
+ for it in items:
58
+ try: w = open(os.path.join(a.data_root, it["path"]), "rb").read()
59
+ except Exception: fin(2, f"fenêtre absente : {it.get('path')}")
60
+ s0 = it["start"]; p = w[s0:s0 + 200]; c = w[s0 + 200:s0 + 400]
61
+ 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}
62
+ R["items"].append(d)
63
+ for k in ("window_sha_ok", "prompt_sha_ok", "cont_sha_ok", "prompt_len_ok"):
64
+ if not d[k]: fails.append(f"{it['window']}:{k}")
65
+ P.append((it["window"], p, c))
66
+ hits = []; n = 0; nb = 0; skipped = []
67
+ for root in scan_roots + pub_roots:
68
+ pub = root in pub_roots
69
+ for dp, dn, fn in os.walk(root):
70
+ dn[:] = [x for x in dn if not x.startswith(SKIP_DIR) and x not in SKIP_DIR]
71
+ for f in fn:
72
+ fp = os.path.join(dp, f); forced = pub or "hf_ready" in fp
73
+ if fp.startswith("/tmp/"): continue
74
+ if not forced and (f.endswith(EXCL_SUFFIX) or not (f.endswith(TXT) or f == "spira_relay.md")): continue
75
+ try: b = open(fp, "rb").read()
76
+ except Exception as e: skipped.append([fp, str(e)[:80]]); continue
77
+ n += 1; nb += len(b)
78
+ for wn, p, c in P:
79
+ for kind, t in (("prompt", p), ("cont", c)):
80
+ full = t in b; k32 = sum(1 for i in range(169) if t[i:i + 32] in b)
81
+ 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)})
82
+ bad = [h for h in hits if not h["source_toleree"]]
83
+ 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},
84
+ "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})
85
+ if bad: fails.append(f"caviardage: {len(bad)} hit(s) hors source")
86
+ if skipped: fails.append(f"{len(skipped)} fichier(s) illisible(s)")
87
+ R["fails"] = fails
88
+ fin(3 if fails else 0)
results/hashing/gen_kit_check_r1/gen_kit_check_v3_result.json ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": "v3",
3
+ "rc": 0,
4
+ "verdict": "PASS",
5
+ "erreur": null,
6
+ "kit_sha": {
7
+ "/workspace/spira_shared/checker/recount/gen_test/gen_prompts.py": {
8
+ "sha": "57fed6cb540f5fb1c91f23a62d96a5c9c9587030e60bf9b4685eede5438ac029",
9
+ "attendu": "57fed6cb540f5fb1c91f23a62d96a5c9c9587030e60bf9b4685eede5438ac029",
10
+ "ok": true
11
+ },
12
+ "/workspace/spira_shared/checker/recount/gen_test/gen_prompts_manifest.json": {
13
+ "sha": "70acee7babde01f77e53d3691c40d4cafae3e55c3d7043e1966de36a9320c2d9",
14
+ "attendu": "70acee7babde01f77e53d3691c40d4cafae3e55c3d7043e1966de36a9320c2d9",
15
+ "ok": true
16
+ },
17
+ "/workspace/spira_shared/checker/recount/gen_test/NEVER_PUSH/prompts_and_cont.bin": {
18
+ "sha": "ca47ea802b09312c1419563a28fe1e2ccab13df1511bf339c8008183dce47902",
19
+ "attendu": "ca47ea802b09312c1419563a28fe1e2ccab13df1511bf339c8008183dce47902",
20
+ "ok": true
21
+ },
22
+ "/workspace/spira_shared/checker/recount/runC_ready/PREDECL_gen_test_runC_r1.md": {
23
+ "sha": "e451dfc7978bd92ada40b45e7c4efc94776555722e2b42a47b74fb1db5dfa66a",
24
+ "attendu": "e451dfc7978bd92ada40b45e7c4efc94776555722e2b42a47b74fb1db5dfa66a",
25
+ "ok": true
26
+ },
27
+ "/workspace/spira_shared/checker/recount/runC_ready/gen_test_kit_r2/gen_kit_r2_result.json": {
28
+ "sha": "026dc89f20c58833790ffca86b74572f12f933e7cb2145f703b12649e99aeb9d",
29
+ "attendu": "026dc89f20c58833790ffca86b74572f12f933e7cb2145f703b12649e99aeb9d",
30
+ "ok": true
31
+ }
32
+ },
33
+ "items": [
34
+ {
35
+ "window": "fc2",
36
+ "window_sha_ok": true,
37
+ "prompt_sha_ok": true,
38
+ "cont_sha_ok": true,
39
+ "prompt_len_ok": true
40
+ },
41
+ {
42
+ "window": "fresh_en",
43
+ "window_sha_ok": true,
44
+ "prompt_sha_ok": true,
45
+ "cont_sha_ok": true,
46
+ "prompt_len_ok": true
47
+ },
48
+ {
49
+ "window": "fresh_fr",
50
+ "window_sha_ok": true,
51
+ "prompt_sha_ok": true,
52
+ "cont_sha_ok": true,
53
+ "prompt_len_ok": true
54
+ },
55
+ {
56
+ "window": "test20k_old",
57
+ "window_sha_ok": true,
58
+ "prompt_sha_ok": true,
59
+ "cont_sha_ok": true,
60
+ "prompt_len_ok": true
61
+ },
62
+ {
63
+ "window": "test_v3",
64
+ "window_sha_ok": true,
65
+ "prompt_sha_ok": true,
66
+ "cont_sha_ok": true,
67
+ "prompt_len_ok": true
68
+ }
69
+ ],
70
+ "perimetre": {
71
+ "scan_roots": [
72
+ "/workspace/spira_shared/"
73
+ ],
74
+ "public_roots": [
75
+ "/workspace/SPIRA/web/public"
76
+ ],
77
+ "source_prefixes": [
78
+ "/workspace/spira_shared/corpus_v3/raw/",
79
+ "/workspace/spira_shared/corpus_gutenberg/",
80
+ "/workspace/spira_shared/corpus_gutenberg_v2/raw/"
81
+ ],
82
+ "TXT": [
83
+ ".md",
84
+ ".json",
85
+ ".txt",
86
+ ".log",
87
+ ".csv",
88
+ ".diff",
89
+ ".py",
90
+ ".sh",
91
+ ".yaml",
92
+ ".yml",
93
+ ".html"
94
+ ],
95
+ "EXCL_SUFFIX": [
96
+ ".bin",
97
+ ".npz",
98
+ ".npy",
99
+ ".pt",
100
+ ".ckpt",
101
+ ".safetensors",
102
+ ".lock"
103
+ ],
104
+ "SKIP_DIR": [
105
+ "NEVER_PUSH",
106
+ "broad",
107
+ ".git",
108
+ "__pycache__",
109
+ "venv",
110
+ ".venv",
111
+ "site-packages"
112
+ ]
113
+ },
114
+ "fichiers_scannes": 53727,
115
+ "octets_scannes": 1034296244,
116
+ "illisibles": [],
117
+ "hits": [
118
+ {
119
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg1184.txt",
120
+ "window": "test_v3",
121
+ "seg": "prompt",
122
+ "full200": true,
123
+ "sub32_sur_169": 169,
124
+ "source_toleree": true
125
+ },
126
+ {
127
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg1184.txt",
128
+ "window": "test_v3",
129
+ "seg": "cont",
130
+ "full200": true,
131
+ "sub32_sur_169": 169,
132
+ "source_toleree": true
133
+ },
134
+ {
135
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg5200.txt",
136
+ "window": "fresh_en",
137
+ "seg": "prompt",
138
+ "full200": false,
139
+ "sub32_sur_169": 107,
140
+ "source_toleree": true
141
+ },
142
+ {
143
+ "file": "/workspace/spira_shared/corpus_v3/raw/pg5200.txt",
144
+ "window": "fresh_en",
145
+ "seg": "cont",
146
+ "full200": false,
147
+ "sub32_sur_169": 96,
148
+ "source_toleree": true
149
+ },
150
+ {
151
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/frankenstein.txt",
152
+ "window": "test20k_old",
153
+ "seg": "prompt",
154
+ "full200": false,
155
+ "sub32_sur_169": 107,
156
+ "source_toleree": true
157
+ },
158
+ {
159
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/frankenstein.txt",
160
+ "window": "test20k_old",
161
+ "seg": "cont",
162
+ "full200": false,
163
+ "sub32_sur_169": 97,
164
+ "source_toleree": true
165
+ },
166
+ {
167
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/metamorphosis.txt",
168
+ "window": "fresh_en",
169
+ "seg": "prompt",
170
+ "full200": false,
171
+ "sub32_sur_169": 107,
172
+ "source_toleree": true
173
+ },
174
+ {
175
+ "file": "/workspace/spira_shared/corpus_gutenberg/corpus/books/metamorphosis.txt",
176
+ "window": "fresh_en",
177
+ "seg": "cont",
178
+ "full200": false,
179
+ "sub32_sur_169": 96,
180
+ "source_toleree": true
181
+ },
182
+ {
183
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg83.txt",
184
+ "window": "test_v3",
185
+ "seg": "prompt",
186
+ "full200": false,
187
+ "sub32_sur_169": 2,
188
+ "source_toleree": true
189
+ },
190
+ {
191
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg203.txt",
192
+ "window": "test_v3",
193
+ "seg": "prompt",
194
+ "full200": false,
195
+ "sub32_sur_169": 6,
196
+ "source_toleree": true
197
+ },
198
+ {
199
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg200.txt",
200
+ "window": "fresh_en",
201
+ "seg": "cont",
202
+ "full200": false,
203
+ "sub32_sur_169": 3,
204
+ "source_toleree": true
205
+ },
206
+ {
207
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg90.txt",
208
+ "window": "test_v3",
209
+ "seg": "cont",
210
+ "full200": false,
211
+ "sub32_sur_169": 1,
212
+ "source_toleree": true
213
+ },
214
+ {
215
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg82.txt",
216
+ "window": "test_v3",
217
+ "seg": "prompt",
218
+ "full200": false,
219
+ "sub32_sur_169": 6,
220
+ "source_toleree": true
221
+ },
222
+ {
223
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg415.txt",
224
+ "window": "test_v3",
225
+ "seg": "prompt",
226
+ "full200": false,
227
+ "sub32_sur_169": 2,
228
+ "source_toleree": true
229
+ },
230
+ {
231
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg84.txt",
232
+ "window": "test20k_old",
233
+ "seg": "prompt",
234
+ "full200": false,
235
+ "sub32_sur_169": 107,
236
+ "source_toleree": true
237
+ },
238
+ {
239
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg84.txt",
240
+ "window": "test20k_old",
241
+ "seg": "cont",
242
+ "full200": false,
243
+ "sub32_sur_169": 97,
244
+ "source_toleree": true
245
+ },
246
+ {
247
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg308.txt",
248
+ "window": "test_v3",
249
+ "seg": "cont",
250
+ "full200": false,
251
+ "sub32_sur_169": 2,
252
+ "source_toleree": true
253
+ },
254
+ {
255
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg344.txt",
256
+ "window": "test_v3",
257
+ "seg": "cont",
258
+ "full200": false,
259
+ "sub32_sur_169": 2,
260
+ "source_toleree": true
261
+ },
262
+ {
263
+ "file": "/workspace/spira_shared/corpus_gutenberg_v2/raw/pg164.txt",
264
+ "window": "test_v3",
265
+ "seg": "cont",
266
+ "full200": false,
267
+ "sub32_sur_169": 7,
268
+ "source_toleree": true
269
+ }
270
+ ],
271
+ "n_hits_source": 19,
272
+ "n_hits_hors_source": 0,
273
+ "fails_fige": [],
274
+ "fails": [],
275
+ "secondes": 432.9,
276
+ "maxrss_Mo": 77.12890625
277
+ }
results/hashing/gen_kit_check_r1/gen_kit_check_v3b.py ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """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).
3
+ N'affiche ni n'écrit aucun texte de prompt : seulement chemins, sha, compteurs. v2 (e0ebfd92) inchangé.
4
+ rc : 0 = PASS ; 3 = FAIL ; 2 = analyse impossible.
5
+ Règles :
6
+ - 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.
7
+ - 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 ;
8
+ un hit est TOLÉRÉ seulement sous un préfixe de corpus source déclaré (--source-prefix) ; tout autre hit → FAIL.
9
+ - périmètre : fichiers texte (TXT) + tout fichier sous hf_ready ou sous une racine publique (--public-root) ; EXCL_SUFFIX N'EST PAS appliqué
10
+ 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.
11
+ Limite déclarée : broad/ et /tmp ne sont pas lus."""
12
+ import os, sys, json, hashlib, time, resource, argparse
13
+ T0 = time.perf_counter(); sha = lambda b: hashlib.sha256(b).hexdigest()
14
+ S = "/workspace/spira_shared/"; G = S + "checker/recount/gen_test/"
15
+ ap = argparse.ArgumentParser()
16
+ ap.add_argument("--data-root", default=S)
17
+ ap.add_argument("--manifest", default=G + "gen_prompts_manifest.json")
18
+ ap.add_argument("--expect", default=json.dumps({
19
+ G + "gen_prompts.py": "57fed6cb540f5fb1c91f23a62d96a5c9c9587030e60bf9b4685eede5438ac029",
20
+ G + "gen_prompts_manifest.json": "70acee7babde01f77e53d3691c40d4cafae3e55c3d7043e1966de36a9320c2d9",
21
+ G + "NEVER_PUSH/prompts_and_cont.bin": "ca47ea802b09312c1419563a28fe1e2ccab13df1511bf339c8008183dce47902",
22
+ S + "checker/recount/runC_ready/PREDECL_gen_test_runC_r1.md": "e451dfc7978bd92ada40b45e7c4efc94776555722e2b42a47b74fb1db5dfa66a",
23
+ S + "checker/recount/runC_ready/gen_test_kit_r2/gen_kit_r2_result.json": "026dc89f20c58833790ffca86b74572f12f933e7cb2145f703b12649e99aeb9d"}))
24
+ ap.add_argument("--blob", default=G + "NEVER_PUSH/prompts_and_cont.bin")
25
+ ap.add_argument("--n-items", type=int, default=5)
26
+ ap.add_argument("--scan-root", action="append")
27
+ ap.add_argument("--public-root", action="append")
28
+ ap.add_argument("--source-prefix", action="append")
29
+ ap.add_argument("--out", required=True)
30
+ a = ap.parse_args()
31
+ scan_roots = a.scan_root or [S]; pub_roots = a.public_root or ["/workspace/SPIRA/web/public"]
32
+ src_pfx = a.source_prefix or [S + "corpus_v3/raw/", S + "corpus_gutenberg/", S + "corpus_gutenberg_v2/raw/"]
33
+ TXT = (".md", ".json", ".txt", ".log", ".csv", ".diff", ".py", ".sh", ".yaml", ".yml", ".html")
34
+ EXCL_SUFFIX = (".bin", ".npz", ".npy", ".pt", ".ckpt", ".safetensors", ".lock")
35
+ SKIP_DIR = ("NEVER_PUSH", "broad", ".git", "__pycache__", "venv", ".venv", "site-packages")
36
+ R = {"version": "v3", "rc": 2, "verdict": None, "erreur": None}
37
+ def fin(rc, err=None):
38
+ R["rc"] = rc; R["erreur"] = err; R["verdict"] = {0: "PASS", 3: "FAIL"}.get(rc, "ANALYSE IMPOSSIBLE")
39
+ R["secondes"] = round(time.perf_counter() - T0, 1); R["maxrss_Mo"] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024
40
+ try: json.dump(R, open(a.out, "w"), indent=1)
41
+ except Exception as e: print("sortie impossible", e, file=sys.stderr); sys.exit(2)
42
+ 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)
43
+ try:
44
+ exp = json.loads(a.expect); man = json.load(open(a.manifest)); blob = open(a.blob, "rb").read()
45
+ except Exception as e: fin(2, f"lecture impossible : {e}")
46
+ fails = []
47
+ R["kit_sha"] = {}
48
+ for f, e in exp.items():
49
+ try: h = sha(open(f, "rb").read())
50
+ except Exception as x: fin(2, f"fichier du kit absent : {f}")
51
+ ok = h.startswith(e); R["kit_sha"][f] = {"sha": h, "attendu": e, "ok": ok}
52
+ if not ok: fails.append("kit_sha:" + f)
53
+ if man.get("blob_sha256") != sha(blob): fails.append("blob_sha_manifeste")
54
+ items = man.get("items", [])
55
+ if len(items) != a.n_items: fails.append(f"n_items {len(items)}≠{a.n_items}")
56
+ P = []; R["items"] = []
57
+ for it in items:
58
+ try: w = open(os.path.join(a.data_root, it["path"]), "rb").read()
59
+ except Exception: fin(2, f"fenêtre absente : {it.get('path')}")
60
+ s0 = it["start"]; p = w[s0:s0 + 200]; c = w[s0 + 200:s0 + 400]
61
+ 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}
62
+ R["items"].append(d)
63
+ for k in ("window_sha_ok", "prompt_sha_ok", "cont_sha_ok", "prompt_len_ok"):
64
+ if not d[k]: fails.append(f"{it['window']}:{k}")
65
+ P.append((it["window"], p, c))
66
+ hits = []; n = 0; nb = 0; skipped = []
67
+ for root in scan_roots + pub_roots:
68
+ pub = root in pub_roots
69
+ for dp, dn, fn in os.walk(root):
70
+ dn[:] = [x for x in dn if not x.startswith(SKIP_DIR) and x not in SKIP_DIR]
71
+ for f in fn:
72
+ fp = os.path.join(dp, f); forced = pub or "hf_ready" in fp
73
+ if fp.startswith("/tmp/"): continue
74
+ if not forced and (f.endswith(EXCL_SUFFIX) or not (f.endswith(TXT) or f == "spira_relay.md")): continue
75
+ try: b = open(fp, "rb").read()
76
+ except Exception as e: skipped.append([fp, str(e)[:80]]); continue
77
+ n += 1; nb += len(b)
78
+ for wn, p, c in P:
79
+ for kind, t in (("prompt", p), ("cont", c)):
80
+ full = t in b; k32 = sum(1 for i in range(169) if t[i:i + 32] in b)
81
+ 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)})
82
+ bad = [h for h in hits if not h["source_toleree"]]
83
+ 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},
84
+ "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})
85
+ if bad: fails.append(f"caviardage: {len(bad)} hit(s) hors source")
86
+ if skipped: fails.append(f"{len(skipped)} fichier(s) illisible(s)")
87
+ R["fails"] = fails
88
+ fin(3 if fails else 0)
results/hashing/gen_kit_check_r1/relay_entry_debut.md ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ ### Sat Oct 31 12:13:17 EDT 2026 — SPIRA Hashing — gen_kit_check_r1 DÉBUT
2
+ - 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.
3
+
4
+ Lu/appliqué — SPIRA Hashing
results/hashing/gen_kit_check_r1/relay_entry_v3_debut.md ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ ### Sat Oct 31 12:30:33 EDT 2026 — SPIRA Hashing — gen_kit_check v3 DÉBUT
2
+ - 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.
3
+
4
+ Lu/appliqué — SPIRA Hashing
results/hashing/gen_kit_check_r1/relay_entry_v3_fin.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ ### Sat Oct 31 12:39:43 EDT 2026 — SPIRA Hashing — gen_kit_check v3 FIN + v3b
2
+ - 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).
3
+ - 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.
4
+
5
+ Lu/appliqué — SPIRA Hashing
results/hashing/go_package_missing_r1/MISSING_DECISIONS.md ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MISSING_DECISIONS r1 — SPIRA Hashing — 31 oct. 2026 — document seulement
2
+ Complète GO_PACKAGE_runC_B.md (5ee520ff), qui ne couvre que D1–D10 (audit_r13, AUDIT.md 03583d4f, point 2 FAIL).
3
+ Aucun PID, aucun job lancé. Rien poussé, rien supprimé, aucun drapeau GO. Sources : DECISIONS_EN_ATTENTE r8 (fe2308ed, reprenant r4–r7), relais SPIRA.
4
+ 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.
5
+
6
+ ## D11 — Option d'échelle de l'éval appariée (A à E)
7
+ - Question : quelle option de scale pour imposed_pos_eval ?
8
+ - 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).
9
+ - É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).
10
+ - Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
11
+
12
+ ## D12 — Politique de scale et de bornes pour v1d
13
+ - Question : que faire des bornes fusion.scale [0,03 ; 0,11] pour v1d ?
14
+ - Options : A abaisser la borne (changement de règle permanente) ; C garder [0,03 ; 0,11] ; E autre scale.
15
+ - É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.
16
+ - Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
17
+
18
+ ## D13 — Option (iii) : usage du ratio σf/σs des checkpoints existants
19
+ - Question : quel usage faire de run_iii pour la question du scale ?
20
+ - Options : en prendre acte comme éclairage de D12 ; ne pas l'utiliser.
21
+ - É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).
22
+ - Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
23
+
24
+ ## D14 — Pré-cal r3 sur la porte v1c
25
+ - Question : appliquer ou non le correctif r3 (fix 1cfc5aa9) à la porte v1c ?
26
+ - Options : appliquer ; ne pas appliquer.
27
+ - É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).
28
+ - Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
29
+
30
+ ## D15 — GO du sweep de précal (balayage de longueur)
31
+ - Question : lancer le balayage de PREDECL_precal_sweep_BROUILLON_r2 (0f2db9f9, ré-audit Checker PASS 609bb24a), et avec quels paramètres ?
32
+ - Options à fixer (PREDECL r2 l.58) :
33
+ - lancement : oui / non ;
34
+ - 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 ;
35
+ - 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) ;
36
+ - bornes et nombre de points (proposé : 5 points log-espacés, 60 000 → 1 200 000 ticks, 2 bras, 10 runs) ;
37
+ - lieu de mesure de l'échelle : data[:60000] d'entraînement ou v1d.
38
+ - É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.
39
+ - Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
40
+
41
+ ## D16 — leak16 sur 6 ou 8 fenêtres
42
+ - 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.)
43
+ - Options : 6 fenêtres ; 8 fenêtres.
44
+ - É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.
45
+ - Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
46
+
47
+ ## D17 — Exception .py pour la garde de push
48
+ - Question : accorder une exception ou un seuil propre aux .py (et runner.sh) ?
49
+ - 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.
50
+ - É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.
51
+ - Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
52
+
53
+ ## D18 — Push de run_iii r3 et des autres arbres prêts
54
+ - 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.
55
+ - 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.
56
+ - É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.
57
+ - Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
58
+
59
+ ## D19 — Pause de la routine horaire
60
+ - Question : mettre en pause, ou non, la routine horaire de surveillance SPIRA ?
61
+ - Options : maintenir ; mettre en pause (jusqu'à quand) ; arrêter.
62
+ - É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é.
63
+ - Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
64
+
65
+ ## D20 — Échantillon A ou B pour le run C
66
+ - Question : quel échantillon de données pour le run C ?
67
+ - Options : A b6655e90 (34 557 670 o) ; B b7404e88 (35 716 621 o) ; e0acd131 (1 259 666 o de licence inconnue, déconseillé).
68
+ - É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.
69
+ - Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
70
+
71
+ ## D21 — Test de génération : lancement et choix du checkpoint
72
+ - Question : lancer le test de génération, et sur quel checkpoint ?
73
+ - Options : ne pas lancer ; lancer en mode descriptif sur un ckpt à désigner (ex. v1c ctl) ; attendre un ckpt MESURABLE.
74
+ - É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).
75
+ - Hashing n'écrit aucun code, harness ni référence jouet pour ce test tant que Philippe-Antoine ne l'a pas ordonné.
76
+ - Aucun défaut — EN ATTENTE DE DÉCISION de Philippe-Antoine.
77
+
78
+ ## Corrections à apporter aux décisions existantes du GO_PACKAGE
79
+ 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.
80
+ 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.
81
+ 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. »
results/hashing/go_package_missing_r1/SHA256SUMS ADDED
@@ -0,0 +1 @@
 
 
1
+ bac947b79dbd49fb3eb79c3d9fa5205effd4a9215cf6a6781bc455b0183623bb MISSING_DECISIONS.md
results/hashing/hf_pushed.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ 2026-10-30 19:15:56 d3c24c89 v3_scale/hashing/m8cp1/ (8 fichiers verdict/gap/script/FROZEN) Checker PASS 19h16
2
+ 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
3
+ 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
4
+ 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
results/hashing/leak16_baseline_recount/SHA256SUMS ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ 9b870e4a3c65057999567662ffbdf690c66cea163f234ef45b8f1b75aa9d9478 recount_leak16.py
2
+ e2ed4e52d646df94a0fe1455e5c0e8e74249a07aeccae378d37d7af26e3b41a0 results.json
3
+ 8ef3d3d8523741eb95463015445a2c1f58a06aad24b13d7eb17ba9b77d2567a0 recount_leak16_stream.py
4
+ 7aa14491a0010b6254d736f7c86468a0763442d78e27cff1e042943d18a4b7c9 results_stream.json
5
+ 066d5a7a0b3c7d95d6e84532b3def027ca2c32d9da9864c092202d10fcf966e1 leakcheck_hf.py
6
+ 5dceec4a2501cac734df4785a8830ff24b9fd0bdd51febd0e8ddc8a33adbecb8 leakcheck_hf_ready.out
results/hashing/leak16_baseline_recount/hf_ready/README.md ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPIRA — leak16 baseline recount (sanitized)
2
+
3
+ Recomptage exact du recouvrement par 16-grammes d'octets, fenêtres d'évaluation SPIRA
4
+ (fc2, fresh_en, fresh_fr, test20k_old, test_v3, queries) vs sources d'entraînement
5
+ (v1c_corpus, v1c_sample, v1b_corpus, v1b_sample).
6
+
7
+ - `recount_leak16.py` : version d'origine (pic RSS ≈ 365 Mo).
8
+ - `recount_leak16_stream.py` : version streaming (clés V16 brutes, tri en place, searchsorted ; blocs de 256 Kio,
9
+ recouvrement 15 octets ; pic RSS mesuré 239,5 Mo). Résultats numériques identiques à l'origine.
10
+ - `results_counts.json` : uniquement comptes, pourcentages, tailles et sha256. Aucun fragment de texte, aucun octet de fenêtre.
11
+
12
+ Méthode : exacte, sans hachage. `n_16gram_positions_shared` = positions (avec répétitions) (fenêtre) dont le 16-gramme
13
+ apparaît dans la source ; `bytes_covered_ge16` = octets couverts par au moins un tel 16-gramme.
14
+ Chaque valeur concordent avec le comptage de Checker (`all_checks_match: true`).
15
+
16
+ Les scripts lisent des chemins locaux (/workspace/spira_shared/...) ; les données ne sont pas incluses.
17
+ Contrôle de fuite : aucun fichier de ce dossier ne partage une suite de plus de 15 octets avec une fenêtre d'évaluation.
18
+ Modifications par rapport aux originaux du dossier parent (contrôle ast.dump, fichier par fichier) :
19
+ - `recount_leak16.py` : réindentation (espaces -> tabulations) et blancs avant `#` seulement. AST identique.
20
+ - `recount_leak16_stream.py` : même réindentation, plus une réécriture d'une comparaison : `len(sys.argv)>1` devient `1<len(sys.argv)`
21
+ (opérandes inversés, même comportement). AST NON identique (un seul nœud Compare diffère), sémantique inchangée.
22
+ - `results_counts.json` : extrait (comptes seulement) de results.json et results_stream.json ; pas un script.
23
+
24
+ Destination HF prévue : `v3_scale/hashing/leak16_baseline_recount/` (pas results/). Non poussé ; fichiers gardés localement dans hf_ready/.
results/hashing/leak16_baseline_recount/hf_ready/SHA256SUMS ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ aad2672b4de5b06fbc7410561d4fb43004a050833cc152d3f388a42bbe004b4a README.md
2
+ b2854be82b592f5743387a2d284bd5bfd3304f5822d504dcfb4b27a00ea00375 recount_leak16.py
3
+ 734270e1f593e95de6fd22635357b9473517bc6f416aa04bde1e5e593c263a79 recount_leak16_stream.py
4
+ 7f4d1ce499361abb0d4039c7e5819b99fbee78b9878df5032de9b4b97bb7041c results_counts.json
results/hashing/leak16_baseline_recount/hf_ready/recount_leak16.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Recount indépendant leak16 (clés exactes 2x8 o, sans hachage, corpus en blocs de 1 Mo). Lecture seule.
2
+ import json,hashlib,sys,resource,time,numpy as np
3
+ R='/workspace/spira_shared/'; T=R+'checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json'
4
+ def sha(p):
5
+ h=hashlib.sha256()
6
+ with open(p,'rb') as f:
7
+ for b in iter(lambda:f.read(1<<20),b''): h.update(b)
8
+ return h.hexdigest()
9
+ def keys(a): # a uint8 -> (hi,lo) big-endian u64 of each 16-gram
10
+ n=len(a)-15; hi=np.zeros(n,np.uint64); lo=np.zeros(n,np.uint64)
11
+ for i in range(8):
12
+ hi=(hi<<np.uint64(8))|a[i:i+n].astype(np.uint64); lo=(lo<<np.uint64(8))|a[i+8:i+8+n].astype(np.uint64)
13
+ return hi,lo
14
+ J=json.load(open(T)); out={'target':T,'target_sha256':sha(T),'windows':{},'sources':{}}
15
+ W={};allh=[];alll=[]
16
+ for w,m in J['windows'].items():
17
+ p=R+m['path']; s=sha(p); a=np.fromfile(p,np.uint8)
18
+ out['windows'][w]={'path':p,'sha256':s,'sha_ok':s==m['sha256'],'bytes':len(a),'bytes_ok':len(a)==m['bytes']}
19
+ h,l=keys(a); W[w]=(h,l); allh.append(h); alll.append(l)
20
+ H=np.concatenate(allh);L=np.concatenate(alll); o=np.lexsort((L,H)); H=H[o];L=L[o]
21
+ k=np.ones(len(H),bool); k[1:]=(H[1:]!=H[:-1])|(L[1:]!=L[:-1]); UH=H[k];UL=L[k]; del H,L,o,k,allh,alll
22
+ idx={w:None for w in W}
23
+ for w,(h,l) in W.items():
24
+ i=np.searchsorted(UH,h,'left'); r=np.searchsorted(UH,h,'right')
25
+ while True: # exact match on lo within hi group
26
+ bad=UL[np.minimum(i,len(UL)-1)]!=l
27
+ if not bad.any(): break
28
+ i[bad]+=1
29
+ assert (UH[i]==h).all() and (UL[i]==l).all(); idx[w]=i
30
+ def member(h,l):
31
+ i=np.searchsorted(UH,h,'left'); r=np.searchsorted(UH,h,'right'); f=np.zeros(len(h),bool); g=np.full(len(h),-1)
32
+ c=np.nonzero(r>i)[0]; ii=i[c].copy(); rr=r[c]
33
+ while len(c):
34
+ m=UL[ii]==l[c]; f[c[m]]=True; g[c[m]]=ii[m]
35
+ keep=(~m)&(ii+1<rr); c=c[keep]; ii=ii[keep]+1; rr=rr[keep]
36
+ return g[f]
37
+ for s,m in J['sources'].items():
38
+ t=time.time(); p=m['path']; sh=sha(p); found=np.zeros(len(UH),bool); n=0; prev=b''
39
+ with open(p,'rb') as f:
40
+ for b in iter(lambda:f.read(1<<20),b''):
41
+ a=np.frombuffer(prev+b,np.uint8); n+=len(b); prev=bytes(a[-15:])
42
+ if len(a)>=16: found[member(*keys(a))]=True
43
+ pw={}
44
+ for w,(h,l) in W.items():
45
+ hit=found[idx[w]]; N=len(hit)+15; d=np.zeros(N+1,np.int32); pos=np.nonzero(hit)[0]
46
+ np.add.at(d,pos,1); np.add.at(d,pos+16,-1); cov=np.cumsum(d[:N])>0
47
+ e=np.diff(np.concatenate(([0],cov.astype(np.int8),[0]))); runs=np.nonzero(e==-1)[0]-np.nonzero(e==1)[0]
48
+ c=m['per_window'][w]; mine={'bytes_covered_ge16':int(cov.sum()),'n_16gram_positions_shared':int(hit.sum()),
49
+ 'n_16grams_shared_unique':int(len(np.unique(idx[w][hit]))),'longest_covered_run_bytes':int(runs.max() if len(runs) else 0)}
50
+ mine['frac_covered_ge16']=mine['bytes_covered_ge16']/N
51
+ mine['checker']=c; mine['covered_match']=mine['bytes_covered_ge16']==c['bytes_covered_ge16']
52
+ mine['longest_match']=mine['longest_covered_run_bytes']==c['longest_covered_run_bytes']
53
+ mine['n16_match_positions']=mine['n_16gram_positions_shared']==c['n_16grams_shared']
54
+ mine['n16_match_unique']=mine['n_16grams_shared_unique']==c['n_16grams_shared']; pw[w]=mine
55
+ 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)}
56
+ print(s,round(time.time()-t),flush=True)
57
+ out['peak_rss_mb']=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024
58
+ json.dump(out,open('results.json','w'),indent=1,ensure_ascii=False); print(out['peak_rss_mb'])
results/hashing/leak16_baseline_recount/hf_ready/recount_leak16_stream.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Recount leak16 en streaming (< 300 Mo) : version de recount_leak16.py (9b870e4a).
2
+ # Exact : clés = 16 octets bruts (dtype V16, ordre memcmp), aucun hachage ; tableau trié unique + searchsorted ;
3
+ # corpus lu en blocs de 256 Kio avec recouvrement de 15 octets ; n_16grams_shared compté en positions.
4
+ # Lecture seule hors de ce dossier. Sortie : argv[1] (défaut results_stream.json).
5
+ import json,hashlib,sys,resource,time,numpy as np
6
+ from numpy.lib.stride_tricks import sliding_window_view as swv
7
+ R='/workspace/spira_shared/'; T=R+'checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json'
8
+ OUT=sys.argv[1] if 1<len(sys.argv) else 'results_stream.json'; BLK=1<<18
9
+ def sha(p):
10
+ h=hashlib.sha256()
11
+ with open(p,'rb') as f:
12
+ for b in iter(lambda:f.read(1<<20),b''): h.update(b)
13
+ return h.hexdigest()
14
+ def keys(a): return np.ascontiguousarray(swv(a,16)).view('V16').ravel() # a uint8 -> 16-grammes (copie n*16 o)
15
+ J=json.load(open(T)); out={'target':T,'target_sha256':sha(T),'windows':{},'sources':{}}
16
+ NW={}
17
+ for w,m in J['windows'].items():
18
+ p=R+m['path']; s=sha(p); NW[w]=n=int(np.fromfile(p,np.uint8).size)
19
+ out['windows'][w]={'path':p,'sha256':s,'sha_ok':s==m['sha256'],'bytes':n,'bytes_ok':n==m['bytes']}
20
+ U=np.empty(sum(n-15 for n in NW.values()),'V16'); k=0 # un seul tableau préalloué, rempli par blocs
21
+ for w,m in J['windows'].items():
22
+ a=np.fromfile(R+m['path'],np.uint8)
23
+ for s0 in range(0,len(a)-15,BLK):
24
+ q=keys(a[s0:s0+BLK+15]); U[k:k+len(q)]=q; k+=len(q)
25
+ del a
26
+ assert k==len(U); U.sort() # tri en place (ordre memcmp)
27
+ keep=np.ones(len(U),bool); keep[1:]=U[1:]!=U[:-1]; nu=int(keep.sum())
28
+ U[:nu]=U[keep]; U=U[:nu].copy(); del keep # dédoublonnage exact
29
+ def lookup(q): # -> (indices dans U, masque présent), exact octet à octet
30
+ i=np.searchsorted(U,q); j=np.minimum(i,len(U)-1); f=U[j]==q; return j,f
31
+ idx={}
32
+ for w,m in J['windows'].items():
33
+ a=np.fromfile(R+m['path'],np.uint8); ii=[]
34
+ for s0 in range(0,len(a)-15,BLK):
35
+ j,f=lookup(keys(a[s0:s0+BLK+15])); assert f.all(); ii.append(j.astype(np.int32))
36
+ idx[w]=np.concatenate(ii); assert len(idx[w])==NW[w]-15
37
+ for s,m in J['sources'].items():
38
+ t=time.time(); p=m['path']; sh=sha(p); found=np.zeros(len(U),bool); n=0; prev=b''
39
+ with open(p,'rb') as f:
40
+ for b in iter(lambda:f.read(BLK),b''):
41
+ a=np.frombuffer(prev+b,np.uint8); n+=len(b); prev=bytes(a[-15:])
42
+ if len(a)>=16:
43
+ j,fm=lookup(keys(a)); found[j[fm]]=True
44
+ pw={}
45
+ for w in idx:
46
+ hit=found[idx[w]]; N=len(hit)+15; d=np.zeros(N+1,np.int32); pos=np.nonzero(hit)[0]
47
+ np.add.at(d,pos,1); np.add.at(d,pos+16,-1); cov=np.cumsum(d[:N])>0
48
+ e=np.diff(np.concatenate(([0],cov.astype(np.int8),[0]))); runs=np.nonzero(e==-1)[0]-np.nonzero(e==1)[0]
49
+ c=m['per_window'][w]; mine={'bytes_covered_ge16':int(cov.sum()),'n_16gram_positions_shared':int(hit.sum()),
50
+ 'n_16grams_shared_unique':int(len(np.unique(idx[w][hit]))),'longest_covered_run_bytes':int(runs.max() if len(runs) else 0)}
51
+ mine['frac_covered_ge16']=mine['bytes_covered_ge16']/N
52
+ mine['checker']=c; mine['covered_match']=mine['bytes_covered_ge16']==c['bytes_covered_ge16']
53
+ mine['longest_match']=mine['longest_covered_run_bytes']==c['longest_covered_run_bytes']
54
+ mine['n16_match_positions']=mine['n_16gram_positions_shared']==c['n_16grams_shared']
55
+ mine['n16_match_unique']=mine['n_16grams_shared_unique']==c['n_16grams_shared']; pw[w]=mine
56
+ 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)}
57
+ print(s,round(time.time()-t),flush=True)
58
+ out['peak_rss_mb']=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024
59
+ json.dump(out,open(OUT,'w'),indent=1,ensure_ascii=False); print(out['peak_rss_mb'])
results/hashing/leak16_baseline_recount/hf_ready/results_counts.json ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "description": "leak16 baseline recount (exact 16-byte n-grams, no hashing): eval windows vs training sources v1b/v1c. Counts, percentages, sizes and sha256 only.",
3
+ "target_json_sha256": "a9ee65d4ad394ada0af487a0cb7eec66073f5440fb405ec19d5df641b5334598",
4
+ "windows": {
5
+ "fc2": {
6
+ "bytes": 199792,
7
+ "sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
8
+ },
9
+ "fresh_en": {
10
+ "bytes": 119763,
11
+ "sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
12
+ },
13
+ "fresh_fr": {
14
+ "bytes": 1088688,
15
+ "sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
16
+ },
17
+ "test20k_old": {
18
+ "bytes": 319940,
19
+ "sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
20
+ },
21
+ "test_v3": {
22
+ "bytes": 3486653,
23
+ "sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
24
+ },
25
+ "queries": {
26
+ "bytes": 27800,
27
+ "sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
28
+ }
29
+ },
30
+ "sources": {
31
+ "v1c_corpus": {
32
+ "bytes": 503301148,
33
+ "sha256": "33577b70c819af76fe4737319e929f4c097b0c72f020e8b07b4baddbb1823439",
34
+ "per_window": {
35
+ "fc2": {
36
+ "bytes_covered_ge16": 145139,
37
+ "n_16gram_positions_shared": 71796,
38
+ "n_16grams_shared_unique": 38057,
39
+ "longest_covered_run_bytes": 419,
40
+ "pct_covered_ge16": 72.6451,
41
+ "matches_checker_covered": true,
42
+ "matches_checker_longest": true,
43
+ "matches_checker_n16_positions": true
44
+ },
45
+ "fresh_en": {
46
+ "bytes_covered_ge16": 93456,
47
+ "n_16gram_positions_shared": 34364,
48
+ "n_16grams_shared_unique": 32608,
49
+ "longest_covered_run_bytes": 338,
50
+ "pct_covered_ge16": 78.0341,
51
+ "matches_checker_covered": true,
52
+ "matches_checker_longest": true,
53
+ "matches_checker_n16_positions": true
54
+ },
55
+ "fresh_fr": {
56
+ "bytes_covered_ge16": 652302,
57
+ "n_16gram_positions_shared": 194384,
58
+ "n_16grams_shared_unique": 168701,
59
+ "longest_covered_run_bytes": 145,
60
+ "pct_covered_ge16": 59.9163,
61
+ "matches_checker_covered": true,
62
+ "matches_checker_longest": true,
63
+ "matches_checker_n16_positions": true
64
+ },
65
+ "test20k_old": {
66
+ "bytes_covered_ge16": 235956,
67
+ "n_16gram_positions_shared": 91729,
68
+ "n_16grams_shared_unique": 73892,
69
+ "longest_covered_run_bytes": 266,
70
+ "pct_covered_ge16": 73.7501,
71
+ "matches_checker_covered": true,
72
+ "matches_checker_longest": true,
73
+ "matches_checker_n16_positions": true
74
+ },
75
+ "test_v3": {
76
+ "bytes_covered_ge16": 2433706,
77
+ "n_16gram_positions_shared": 859632,
78
+ "n_16grams_shared_unique": 667154,
79
+ "longest_covered_run_bytes": 353,
80
+ "pct_covered_ge16": 69.8006,
81
+ "matches_checker_covered": true,
82
+ "matches_checker_longest": true,
83
+ "matches_checker_n16_positions": true
84
+ },
85
+ "queries": {
86
+ "bytes_covered_ge16": 13583,
87
+ "n_16gram_positions_shared": 3748,
88
+ "n_16grams_shared_unique": 75,
89
+ "longest_covered_run_bytes": 53,
90
+ "pct_covered_ge16": 48.8597,
91
+ "matches_checker_covered": true,
92
+ "matches_checker_longest": true,
93
+ "matches_checker_n16_positions": true
94
+ }
95
+ }
96
+ },
97
+ "v1c_sample": {
98
+ "bytes": 35948296,
99
+ "sha256": "3d8b6181cbffb27e360758267e1084197dccad82ae05b868691758e1cf72eed4",
100
+ "per_window": {
101
+ "fc2": {
102
+ "bytes_covered_ge16": 100440,
103
+ "n_16gram_positions_shared": 40436,
104
+ "n_16grams_shared_unique": 15136,
105
+ "longest_covered_run_bytes": 191,
106
+ "pct_covered_ge16": 50.2723,
107
+ "matches_checker_covered": true,
108
+ "matches_checker_longest": true,
109
+ "matches_checker_n16_positions": true
110
+ },
111
+ "fresh_en": {
112
+ "bytes_covered_ge16": 52239,
113
+ "n_16gram_positions_shared": 11634,
114
+ "n_16grams_shared_unique": 10573,
115
+ "longest_covered_run_bytes": 109,
116
+ "pct_covered_ge16": 43.6186,
117
+ "matches_checker_covered": true,
118
+ "matches_checker_longest": true,
119
+ "matches_checker_n16_positions": true
120
+ },
121
+ "fresh_fr": {
122
+ "bytes_covered_ge16": 286582,
123
+ "n_16gram_positions_shared": 55095,
124
+ "n_16grams_shared_unique": 41336,
125
+ "longest_covered_run_bytes": 88,
126
+ "pct_covered_ge16": 26.3236,
127
+ "matches_checker_covered": true,
128
+ "matches_checker_longest": true,
129
+ "matches_checker_n16_positions": true
130
+ },
131
+ "test20k_old": {
132
+ "bytes_covered_ge16": 128766,
133
+ "n_16gram_positions_shared": 36414,
134
+ "n_16grams_shared_unique": 23867,
135
+ "longest_covered_run_bytes": 205,
136
+ "pct_covered_ge16": 40.2469,
137
+ "matches_checker_covered": true,
138
+ "matches_checker_longest": true,
139
+ "matches_checker_n16_positions": true
140
+ },
141
+ "test_v3": {
142
+ "bytes_covered_ge16": 1316746,
143
+ "n_16gram_positions_shared": 295112,
144
+ "n_16grams_shared_unique": 185590,
145
+ "longest_covered_run_bytes": 129,
146
+ "pct_covered_ge16": 37.7653,
147
+ "matches_checker_covered": true,
148
+ "matches_checker_longest": true,
149
+ "matches_checker_n16_positions": true
150
+ },
151
+ "queries": {
152
+ "bytes_covered_ge16": 6200,
153
+ "n_16gram_positions_shared": 900,
154
+ "n_16grams_shared_unique": 18,
155
+ "longest_covered_run_bytes": 21,
156
+ "pct_covered_ge16": 22.3022,
157
+ "matches_checker_covered": true,
158
+ "matches_checker_longest": true,
159
+ "matches_checker_n16_positions": true
160
+ }
161
+ }
162
+ },
163
+ "v1b_corpus": {
164
+ "bytes": 520785883,
165
+ "sha256": "ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3",
166
+ "per_window": {
167
+ "fc2": {
168
+ "bytes_covered_ge16": 145183,
169
+ "n_16gram_positions_shared": 71837,
170
+ "n_16grams_shared_unique": 38098,
171
+ "longest_covered_run_bytes": 419,
172
+ "pct_covered_ge16": 72.6671,
173
+ "matches_checker_covered": true,
174
+ "matches_checker_longest": true,
175
+ "matches_checker_n16_positions": true
176
+ },
177
+ "fresh_en": {
178
+ "bytes_covered_ge16": 94752,
179
+ "n_16gram_positions_shared": 35873,
180
+ "n_16grams_shared_unique": 34072,
181
+ "longest_covered_run_bytes": 338,
182
+ "pct_covered_ge16": 79.1163,
183
+ "matches_checker_covered": true,
184
+ "matches_checker_longest": true,
185
+ "matches_checker_n16_positions": true
186
+ },
187
+ "fresh_fr": {
188
+ "bytes_covered_ge16": 652322,
189
+ "n_16gram_positions_shared": 194413,
190
+ "n_16grams_shared_unique": 168730,
191
+ "longest_covered_run_bytes": 145,
192
+ "pct_covered_ge16": 59.9182,
193
+ "matches_checker_covered": true,
194
+ "matches_checker_longest": true,
195
+ "matches_checker_n16_positions": true
196
+ },
197
+ "test20k_old": {
198
+ "bytes_covered_ge16": 237099,
199
+ "n_16gram_positions_shared": 92792,
200
+ "n_16grams_shared_unique": 74894,
201
+ "longest_covered_run_bytes": 266,
202
+ "pct_covered_ge16": 74.1073,
203
+ "matches_checker_covered": true,
204
+ "matches_checker_longest": true,
205
+ "matches_checker_n16_positions": true
206
+ },
207
+ "test_v3": {
208
+ "bytes_covered_ge16": 2442104,
209
+ "n_16gram_positions_shared": 866084,
210
+ "n_16grams_shared_unique": 673440,
211
+ "longest_covered_run_bytes": 353,
212
+ "pct_covered_ge16": 70.0415,
213
+ "matches_checker_covered": true,
214
+ "matches_checker_longest": true,
215
+ "matches_checker_n16_positions": true
216
+ },
217
+ "queries": {
218
+ "bytes_covered_ge16": 15133,
219
+ "n_16gram_positions_shared": 4398,
220
+ "n_16grams_shared_unique": 88,
221
+ "longest_covered_run_bytes": 53,
222
+ "pct_covered_ge16": 54.4353,
223
+ "matches_checker_covered": true,
224
+ "matches_checker_longest": true,
225
+ "matches_checker_n16_positions": true
226
+ }
227
+ }
228
+ },
229
+ "v1b_sample": {
230
+ "bytes": 35128951,
231
+ "sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
232
+ "per_window": {
233
+ "fc2": {
234
+ "bytes_covered_ge16": 100880,
235
+ "n_16gram_positions_shared": 40698,
236
+ "n_16grams_shared_unique": 15264,
237
+ "longest_covered_run_bytes": 277,
238
+ "pct_covered_ge16": 50.4925,
239
+ "matches_checker_covered": true,
240
+ "matches_checker_longest": true,
241
+ "matches_checker_n16_positions": true
242
+ },
243
+ "fresh_en": {
244
+ "bytes_covered_ge16": 55107,
245
+ "n_16gram_positions_shared": 12710,
246
+ "n_16grams_shared_unique": 11534,
247
+ "longest_covered_run_bytes": 108,
248
+ "pct_covered_ge16": 46.0134,
249
+ "matches_checker_covered": true,
250
+ "matches_checker_longest": true,
251
+ "matches_checker_n16_positions": true
252
+ },
253
+ "fresh_fr": {
254
+ "bytes_covered_ge16": 283182,
255
+ "n_16gram_positions_shared": 55308,
256
+ "n_16grams_shared_unique": 41593,
257
+ "longest_covered_run_bytes": 76,
258
+ "pct_covered_ge16": 26.0113,
259
+ "matches_checker_covered": true,
260
+ "matches_checker_longest": true,
261
+ "matches_checker_n16_positions": true
262
+ },
263
+ "test20k_old": {
264
+ "bytes_covered_ge16": 128263,
265
+ "n_16gram_positions_shared": 36178,
266
+ "n_16grams_shared_unique": 23521,
267
+ "longest_covered_run_bytes": 166,
268
+ "pct_covered_ge16": 40.0897,
269
+ "matches_checker_covered": true,
270
+ "matches_checker_longest": true,
271
+ "matches_checker_n16_positions": true
272
+ },
273
+ "test_v3": {
274
+ "bytes_covered_ge16": 1189410,
275
+ "n_16gram_positions_shared": 260934,
276
+ "n_16grams_shared_unique": 174208,
277
+ "longest_covered_run_bytes": 105,
278
+ "pct_covered_ge16": 34.1132,
279
+ "matches_checker_covered": true,
280
+ "matches_checker_longest": true,
281
+ "matches_checker_n16_positions": true
282
+ },
283
+ "queries": {
284
+ "bytes_covered_ge16": 8500,
285
+ "n_16gram_positions_shared": 1800,
286
+ "n_16grams_shared_unique": 36,
287
+ "longest_covered_run_bytes": 36,
288
+ "pct_covered_ge16": 30.5755,
289
+ "matches_checker_covered": true,
290
+ "matches_checker_longest": true,
291
+ "matches_checker_n16_positions": true
292
+ }
293
+ }
294
+ }
295
+ },
296
+ "all_checks_match": true
297
+ }
results/hashing/leak16_baseline_recount/leakcheck_hf.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Leak check: for each file in hf_ready, longest byte run shared with any eval window (exact, binary search on k).
2
+ import json,sys,os,numpy as np
3
+ from numpy.lib.stride_tricks import sliding_window_view as swv
4
+ R='/workspace/spira_shared/'; J=json.load(open(R+'checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json'))
5
+ D=sys.argv[1]; files=sorted(f for f in os.listdir(D) if f!='SHA256SUMS')
6
+ W=[np.fromfile(R+m['path'],np.uint8) for m in J['windows'].values()]
7
+ 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}')
8
+ def shares(fb,k):
9
+ q=np.unique(grams(fb,k))
10
+ for a in W:
11
+ for s0 in range(0,max(len(a)-k+1,1),1<<18):
12
+ g=grams(a[s0:s0+(1<<18)+k-1],k); i=np.searchsorted(q,g); i=np.minimum(i,len(q)-1)
13
+ if len(q) and (q[i]==g).any(): return True
14
+ return False
15
+ res={}
16
+ for f in files:
17
+ fb=np.fromfile(os.path.join(D,f),np.uint8); lo,hi=0,min(len(fb),64)
18
+ if shares(fb,hi): lo=hi
19
+ while lo<hi:
20
+ m=(lo+hi+1)//2
21
+ if shares(fb,m): lo=m
22
+ else: hi=m-1
23
+ res[f]={'longest_shared_run_bytes':lo,'shares_16gram':lo>=16}
24
+ print(json.dumps(res,indent=1)); print('LEAKCHECK','PASS' if all(not v['shares_16gram'] for v in res.values()) else 'FAIL')
results/hashing/leak16_baseline_recount/recount_leak16.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Recount indépendant leak16 (clés exactes 2x8 o, sans hachage, corpus en blocs de 1 Mo). Lecture seule.
2
+ import json,hashlib,sys,resource,time,numpy as np
3
+ R='/workspace/spira_shared/'; T=R+'checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json'
4
+ def sha(p):
5
+ h=hashlib.sha256()
6
+ with open(p,'rb') as f:
7
+ for b in iter(lambda:f.read(1<<20),b''): h.update(b)
8
+ return h.hexdigest()
9
+ def keys(a): # a uint8 -> (hi,lo) big-endian u64 of each 16-gram
10
+ n=len(a)-15; hi=np.zeros(n,np.uint64); lo=np.zeros(n,np.uint64)
11
+ for i in range(8):
12
+ hi=(hi<<np.uint64(8))|a[i:i+n].astype(np.uint64); lo=(lo<<np.uint64(8))|a[i+8:i+8+n].astype(np.uint64)
13
+ return hi,lo
14
+ J=json.load(open(T)); out={'target':T,'target_sha256':sha(T),'windows':{},'sources':{}}
15
+ W={};allh=[];alll=[]
16
+ for w,m in J['windows'].items():
17
+ p=R+m['path']; s=sha(p); a=np.fromfile(p,np.uint8)
18
+ out['windows'][w]={'path':p,'sha256':s,'sha_ok':s==m['sha256'],'bytes':len(a),'bytes_ok':len(a)==m['bytes']}
19
+ h,l=keys(a); W[w]=(h,l); allh.append(h); alll.append(l)
20
+ H=np.concatenate(allh);L=np.concatenate(alll); o=np.lexsort((L,H)); H=H[o];L=L[o]
21
+ k=np.ones(len(H),bool); k[1:]=(H[1:]!=H[:-1])|(L[1:]!=L[:-1]); UH=H[k];UL=L[k]; del H,L,o,k,allh,alll
22
+ idx={w:None for w in W}
23
+ for w,(h,l) in W.items():
24
+ i=np.searchsorted(UH,h,'left'); r=np.searchsorted(UH,h,'right')
25
+ while True: # exact match on lo within hi group
26
+ bad=UL[np.minimum(i,len(UL)-1)]!=l
27
+ if not bad.any(): break
28
+ i[bad]+=1
29
+ assert (UH[i]==h).all() and (UL[i]==l).all(); idx[w]=i
30
+ def member(h,l):
31
+ i=np.searchsorted(UH,h,'left'); r=np.searchsorted(UH,h,'right'); f=np.zeros(len(h),bool); g=np.full(len(h),-1)
32
+ c=np.nonzero(r>i)[0]; ii=i[c].copy(); rr=r[c]
33
+ while len(c):
34
+ m=UL[ii]==l[c]; f[c[m]]=True; g[c[m]]=ii[m]
35
+ keep=(~m)&(ii+1<rr); c=c[keep]; ii=ii[keep]+1; rr=rr[keep]
36
+ return g[f]
37
+ for s,m in J['sources'].items():
38
+ t=time.time(); p=m['path']; sh=sha(p); found=np.zeros(len(UH),bool); n=0; prev=b''
39
+ with open(p,'rb') as f:
40
+ for b in iter(lambda:f.read(1<<20),b''):
41
+ a=np.frombuffer(prev+b,np.uint8); n+=len(b); prev=bytes(a[-15:])
42
+ if len(a)>=16: found[member(*keys(a))]=True
43
+ pw={}
44
+ for w,(h,l) in W.items():
45
+ hit=found[idx[w]]; N=len(hit)+15; d=np.zeros(N+1,np.int32); pos=np.nonzero(hit)[0]
46
+ np.add.at(d,pos,1); np.add.at(d,pos+16,-1); cov=np.cumsum(d[:N])>0
47
+ e=np.diff(np.concatenate(([0],cov.astype(np.int8),[0]))); runs=np.nonzero(e==-1)[0]-np.nonzero(e==1)[0]
48
+ c=m['per_window'][w]; mine={'bytes_covered_ge16':int(cov.sum()),'n_16gram_positions_shared':int(hit.sum()),
49
+ 'n_16grams_shared_unique':int(len(np.unique(idx[w][hit]))),'longest_covered_run_bytes':int(runs.max() if len(runs) else 0)}
50
+ mine['frac_covered_ge16']=mine['bytes_covered_ge16']/N
51
+ mine['checker']=c; mine['covered_match']=mine['bytes_covered_ge16']==c['bytes_covered_ge16']
52
+ mine['longest_match']=mine['longest_covered_run_bytes']==c['longest_covered_run_bytes']
53
+ mine['n16_match_positions']=mine['n_16gram_positions_shared']==c['n_16grams_shared']
54
+ mine['n16_match_unique']=mine['n_16grams_shared_unique']==c['n_16grams_shared']; pw[w]=mine
55
+ 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)}
56
+ print(s,round(time.time()-t),flush=True)
57
+ out['peak_rss_mb']=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024
58
+ json.dump(out,open('results.json','w'),indent=1,ensure_ascii=False); print(out['peak_rss_mb'])
results/hashing/leak16_baseline_recount/recount_leak16_stream.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Recount leak16 en streaming (< 300 Mo) : version de recount_leak16.py (9b870e4a).
2
+ # Exact : clés = 16 octets bruts (dtype V16, ordre memcmp), aucun hachage ; tableau trié unique + searchsorted ;
3
+ # corpus lu en blocs de 256 Kio avec recouvrement de 15 octets ; n_16grams_shared compté en positions.
4
+ # Lecture seule hors de ce dossier. Sortie : argv[1] (défaut results_stream.json).
5
+ import json,hashlib,sys,resource,time,numpy as np
6
+ from numpy.lib.stride_tricks import sliding_window_view as swv
7
+ R='/workspace/spira_shared/'; T=R+'checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json'
8
+ OUT=sys.argv[1] if len(sys.argv)>1 else 'results_stream.json'; BLK=1<<18
9
+ def sha(p):
10
+ h=hashlib.sha256()
11
+ with open(p,'rb') as f:
12
+ for b in iter(lambda:f.read(1<<20),b''): h.update(b)
13
+ return h.hexdigest()
14
+ def keys(a): return np.ascontiguousarray(swv(a,16)).view('V16').ravel() # a uint8 -> 16-grammes (copie n*16 o)
15
+ J=json.load(open(T)); out={'target':T,'target_sha256':sha(T),'windows':{},'sources':{}}
16
+ NW={}
17
+ for w,m in J['windows'].items():
18
+ p=R+m['path']; s=sha(p); NW[w]=n=int(np.fromfile(p,np.uint8).size)
19
+ out['windows'][w]={'path':p,'sha256':s,'sha_ok':s==m['sha256'],'bytes':n,'bytes_ok':n==m['bytes']}
20
+ U=np.empty(sum(n-15 for n in NW.values()),'V16'); k=0 # un seul tableau préalloué, rempli par blocs
21
+ for w,m in J['windows'].items():
22
+ a=np.fromfile(R+m['path'],np.uint8)
23
+ for s0 in range(0,len(a)-15,BLK):
24
+ q=keys(a[s0:s0+BLK+15]); U[k:k+len(q)]=q; k+=len(q)
25
+ del a
26
+ assert k==len(U); U.sort() # tri en place (ordre memcmp)
27
+ keep=np.ones(len(U),bool); keep[1:]=U[1:]!=U[:-1]; nu=int(keep.sum())
28
+ U[:nu]=U[keep]; U=U[:nu].copy(); del keep # dédoublonnage exact
29
+ def lookup(q): # -> (indices dans U, masque présent), exact octet à octet
30
+ i=np.searchsorted(U,q); j=np.minimum(i,len(U)-1); f=U[j]==q; return j,f
31
+ idx={}
32
+ for w,m in J['windows'].items():
33
+ a=np.fromfile(R+m['path'],np.uint8); ii=[]
34
+ for s0 in range(0,len(a)-15,BLK):
35
+ j,f=lookup(keys(a[s0:s0+BLK+15])); assert f.all(); ii.append(j.astype(np.int32))
36
+ idx[w]=np.concatenate(ii); assert len(idx[w])==NW[w]-15
37
+ for s,m in J['sources'].items():
38
+ t=time.time(); p=m['path']; sh=sha(p); found=np.zeros(len(U),bool); n=0; prev=b''
39
+ with open(p,'rb') as f:
40
+ for b in iter(lambda:f.read(BLK),b''):
41
+ a=np.frombuffer(prev+b,np.uint8); n+=len(b); prev=bytes(a[-15:])
42
+ if len(a)>=16:
43
+ j,fm=lookup(keys(a)); found[j[fm]]=True
44
+ pw={}
45
+ for w in idx:
46
+ hit=found[idx[w]]; N=len(hit)+15; d=np.zeros(N+1,np.int32); pos=np.nonzero(hit)[0]
47
+ np.add.at(d,pos,1); np.add.at(d,pos+16,-1); cov=np.cumsum(d[:N])>0
48
+ e=np.diff(np.concatenate(([0],cov.astype(np.int8),[0]))); runs=np.nonzero(e==-1)[0]-np.nonzero(e==1)[0]
49
+ c=m['per_window'][w]; mine={'bytes_covered_ge16':int(cov.sum()),'n_16gram_positions_shared':int(hit.sum()),
50
+ 'n_16grams_shared_unique':int(len(np.unique(idx[w][hit]))),'longest_covered_run_bytes':int(runs.max() if len(runs) else 0)}
51
+ mine['frac_covered_ge16']=mine['bytes_covered_ge16']/N
52
+ mine['checker']=c; mine['covered_match']=mine['bytes_covered_ge16']==c['bytes_covered_ge16']
53
+ mine['longest_match']=mine['longest_covered_run_bytes']==c['longest_covered_run_bytes']
54
+ mine['n16_match_positions']=mine['n_16gram_positions_shared']==c['n_16grams_shared']
55
+ mine['n16_match_unique']=mine['n_16grams_shared_unique']==c['n_16grams_shared']; pw[w]=mine
56
+ 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)}
57
+ print(s,round(time.time()-t),flush=True)
58
+ out['peak_rss_mb']=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024
59
+ json.dump(out,open(OUT,'w'),indent=1,ensure_ascii=False); print(out['peak_rss_mb'])
results/hashing/leak16_baseline_recount/results.json ADDED
@@ -0,0 +1,523 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "target": "/workspace/spira_shared/checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json",
3
+ "target_sha256": "a9ee65d4ad394ada0af487a0cb7eec66073f5440fb405ec19d5df641b5334598",
4
+ "windows": {
5
+ "fc2": {
6
+ "path": "/workspace/spira_shared/broad/freshcode_v2.bin",
7
+ "sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
8
+ "sha_ok": true,
9
+ "bytes": 199792,
10
+ "bytes_ok": true
11
+ },
12
+ "fresh_en": {
13
+ "path": "/workspace/spira_shared/spira_m7/windows/fresh_en.bin",
14
+ "sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
15
+ "sha_ok": true,
16
+ "bytes": 119763,
17
+ "bytes_ok": true
18
+ },
19
+ "fresh_fr": {
20
+ "path": "/workspace/spira_shared/spira_m7/windows/fresh_fr.bin",
21
+ "sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
22
+ "sha_ok": true,
23
+ "bytes": 1088688,
24
+ "bytes_ok": true
25
+ },
26
+ "test20k_old": {
27
+ "path": "/workspace/spira_shared/spira_m7/windows/test20k.bin",
28
+ "sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
29
+ "sha_ok": true,
30
+ "bytes": 319940,
31
+ "bytes_ok": true
32
+ },
33
+ "test_v3": {
34
+ "path": "/workspace/spira_shared/corpus_v3/test.bin",
35
+ "sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
36
+ "sha_ok": true,
37
+ "bytes": 3486653,
38
+ "bytes_ok": true
39
+ },
40
+ "queries": {
41
+ "path": "/workspace/spira_shared/spira_m7/windows/queries.bin",
42
+ "sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
43
+ "sha_ok": true,
44
+ "bytes": 27800,
45
+ "bytes_ok": true
46
+ }
47
+ },
48
+ "sources": {
49
+ "v1c_corpus": {
50
+ "path": "/workspace/spira_shared/hashing_gen/corpus_diverse_v1c/train.bin",
51
+ "sha256": "33577b70c819af76fe4737319e929f4c097b0c72f020e8b07b4baddbb1823439",
52
+ "sha_ok": true,
53
+ "bytes": 503301148,
54
+ "bytes_ok": true,
55
+ "per_window": {
56
+ "fc2": {
57
+ "bytes_covered_ge16": 145139,
58
+ "n_16gram_positions_shared": 71796,
59
+ "n_16grams_shared_unique": 38057,
60
+ "longest_covered_run_bytes": 419,
61
+ "frac_covered_ge16": 0.72645050852887,
62
+ "checker": {
63
+ "bytes": 199792,
64
+ "bytes_covered_ge16": 145139,
65
+ "frac_covered_ge16": 0.72645050852887,
66
+ "n_16grams_shared": 71796,
67
+ "longest_covered_run_bytes": 419
68
+ },
69
+ "covered_match": true,
70
+ "longest_match": true,
71
+ "n16_match_positions": true,
72
+ "n16_match_unique": false
73
+ },
74
+ "fresh_en": {
75
+ "bytes_covered_ge16": 93456,
76
+ "n_16gram_positions_shared": 34364,
77
+ "n_16grams_shared_unique": 32608,
78
+ "longest_covered_run_bytes": 338,
79
+ "frac_covered_ge16": 0.7803411738182912,
80
+ "checker": {
81
+ "bytes": 119763,
82
+ "bytes_covered_ge16": 93456,
83
+ "frac_covered_ge16": 0.7803411738182912,
84
+ "n_16grams_shared": 34364,
85
+ "longest_covered_run_bytes": 338
86
+ },
87
+ "covered_match": true,
88
+ "longest_match": true,
89
+ "n16_match_positions": true,
90
+ "n16_match_unique": false
91
+ },
92
+ "fresh_fr": {
93
+ "bytes_covered_ge16": 652302,
94
+ "n_16gram_positions_shared": 194384,
95
+ "n_16grams_shared_unique": 168701,
96
+ "longest_covered_run_bytes": 145,
97
+ "frac_covered_ge16": 0.5991633966756316,
98
+ "checker": {
99
+ "bytes": 1088688,
100
+ "bytes_covered_ge16": 652302,
101
+ "frac_covered_ge16": 0.5991633966756316,
102
+ "n_16grams_shared": 194384,
103
+ "longest_covered_run_bytes": 145
104
+ },
105
+ "covered_match": true,
106
+ "longest_match": true,
107
+ "n16_match_positions": true,
108
+ "n16_match_unique": false
109
+ },
110
+ "test20k_old": {
111
+ "bytes_covered_ge16": 235956,
112
+ "n_16gram_positions_shared": 91729,
113
+ "n_16grams_shared_unique": 73892,
114
+ "longest_covered_run_bytes": 266,
115
+ "frac_covered_ge16": 0.7375007813965119,
116
+ "checker": {
117
+ "bytes": 319940,
118
+ "bytes_covered_ge16": 235956,
119
+ "frac_covered_ge16": 0.7375007813965119,
120
+ "n_16grams_shared": 91729,
121
+ "longest_covered_run_bytes": 266
122
+ },
123
+ "covered_match": true,
124
+ "longest_match": true,
125
+ "n16_match_positions": true,
126
+ "n16_match_unique": false
127
+ },
128
+ "test_v3": {
129
+ "bytes_covered_ge16": 2433706,
130
+ "n_16gram_positions_shared": 859632,
131
+ "n_16grams_shared_unique": 667154,
132
+ "longest_covered_run_bytes": 353,
133
+ "frac_covered_ge16": 0.698006368858616,
134
+ "checker": {
135
+ "bytes": 3486653,
136
+ "bytes_covered_ge16": 2433706,
137
+ "frac_covered_ge16": 0.698006368858616,
138
+ "n_16grams_shared": 859632,
139
+ "longest_covered_run_bytes": 353
140
+ },
141
+ "covered_match": true,
142
+ "longest_match": true,
143
+ "n16_match_positions": true,
144
+ "n16_match_unique": false
145
+ },
146
+ "queries": {
147
+ "bytes_covered_ge16": 13583,
148
+ "n_16gram_positions_shared": 3748,
149
+ "n_16grams_shared_unique": 75,
150
+ "longest_covered_run_bytes": 53,
151
+ "frac_covered_ge16": 0.4885971223021583,
152
+ "checker": {
153
+ "bytes": 27800,
154
+ "bytes_covered_ge16": 13583,
155
+ "frac_covered_ge16": 0.4885971223021583,
156
+ "n_16grams_shared": 3748,
157
+ "longest_covered_run_bytes": 53
158
+ },
159
+ "covered_match": true,
160
+ "longest_match": true,
161
+ "n16_match_positions": true,
162
+ "n16_match_unique": false
163
+ }
164
+ },
165
+ "seconds": 351.0
166
+ },
167
+ "v1c_sample": {
168
+ "path": "/workspace/spira_shared/spira_m8/v1c/sample/v1c_sample.bin",
169
+ "sha256": "3d8b6181cbffb27e360758267e1084197dccad82ae05b868691758e1cf72eed4",
170
+ "sha_ok": true,
171
+ "bytes": 35948296,
172
+ "bytes_ok": true,
173
+ "per_window": {
174
+ "fc2": {
175
+ "bytes_covered_ge16": 100440,
176
+ "n_16gram_positions_shared": 40436,
177
+ "n_16grams_shared_unique": 15136,
178
+ "longest_covered_run_bytes": 191,
179
+ "frac_covered_ge16": 0.5027228317450149,
180
+ "checker": {
181
+ "bytes": 199792,
182
+ "bytes_covered_ge16": 100440,
183
+ "frac_covered_ge16": 0.5027228317450149,
184
+ "n_16grams_shared": 40436,
185
+ "longest_covered_run_bytes": 191
186
+ },
187
+ "covered_match": true,
188
+ "longest_match": true,
189
+ "n16_match_positions": true,
190
+ "n16_match_unique": false
191
+ },
192
+ "fresh_en": {
193
+ "bytes_covered_ge16": 52239,
194
+ "n_16gram_positions_shared": 11634,
195
+ "n_16grams_shared_unique": 10573,
196
+ "longest_covered_run_bytes": 109,
197
+ "frac_covered_ge16": 0.4361864682748428,
198
+ "checker": {
199
+ "bytes": 119763,
200
+ "bytes_covered_ge16": 52239,
201
+ "frac_covered_ge16": 0.4361864682748428,
202
+ "n_16grams_shared": 11634,
203
+ "longest_covered_run_bytes": 109
204
+ },
205
+ "covered_match": true,
206
+ "longest_match": true,
207
+ "n16_match_positions": true,
208
+ "n16_match_unique": false
209
+ },
210
+ "fresh_fr": {
211
+ "bytes_covered_ge16": 286582,
212
+ "n_16gram_positions_shared": 55095,
213
+ "n_16grams_shared_unique": 41336,
214
+ "longest_covered_run_bytes": 88,
215
+ "frac_covered_ge16": 0.2632361153976162,
216
+ "checker": {
217
+ "bytes": 1088688,
218
+ "bytes_covered_ge16": 286582,
219
+ "frac_covered_ge16": 0.2632361153976162,
220
+ "n_16grams_shared": 55095,
221
+ "longest_covered_run_bytes": 88
222
+ },
223
+ "covered_match": true,
224
+ "longest_match": true,
225
+ "n16_match_positions": true,
226
+ "n16_match_unique": false
227
+ },
228
+ "test20k_old": {
229
+ "bytes_covered_ge16": 128766,
230
+ "n_16gram_positions_shared": 36414,
231
+ "n_16grams_shared_unique": 23867,
232
+ "longest_covered_run_bytes": 205,
233
+ "frac_covered_ge16": 0.40246921297743327,
234
+ "checker": {
235
+ "bytes": 319940,
236
+ "bytes_covered_ge16": 128766,
237
+ "frac_covered_ge16": 0.40246921297743327,
238
+ "n_16grams_shared": 36414,
239
+ "longest_covered_run_bytes": 205
240
+ },
241
+ "covered_match": true,
242
+ "longest_match": true,
243
+ "n16_match_positions": true,
244
+ "n16_match_unique": false
245
+ },
246
+ "test_v3": {
247
+ "bytes_covered_ge16": 1316746,
248
+ "n_16gram_positions_shared": 295112,
249
+ "n_16grams_shared_unique": 185590,
250
+ "longest_covered_run_bytes": 129,
251
+ "frac_covered_ge16": 0.37765329672898335,
252
+ "checker": {
253
+ "bytes": 3486653,
254
+ "bytes_covered_ge16": 1316746,
255
+ "frac_covered_ge16": 0.37765329672898335,
256
+ "n_16grams_shared": 295112,
257
+ "longest_covered_run_bytes": 129
258
+ },
259
+ "covered_match": true,
260
+ "longest_match": true,
261
+ "n16_match_positions": true,
262
+ "n16_match_unique": false
263
+ },
264
+ "queries": {
265
+ "bytes_covered_ge16": 6200,
266
+ "n_16gram_positions_shared": 900,
267
+ "n_16grams_shared_unique": 18,
268
+ "longest_covered_run_bytes": 21,
269
+ "frac_covered_ge16": 0.22302158273381295,
270
+ "checker": {
271
+ "bytes": 27800,
272
+ "bytes_covered_ge16": 6200,
273
+ "frac_covered_ge16": 0.22302158273381295,
274
+ "n_16grams_shared": 900,
275
+ "longest_covered_run_bytes": 21
276
+ },
277
+ "covered_match": true,
278
+ "longest_match": true,
279
+ "n16_match_positions": true,
280
+ "n16_match_unique": false
281
+ }
282
+ },
283
+ "seconds": 22.5
284
+ },
285
+ "v1b_corpus": {
286
+ "path": "/workspace/spira_shared/hashing_gen/corpus_v1b/train.bin",
287
+ "sha256": "ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3",
288
+ "sha_ok": true,
289
+ "bytes": 520785883,
290
+ "bytes_ok": true,
291
+ "per_window": {
292
+ "fc2": {
293
+ "bytes_covered_ge16": 145183,
294
+ "n_16gram_positions_shared": 71837,
295
+ "n_16grams_shared_unique": 38098,
296
+ "longest_covered_run_bytes": 419,
297
+ "frac_covered_ge16": 0.7266707375670698,
298
+ "checker": {
299
+ "bytes": 199792,
300
+ "bytes_covered_ge16": 145183,
301
+ "frac_covered_ge16": 0.7266707375670698,
302
+ "n_16grams_shared": 71837,
303
+ "longest_covered_run_bytes": 419
304
+ },
305
+ "covered_match": true,
306
+ "longest_match": true,
307
+ "n16_match_positions": true,
308
+ "n16_match_unique": false
309
+ },
310
+ "fresh_en": {
311
+ "bytes_covered_ge16": 94752,
312
+ "n_16gram_positions_shared": 35873,
313
+ "n_16grams_shared_unique": 34072,
314
+ "longest_covered_run_bytes": 338,
315
+ "frac_covered_ge16": 0.7911625460284061,
316
+ "checker": {
317
+ "bytes": 119763,
318
+ "bytes_covered_ge16": 94752,
319
+ "frac_covered_ge16": 0.7911625460284061,
320
+ "n_16grams_shared": 35873,
321
+ "longest_covered_run_bytes": 338
322
+ },
323
+ "covered_match": true,
324
+ "longest_match": true,
325
+ "n16_match_positions": true,
326
+ "n16_match_unique": false
327
+ },
328
+ "fresh_fr": {
329
+ "bytes_covered_ge16": 652322,
330
+ "n_16gram_positions_shared": 194413,
331
+ "n_16grams_shared_unique": 168730,
332
+ "longest_covered_run_bytes": 145,
333
+ "frac_covered_ge16": 0.5991817674117837,
334
+ "checker": {
335
+ "bytes": 1088688,
336
+ "bytes_covered_ge16": 652322,
337
+ "frac_covered_ge16": 0.5991817674117837,
338
+ "n_16grams_shared": 194413,
339
+ "longest_covered_run_bytes": 145
340
+ },
341
+ "covered_match": true,
342
+ "longest_match": true,
343
+ "n16_match_positions": true,
344
+ "n16_match_unique": false
345
+ },
346
+ "test20k_old": {
347
+ "bytes_covered_ge16": 237099,
348
+ "n_16gram_positions_shared": 92792,
349
+ "n_16grams_shared_unique": 74894,
350
+ "longest_covered_run_bytes": 266,
351
+ "frac_covered_ge16": 0.7410733262486716,
352
+ "checker": {
353
+ "bytes": 319940,
354
+ "bytes_covered_ge16": 237099,
355
+ "frac_covered_ge16": 0.7410733262486716,
356
+ "n_16grams_shared": 92792,
357
+ "longest_covered_run_bytes": 266
358
+ },
359
+ "covered_match": true,
360
+ "longest_match": true,
361
+ "n16_match_positions": true,
362
+ "n16_match_unique": false
363
+ },
364
+ "test_v3": {
365
+ "bytes_covered_ge16": 2442104,
366
+ "n_16gram_positions_shared": 866084,
367
+ "n_16grams_shared_unique": 673440,
368
+ "longest_covered_run_bytes": 353,
369
+ "frac_covered_ge16": 0.7004149825061455,
370
+ "checker": {
371
+ "bytes": 3486653,
372
+ "bytes_covered_ge16": 2442104,
373
+ "frac_covered_ge16": 0.7004149825061455,
374
+ "n_16grams_shared": 866084,
375
+ "longest_covered_run_bytes": 353
376
+ },
377
+ "covered_match": true,
378
+ "longest_match": true,
379
+ "n16_match_positions": true,
380
+ "n16_match_unique": false
381
+ },
382
+ "queries": {
383
+ "bytes_covered_ge16": 15133,
384
+ "n_16gram_positions_shared": 4398,
385
+ "n_16grams_shared_unique": 88,
386
+ "longest_covered_run_bytes": 53,
387
+ "frac_covered_ge16": 0.5443525179856115,
388
+ "checker": {
389
+ "bytes": 27800,
390
+ "bytes_covered_ge16": 15133,
391
+ "frac_covered_ge16": 0.5443525179856115,
392
+ "n_16grams_shared": 4398,
393
+ "longest_covered_run_bytes": 53
394
+ },
395
+ "covered_match": true,
396
+ "longest_match": true,
397
+ "n16_match_positions": true,
398
+ "n16_match_unique": false
399
+ }
400
+ },
401
+ "seconds": 358.2
402
+ },
403
+ "v1b_sample": {
404
+ "path": "/workspace/spira_shared/hashing_gen/m8_v1b/sample/v1b_sample.bin",
405
+ "sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
406
+ "sha_ok": true,
407
+ "bytes": 35128951,
408
+ "bytes_ok": true,
409
+ "per_window": {
410
+ "fc2": {
411
+ "bytes_covered_ge16": 100880,
412
+ "n_16gram_positions_shared": 40698,
413
+ "n_16grams_shared_unique": 15264,
414
+ "longest_covered_run_bytes": 277,
415
+ "frac_covered_ge16": 0.5049251221270121,
416
+ "checker": {
417
+ "bytes": 199792,
418
+ "bytes_covered_ge16": 100880,
419
+ "frac_covered_ge16": 0.5049251221270121,
420
+ "n_16grams_shared": 40698,
421
+ "longest_covered_run_bytes": 277
422
+ },
423
+ "covered_match": true,
424
+ "longest_match": true,
425
+ "n16_match_positions": true,
426
+ "n16_match_unique": false
427
+ },
428
+ "fresh_en": {
429
+ "bytes_covered_ge16": 55107,
430
+ "n_16gram_positions_shared": 12710,
431
+ "n_16grams_shared_unique": 11534,
432
+ "longest_covered_run_bytes": 108,
433
+ "frac_covered_ge16": 0.46013376418426394,
434
+ "checker": {
435
+ "bytes": 119763,
436
+ "bytes_covered_ge16": 55107,
437
+ "frac_covered_ge16": 0.46013376418426394,
438
+ "n_16grams_shared": 12710,
439
+ "longest_covered_run_bytes": 108
440
+ },
441
+ "covered_match": true,
442
+ "longest_match": true,
443
+ "n16_match_positions": true,
444
+ "n16_match_unique": false
445
+ },
446
+ "fresh_fr": {
447
+ "bytes_covered_ge16": 283182,
448
+ "n_16gram_positions_shared": 55308,
449
+ "n_16grams_shared_unique": 41593,
450
+ "longest_covered_run_bytes": 76,
451
+ "frac_covered_ge16": 0.26011309025175255,
452
+ "checker": {
453
+ "bytes": 1088688,
454
+ "bytes_covered_ge16": 283182,
455
+ "frac_covered_ge16": 0.26011309025175255,
456
+ "n_16grams_shared": 55308,
457
+ "longest_covered_run_bytes": 76
458
+ },
459
+ "covered_match": true,
460
+ "longest_match": true,
461
+ "n16_match_positions": true,
462
+ "n16_match_unique": false
463
+ },
464
+ "test20k_old": {
465
+ "bytes_covered_ge16": 128263,
466
+ "n_16gram_positions_shared": 36178,
467
+ "n_16grams_shared_unique": 23521,
468
+ "longest_covered_run_bytes": 166,
469
+ "frac_covered_ge16": 0.40089704319559916,
470
+ "checker": {
471
+ "bytes": 319940,
472
+ "bytes_covered_ge16": 128263,
473
+ "frac_covered_ge16": 0.40089704319559916,
474
+ "n_16grams_shared": 36178,
475
+ "longest_covered_run_bytes": 166
476
+ },
477
+ "covered_match": true,
478
+ "longest_match": true,
479
+ "n16_match_positions": true,
480
+ "n16_match_unique": false
481
+ },
482
+ "test_v3": {
483
+ "bytes_covered_ge16": 1189410,
484
+ "n_16gram_positions_shared": 260934,
485
+ "n_16grams_shared_unique": 174208,
486
+ "longest_covered_run_bytes": 105,
487
+ "frac_covered_ge16": 0.34113231227770585,
488
+ "checker": {
489
+ "bytes": 3486653,
490
+ "bytes_covered_ge16": 1189410,
491
+ "frac_covered_ge16": 0.34113231227770585,
492
+ "n_16grams_shared": 260934,
493
+ "longest_covered_run_bytes": 105
494
+ },
495
+ "covered_match": true,
496
+ "longest_match": true,
497
+ "n16_match_positions": true,
498
+ "n16_match_unique": false
499
+ },
500
+ "queries": {
501
+ "bytes_covered_ge16": 8500,
502
+ "n_16gram_positions_shared": 1800,
503
+ "n_16grams_shared_unique": 36,
504
+ "longest_covered_run_bytes": 36,
505
+ "frac_covered_ge16": 0.3057553956834532,
506
+ "checker": {
507
+ "bytes": 27800,
508
+ "bytes_covered_ge16": 8500,
509
+ "frac_covered_ge16": 0.3057553956834532,
510
+ "n_16grams_shared": 1800,
511
+ "longest_covered_run_bytes": 36
512
+ },
513
+ "covered_match": true,
514
+ "longest_match": true,
515
+ "n16_match_positions": true,
516
+ "n16_match_unique": false
517
+ }
518
+ },
519
+ "seconds": 22.3
520
+ }
521
+ },
522
+ "peak_rss_mb": 364.83984375
523
+ }
results/hashing/leak16_baseline_recount/results_stream.json ADDED
@@ -0,0 +1,523 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "target": "/workspace/spira_shared/checker/recount/m8_v1d_eval_prep/leak16_baseline_v1b_v1c.json",
3
+ "target_sha256": "a9ee65d4ad394ada0af487a0cb7eec66073f5440fb405ec19d5df641b5334598",
4
+ "windows": {
5
+ "fc2": {
6
+ "path": "/workspace/spira_shared/broad/freshcode_v2.bin",
7
+ "sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
8
+ "sha_ok": true,
9
+ "bytes": 199792,
10
+ "bytes_ok": true
11
+ },
12
+ "fresh_en": {
13
+ "path": "/workspace/spira_shared/spira_m7/windows/fresh_en.bin",
14
+ "sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
15
+ "sha_ok": true,
16
+ "bytes": 119763,
17
+ "bytes_ok": true
18
+ },
19
+ "fresh_fr": {
20
+ "path": "/workspace/spira_shared/spira_m7/windows/fresh_fr.bin",
21
+ "sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
22
+ "sha_ok": true,
23
+ "bytes": 1088688,
24
+ "bytes_ok": true
25
+ },
26
+ "test20k_old": {
27
+ "path": "/workspace/spira_shared/spira_m7/windows/test20k.bin",
28
+ "sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
29
+ "sha_ok": true,
30
+ "bytes": 319940,
31
+ "bytes_ok": true
32
+ },
33
+ "test_v3": {
34
+ "path": "/workspace/spira_shared/corpus_v3/test.bin",
35
+ "sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
36
+ "sha_ok": true,
37
+ "bytes": 3486653,
38
+ "bytes_ok": true
39
+ },
40
+ "queries": {
41
+ "path": "/workspace/spira_shared/spira_m7/windows/queries.bin",
42
+ "sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
43
+ "sha_ok": true,
44
+ "bytes": 27800,
45
+ "bytes_ok": true
46
+ }
47
+ },
48
+ "sources": {
49
+ "v1c_corpus": {
50
+ "path": "/workspace/spira_shared/hashing_gen/corpus_diverse_v1c/train.bin",
51
+ "sha256": "33577b70c819af76fe4737319e929f4c097b0c72f020e8b07b4baddbb1823439",
52
+ "sha_ok": true,
53
+ "bytes": 503301148,
54
+ "bytes_ok": true,
55
+ "per_window": {
56
+ "fc2": {
57
+ "bytes_covered_ge16": 145139,
58
+ "n_16gram_positions_shared": 71796,
59
+ "n_16grams_shared_unique": 38057,
60
+ "longest_covered_run_bytes": 419,
61
+ "frac_covered_ge16": 0.72645050852887,
62
+ "checker": {
63
+ "bytes": 199792,
64
+ "bytes_covered_ge16": 145139,
65
+ "frac_covered_ge16": 0.72645050852887,
66
+ "n_16grams_shared": 71796,
67
+ "longest_covered_run_bytes": 419
68
+ },
69
+ "covered_match": true,
70
+ "longest_match": true,
71
+ "n16_match_positions": true,
72
+ "n16_match_unique": false
73
+ },
74
+ "fresh_en": {
75
+ "bytes_covered_ge16": 93456,
76
+ "n_16gram_positions_shared": 34364,
77
+ "n_16grams_shared_unique": 32608,
78
+ "longest_covered_run_bytes": 338,
79
+ "frac_covered_ge16": 0.7803411738182912,
80
+ "checker": {
81
+ "bytes": 119763,
82
+ "bytes_covered_ge16": 93456,
83
+ "frac_covered_ge16": 0.7803411738182912,
84
+ "n_16grams_shared": 34364,
85
+ "longest_covered_run_bytes": 338
86
+ },
87
+ "covered_match": true,
88
+ "longest_match": true,
89
+ "n16_match_positions": true,
90
+ "n16_match_unique": false
91
+ },
92
+ "fresh_fr": {
93
+ "bytes_covered_ge16": 652302,
94
+ "n_16gram_positions_shared": 194384,
95
+ "n_16grams_shared_unique": 168701,
96
+ "longest_covered_run_bytes": 145,
97
+ "frac_covered_ge16": 0.5991633966756316,
98
+ "checker": {
99
+ "bytes": 1088688,
100
+ "bytes_covered_ge16": 652302,
101
+ "frac_covered_ge16": 0.5991633966756316,
102
+ "n_16grams_shared": 194384,
103
+ "longest_covered_run_bytes": 145
104
+ },
105
+ "covered_match": true,
106
+ "longest_match": true,
107
+ "n16_match_positions": true,
108
+ "n16_match_unique": false
109
+ },
110
+ "test20k_old": {
111
+ "bytes_covered_ge16": 235956,
112
+ "n_16gram_positions_shared": 91729,
113
+ "n_16grams_shared_unique": 73892,
114
+ "longest_covered_run_bytes": 266,
115
+ "frac_covered_ge16": 0.7375007813965119,
116
+ "checker": {
117
+ "bytes": 319940,
118
+ "bytes_covered_ge16": 235956,
119
+ "frac_covered_ge16": 0.7375007813965119,
120
+ "n_16grams_shared": 91729,
121
+ "longest_covered_run_bytes": 266
122
+ },
123
+ "covered_match": true,
124
+ "longest_match": true,
125
+ "n16_match_positions": true,
126
+ "n16_match_unique": false
127
+ },
128
+ "test_v3": {
129
+ "bytes_covered_ge16": 2433706,
130
+ "n_16gram_positions_shared": 859632,
131
+ "n_16grams_shared_unique": 667154,
132
+ "longest_covered_run_bytes": 353,
133
+ "frac_covered_ge16": 0.698006368858616,
134
+ "checker": {
135
+ "bytes": 3486653,
136
+ "bytes_covered_ge16": 2433706,
137
+ "frac_covered_ge16": 0.698006368858616,
138
+ "n_16grams_shared": 859632,
139
+ "longest_covered_run_bytes": 353
140
+ },
141
+ "covered_match": true,
142
+ "longest_match": true,
143
+ "n16_match_positions": true,
144
+ "n16_match_unique": false
145
+ },
146
+ "queries": {
147
+ "bytes_covered_ge16": 13583,
148
+ "n_16gram_positions_shared": 3748,
149
+ "n_16grams_shared_unique": 75,
150
+ "longest_covered_run_bytes": 53,
151
+ "frac_covered_ge16": 0.4885971223021583,
152
+ "checker": {
153
+ "bytes": 27800,
154
+ "bytes_covered_ge16": 13583,
155
+ "frac_covered_ge16": 0.4885971223021583,
156
+ "n_16grams_shared": 3748,
157
+ "longest_covered_run_bytes": 53
158
+ },
159
+ "covered_match": true,
160
+ "longest_match": true,
161
+ "n16_match_positions": true,
162
+ "n16_match_unique": false
163
+ }
164
+ },
165
+ "seconds": 247.4
166
+ },
167
+ "v1c_sample": {
168
+ "path": "/workspace/spira_shared/spira_m8/v1c/sample/v1c_sample.bin",
169
+ "sha256": "3d8b6181cbffb27e360758267e1084197dccad82ae05b868691758e1cf72eed4",
170
+ "sha_ok": true,
171
+ "bytes": 35948296,
172
+ "bytes_ok": true,
173
+ "per_window": {
174
+ "fc2": {
175
+ "bytes_covered_ge16": 100440,
176
+ "n_16gram_positions_shared": 40436,
177
+ "n_16grams_shared_unique": 15136,
178
+ "longest_covered_run_bytes": 191,
179
+ "frac_covered_ge16": 0.5027228317450149,
180
+ "checker": {
181
+ "bytes": 199792,
182
+ "bytes_covered_ge16": 100440,
183
+ "frac_covered_ge16": 0.5027228317450149,
184
+ "n_16grams_shared": 40436,
185
+ "longest_covered_run_bytes": 191
186
+ },
187
+ "covered_match": true,
188
+ "longest_match": true,
189
+ "n16_match_positions": true,
190
+ "n16_match_unique": false
191
+ },
192
+ "fresh_en": {
193
+ "bytes_covered_ge16": 52239,
194
+ "n_16gram_positions_shared": 11634,
195
+ "n_16grams_shared_unique": 10573,
196
+ "longest_covered_run_bytes": 109,
197
+ "frac_covered_ge16": 0.4361864682748428,
198
+ "checker": {
199
+ "bytes": 119763,
200
+ "bytes_covered_ge16": 52239,
201
+ "frac_covered_ge16": 0.4361864682748428,
202
+ "n_16grams_shared": 11634,
203
+ "longest_covered_run_bytes": 109
204
+ },
205
+ "covered_match": true,
206
+ "longest_match": true,
207
+ "n16_match_positions": true,
208
+ "n16_match_unique": false
209
+ },
210
+ "fresh_fr": {
211
+ "bytes_covered_ge16": 286582,
212
+ "n_16gram_positions_shared": 55095,
213
+ "n_16grams_shared_unique": 41336,
214
+ "longest_covered_run_bytes": 88,
215
+ "frac_covered_ge16": 0.2632361153976162,
216
+ "checker": {
217
+ "bytes": 1088688,
218
+ "bytes_covered_ge16": 286582,
219
+ "frac_covered_ge16": 0.2632361153976162,
220
+ "n_16grams_shared": 55095,
221
+ "longest_covered_run_bytes": 88
222
+ },
223
+ "covered_match": true,
224
+ "longest_match": true,
225
+ "n16_match_positions": true,
226
+ "n16_match_unique": false
227
+ },
228
+ "test20k_old": {
229
+ "bytes_covered_ge16": 128766,
230
+ "n_16gram_positions_shared": 36414,
231
+ "n_16grams_shared_unique": 23867,
232
+ "longest_covered_run_bytes": 205,
233
+ "frac_covered_ge16": 0.40246921297743327,
234
+ "checker": {
235
+ "bytes": 319940,
236
+ "bytes_covered_ge16": 128766,
237
+ "frac_covered_ge16": 0.40246921297743327,
238
+ "n_16grams_shared": 36414,
239
+ "longest_covered_run_bytes": 205
240
+ },
241
+ "covered_match": true,
242
+ "longest_match": true,
243
+ "n16_match_positions": true,
244
+ "n16_match_unique": false
245
+ },
246
+ "test_v3": {
247
+ "bytes_covered_ge16": 1316746,
248
+ "n_16gram_positions_shared": 295112,
249
+ "n_16grams_shared_unique": 185590,
250
+ "longest_covered_run_bytes": 129,
251
+ "frac_covered_ge16": 0.37765329672898335,
252
+ "checker": {
253
+ "bytes": 3486653,
254
+ "bytes_covered_ge16": 1316746,
255
+ "frac_covered_ge16": 0.37765329672898335,
256
+ "n_16grams_shared": 295112,
257
+ "longest_covered_run_bytes": 129
258
+ },
259
+ "covered_match": true,
260
+ "longest_match": true,
261
+ "n16_match_positions": true,
262
+ "n16_match_unique": false
263
+ },
264
+ "queries": {
265
+ "bytes_covered_ge16": 6200,
266
+ "n_16gram_positions_shared": 900,
267
+ "n_16grams_shared_unique": 18,
268
+ "longest_covered_run_bytes": 21,
269
+ "frac_covered_ge16": 0.22302158273381295,
270
+ "checker": {
271
+ "bytes": 27800,
272
+ "bytes_covered_ge16": 6200,
273
+ "frac_covered_ge16": 0.22302158273381295,
274
+ "n_16grams_shared": 900,
275
+ "longest_covered_run_bytes": 21
276
+ },
277
+ "covered_match": true,
278
+ "longest_match": true,
279
+ "n16_match_positions": true,
280
+ "n16_match_unique": false
281
+ }
282
+ },
283
+ "seconds": 17.9
284
+ },
285
+ "v1b_corpus": {
286
+ "path": "/workspace/spira_shared/hashing_gen/corpus_v1b/train.bin",
287
+ "sha256": "ddf67ffb4e9f340aca7a130639580211e1eaa4b4e850cec93fb19d222f63ddb3",
288
+ "sha_ok": true,
289
+ "bytes": 520785883,
290
+ "bytes_ok": true,
291
+ "per_window": {
292
+ "fc2": {
293
+ "bytes_covered_ge16": 145183,
294
+ "n_16gram_positions_shared": 71837,
295
+ "n_16grams_shared_unique": 38098,
296
+ "longest_covered_run_bytes": 419,
297
+ "frac_covered_ge16": 0.7266707375670698,
298
+ "checker": {
299
+ "bytes": 199792,
300
+ "bytes_covered_ge16": 145183,
301
+ "frac_covered_ge16": 0.7266707375670698,
302
+ "n_16grams_shared": 71837,
303
+ "longest_covered_run_bytes": 419
304
+ },
305
+ "covered_match": true,
306
+ "longest_match": true,
307
+ "n16_match_positions": true,
308
+ "n16_match_unique": false
309
+ },
310
+ "fresh_en": {
311
+ "bytes_covered_ge16": 94752,
312
+ "n_16gram_positions_shared": 35873,
313
+ "n_16grams_shared_unique": 34072,
314
+ "longest_covered_run_bytes": 338,
315
+ "frac_covered_ge16": 0.7911625460284061,
316
+ "checker": {
317
+ "bytes": 119763,
318
+ "bytes_covered_ge16": 94752,
319
+ "frac_covered_ge16": 0.7911625460284061,
320
+ "n_16grams_shared": 35873,
321
+ "longest_covered_run_bytes": 338
322
+ },
323
+ "covered_match": true,
324
+ "longest_match": true,
325
+ "n16_match_positions": true,
326
+ "n16_match_unique": false
327
+ },
328
+ "fresh_fr": {
329
+ "bytes_covered_ge16": 652322,
330
+ "n_16gram_positions_shared": 194413,
331
+ "n_16grams_shared_unique": 168730,
332
+ "longest_covered_run_bytes": 145,
333
+ "frac_covered_ge16": 0.5991817674117837,
334
+ "checker": {
335
+ "bytes": 1088688,
336
+ "bytes_covered_ge16": 652322,
337
+ "frac_covered_ge16": 0.5991817674117837,
338
+ "n_16grams_shared": 194413,
339
+ "longest_covered_run_bytes": 145
340
+ },
341
+ "covered_match": true,
342
+ "longest_match": true,
343
+ "n16_match_positions": true,
344
+ "n16_match_unique": false
345
+ },
346
+ "test20k_old": {
347
+ "bytes_covered_ge16": 237099,
348
+ "n_16gram_positions_shared": 92792,
349
+ "n_16grams_shared_unique": 74894,
350
+ "longest_covered_run_bytes": 266,
351
+ "frac_covered_ge16": 0.7410733262486716,
352
+ "checker": {
353
+ "bytes": 319940,
354
+ "bytes_covered_ge16": 237099,
355
+ "frac_covered_ge16": 0.7410733262486716,
356
+ "n_16grams_shared": 92792,
357
+ "longest_covered_run_bytes": 266
358
+ },
359
+ "covered_match": true,
360
+ "longest_match": true,
361
+ "n16_match_positions": true,
362
+ "n16_match_unique": false
363
+ },
364
+ "test_v3": {
365
+ "bytes_covered_ge16": 2442104,
366
+ "n_16gram_positions_shared": 866084,
367
+ "n_16grams_shared_unique": 673440,
368
+ "longest_covered_run_bytes": 353,
369
+ "frac_covered_ge16": 0.7004149825061455,
370
+ "checker": {
371
+ "bytes": 3486653,
372
+ "bytes_covered_ge16": 2442104,
373
+ "frac_covered_ge16": 0.7004149825061455,
374
+ "n_16grams_shared": 866084,
375
+ "longest_covered_run_bytes": 353
376
+ },
377
+ "covered_match": true,
378
+ "longest_match": true,
379
+ "n16_match_positions": true,
380
+ "n16_match_unique": false
381
+ },
382
+ "queries": {
383
+ "bytes_covered_ge16": 15133,
384
+ "n_16gram_positions_shared": 4398,
385
+ "n_16grams_shared_unique": 88,
386
+ "longest_covered_run_bytes": 53,
387
+ "frac_covered_ge16": 0.5443525179856115,
388
+ "checker": {
389
+ "bytes": 27800,
390
+ "bytes_covered_ge16": 15133,
391
+ "frac_covered_ge16": 0.5443525179856115,
392
+ "n_16grams_shared": 4398,
393
+ "longest_covered_run_bytes": 53
394
+ },
395
+ "covered_match": true,
396
+ "longest_match": true,
397
+ "n16_match_positions": true,
398
+ "n16_match_unique": false
399
+ }
400
+ },
401
+ "seconds": 266.2
402
+ },
403
+ "v1b_sample": {
404
+ "path": "/workspace/spira_shared/hashing_gen/m8_v1b/sample/v1b_sample.bin",
405
+ "sha256": "9ea562e44f708adda470c53144dcae748796d77b98039b5fc52ac962d877370b",
406
+ "sha_ok": true,
407
+ "bytes": 35128951,
408
+ "bytes_ok": true,
409
+ "per_window": {
410
+ "fc2": {
411
+ "bytes_covered_ge16": 100880,
412
+ "n_16gram_positions_shared": 40698,
413
+ "n_16grams_shared_unique": 15264,
414
+ "longest_covered_run_bytes": 277,
415
+ "frac_covered_ge16": 0.5049251221270121,
416
+ "checker": {
417
+ "bytes": 199792,
418
+ "bytes_covered_ge16": 100880,
419
+ "frac_covered_ge16": 0.5049251221270121,
420
+ "n_16grams_shared": 40698,
421
+ "longest_covered_run_bytes": 277
422
+ },
423
+ "covered_match": true,
424
+ "longest_match": true,
425
+ "n16_match_positions": true,
426
+ "n16_match_unique": false
427
+ },
428
+ "fresh_en": {
429
+ "bytes_covered_ge16": 55107,
430
+ "n_16gram_positions_shared": 12710,
431
+ "n_16grams_shared_unique": 11534,
432
+ "longest_covered_run_bytes": 108,
433
+ "frac_covered_ge16": 0.46013376418426394,
434
+ "checker": {
435
+ "bytes": 119763,
436
+ "bytes_covered_ge16": 55107,
437
+ "frac_covered_ge16": 0.46013376418426394,
438
+ "n_16grams_shared": 12710,
439
+ "longest_covered_run_bytes": 108
440
+ },
441
+ "covered_match": true,
442
+ "longest_match": true,
443
+ "n16_match_positions": true,
444
+ "n16_match_unique": false
445
+ },
446
+ "fresh_fr": {
447
+ "bytes_covered_ge16": 283182,
448
+ "n_16gram_positions_shared": 55308,
449
+ "n_16grams_shared_unique": 41593,
450
+ "longest_covered_run_bytes": 76,
451
+ "frac_covered_ge16": 0.26011309025175255,
452
+ "checker": {
453
+ "bytes": 1088688,
454
+ "bytes_covered_ge16": 283182,
455
+ "frac_covered_ge16": 0.26011309025175255,
456
+ "n_16grams_shared": 55308,
457
+ "longest_covered_run_bytes": 76
458
+ },
459
+ "covered_match": true,
460
+ "longest_match": true,
461
+ "n16_match_positions": true,
462
+ "n16_match_unique": false
463
+ },
464
+ "test20k_old": {
465
+ "bytes_covered_ge16": 128263,
466
+ "n_16gram_positions_shared": 36178,
467
+ "n_16grams_shared_unique": 23521,
468
+ "longest_covered_run_bytes": 166,
469
+ "frac_covered_ge16": 0.40089704319559916,
470
+ "checker": {
471
+ "bytes": 319940,
472
+ "bytes_covered_ge16": 128263,
473
+ "frac_covered_ge16": 0.40089704319559916,
474
+ "n_16grams_shared": 36178,
475
+ "longest_covered_run_bytes": 166
476
+ },
477
+ "covered_match": true,
478
+ "longest_match": true,
479
+ "n16_match_positions": true,
480
+ "n16_match_unique": false
481
+ },
482
+ "test_v3": {
483
+ "bytes_covered_ge16": 1189410,
484
+ "n_16gram_positions_shared": 260934,
485
+ "n_16grams_shared_unique": 174208,
486
+ "longest_covered_run_bytes": 105,
487
+ "frac_covered_ge16": 0.34113231227770585,
488
+ "checker": {
489
+ "bytes": 3486653,
490
+ "bytes_covered_ge16": 1189410,
491
+ "frac_covered_ge16": 0.34113231227770585,
492
+ "n_16grams_shared": 260934,
493
+ "longest_covered_run_bytes": 105
494
+ },
495
+ "covered_match": true,
496
+ "longest_match": true,
497
+ "n16_match_positions": true,
498
+ "n16_match_unique": false
499
+ },
500
+ "queries": {
501
+ "bytes_covered_ge16": 8500,
502
+ "n_16gram_positions_shared": 1800,
503
+ "n_16grams_shared_unique": 36,
504
+ "longest_covered_run_bytes": 36,
505
+ "frac_covered_ge16": 0.3057553956834532,
506
+ "checker": {
507
+ "bytes": 27800,
508
+ "bytes_covered_ge16": 8500,
509
+ "frac_covered_ge16": 0.3057553956834532,
510
+ "n_16grams_shared": 1800,
511
+ "longest_covered_run_bytes": 36
512
+ },
513
+ "covered_match": true,
514
+ "longest_match": true,
515
+ "n16_match_positions": true,
516
+ "n16_match_unique": false
517
+ }
518
+ },
519
+ "seconds": 18.5
520
+ }
521
+ },
522
+ "peak_rss_mb": 239.453125
523
+ }
results/hashing/leak16_reconcile_r3/REPORT.md ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Recompte indépendant leak16 sur hf_ready_run_iii_r3 (SPIRA Hashing)
2
+ 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.
3
+ 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.
4
+
5
+ ## r3 (plus long run partagé, octets)
6
+ | fichier | sha256 | 6 fenêtres | 8 fenêtres | ≥16 ? |
7
+ |:-:|:-:|:-:|:-:|:-:|
8
+ | ADDENDUM.md | 581e7c2f… | 12 | 12 | non |
9
+ | README.md | 54461b93… | 14 | 14 | non |
10
+ | REPORT.md | fe293479… | 14 | 14 | non |
11
+ | res.json | 23751f0b… | 6 | 6 | non |
12
+ | res_add.json | 63986056… | 5 | 5 | non |
13
+ | rss.py | 4dfb1c2e… | 13 | 13 | non |
14
+ r3 : PASS strict (max 14 o) avec 6 et 8 fenêtres. Comparaison Checker r3 : NON PUBLIÉE.
15
+
16
+ ## Auto-contrôle de l'outil sur r2 contre le tableau Checker 9d7d8383
17
+ | fichier | nous 6 | Checker 6 | nous 8 | Checker 8 | statut |
18
+ |:-:|:-:|:-:|:-:|:-:|:-:|
19
+ | ADDENDUM.md | 12 | 12 | 32 | 32 | MATCH |
20
+ | README.md | 12 | 12 | 12 | 12 | MATCH |
21
+ | REPORT.md | 13 | 13 | 32 | 32 | MATCH |
22
+ | res.json | 6 | 6 | 6 | 6 | MATCH |
23
+ | res_add.json | 5 | 5 | 5 | 5 | MATCH |
24
+ | rss.py | 13 | 13 | 13 | 13 | MATCH |
25
+ | runner.sh | 11 | 11 | 17 | 17 | MATCH |
26
+ 7/7 MATCH, écart 0 o (colonnes « Hashing réf. 6 » et « Hashing réf. 8 » du rapport Checker).
27
+ Sorties : recount_r3.json, selfcheck_r2.json. Rien poussé.
results/hashing/leak16_reconcile_r3/SHA256SUMS ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ 41b6bd9eceff955a366c6bd49aa384470e184bde87cc6c509d21c531c6a6c927 REPORT.md
2
+ 9454d2178cec2f56e28c6c686d8128ba14ae6bcf954e249e26000dc1525aa083 recount.py
3
+ a94c0833168ea8cf74b7bcc023300b6ad7d66aa564c9fbeac4f8289e91612061 recount_r3.json
4
+ 01cb94f62f931a423fbbf190f2ed10d30e5d306069a164c24cbce6d6768fb113 ref_8w.json
5
+ 7cb45f9e469e4779993b224b4f75cd73679c3ca324fd85d9741c511b93081a90 selfcheck_r2.json
results/hashing/leak16_reconcile_r3/recount.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Recompte indépendant leak16 : plus long run d'octets bruts partagé (fichier x fenêtres), streaming par blocs de 256 Ko via memmap.
2
+ import json,sys,os,hashlib,resource,numpy as np
3
+ from numpy.lib.stride_tricks import sliding_window_view as swv
4
+ S='/workspace/spira_shared/'; D=sys.argv[1]; ref=json.load(open(sys.argv[2]))['windows']
5
+ def wp(m): p=m['path']; return p if p.startswith('/') else S+p
6
+ W={}
7
+ for k,m in ref.items():
8
+ h=hashlib.sha256(); a=np.memmap(wp(m),np.uint8,'r')
9
+ for s in range(0,len(a),1<<20): h.update(a[s:s+(1<<20)].tobytes())
10
+ assert h.hexdigest()==m['sha256'],k; W[k]=a
11
+ 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}')
12
+ def hit(fb,k,names):
13
+ q=np.unique(g(fb,k)); out=[]
14
+ if not len(q): return out
15
+ for n in names:
16
+ a=W[n]
17
+ for s in range(0,max(len(a)-k+1,1),1<<18):
18
+ x=g(np.asarray(a[s:s+(1<<18)+k-1]),k); i=np.minimum(np.searchsorted(q,x),len(q)-1)
19
+ if (q[i]==x).any(): out.append(n); break
20
+ return out
21
+ def longest(fb,names):
22
+ lo,hi=0,min(len(fb),128)
23
+ while lo<hi:
24
+ m=(lo+hi+1)//2
25
+ if hit(fb,m,names): lo=m
26
+ else: hi=m-1
27
+ return lo,(hit(fb,lo,names) if lo else [])
28
+ six=['fc2','fresh_en','fresh_fr','test20k_old','test_v3','queries']; eight=six+['bg1_test','neither_code']
29
+ res={}
30
+ for f in sorted(os.listdir(D)):
31
+ if f=='SHA256SUMS': continue
32
+ b=open(os.path.join(D,f),'rb').read(); fb=np.frombuffer(b,np.uint8)
33
+ l6,w6=longest(fb,six); l8,w8=longest(fb,eight)
34
+ res[f]={'sha256':hashlib.sha256(b).hexdigest(),'max6':l6,'win6':w6,'max8':l8,'win8':w8}
35
+ print(json.dumps({'dir':D,'files':res,'peak_rss_mb':resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024},indent=1))
results/hashing/leak16_reconcile_r3/recount_r3.json ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "dir": "/workspace/spira_shared/hashing_gen/precal_ratio_ckpt/hf_ready_run_iii_r3",
3
+ "files": {
4
+ "ADDENDUM.md": {
5
+ "sha256": "581e7c2ffd9ddda09253b4e879b1fac36e7c40e6879d8ed3330f8f4e344764e4",
6
+ "max6": 12,
7
+ "win6": [
8
+ "fresh_fr",
9
+ "test_v3"
10
+ ],
11
+ "max8": 12,
12
+ "win8": [
13
+ "fresh_fr",
14
+ "test_v3"
15
+ ]
16
+ },
17
+ "README.md": {
18
+ "sha256": "54461b939713662e96ba6394ebbe705233b9780806fb05207c9cea034e7e98ed",
19
+ "max6": 14,
20
+ "win6": [
21
+ "fresh_fr"
22
+ ],
23
+ "max8": 14,
24
+ "win8": [
25
+ "fresh_fr"
26
+ ]
27
+ },
28
+ "REPORT.md": {
29
+ "sha256": "fe2934795f726ddd8113e72267c52bfd6252128850a5c0f10cbfce9676e83576",
30
+ "max6": 14,
31
+ "win6": [
32
+ "fresh_fr"
33
+ ],
34
+ "max8": 14,
35
+ "win8": [
36
+ "fresh_fr"
37
+ ]
38
+ },
39
+ "res.json": {
40
+ "sha256": "23751f0b10d4568549f93c07214a36249e5950cddf07bd6f64049864d355c939",
41
+ "max6": 6,
42
+ "win6": [
43
+ "test20k_old",
44
+ "test_v3"
45
+ ],
46
+ "max8": 6,
47
+ "win8": [
48
+ "test20k_old",
49
+ "test_v3",
50
+ "bg1_test",
51
+ "neither_code"
52
+ ]
53
+ },
54
+ "res_add.json": {
55
+ "sha256": "6398605605d9d5c3950c74b055b7737befc91f0e9f0006a8ef718c300700d4eb",
56
+ "max6": 5,
57
+ "win6": [
58
+ "fc2",
59
+ "fresh_en",
60
+ "fresh_fr",
61
+ "test20k_old",
62
+ "test_v3"
63
+ ],
64
+ "max8": 5,
65
+ "win8": [
66
+ "fc2",
67
+ "fresh_en",
68
+ "fresh_fr",
69
+ "test20k_old",
70
+ "test_v3",
71
+ "bg1_test",
72
+ "neither_code"
73
+ ]
74
+ },
75
+ "rss.py": {
76
+ "sha256": "4dfb1c2ecf0264cad4629b7a6c684fd49b709bfffc244032aa877b025bc1bab7",
77
+ "max6": 13,
78
+ "win6": [
79
+ "test20k_old"
80
+ ],
81
+ "max8": 13,
82
+ "win8": [
83
+ "test20k_old",
84
+ "bg1_test",
85
+ "neither_code"
86
+ ]
87
+ }
88
+ },
89
+ "peak_rss_mb": 86.7890625
90
+ }
results/hashing/leak16_reconcile_r3/ref_8w.json ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "windows": {
3
+ "fc2": {
4
+ "path": "broad/freshcode_v2.bin",
5
+ "bytes": 199792,
6
+ "sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3"
7
+ },
8
+ "fresh_en": {
9
+ "path": "spira_m7/windows/fresh_en.bin",
10
+ "bytes": 119763,
11
+ "sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
12
+ },
13
+ "fresh_fr": {
14
+ "path": "spira_m7/windows/fresh_fr.bin",
15
+ "bytes": 1088688,
16
+ "sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715"
17
+ },
18
+ "test20k_old": {
19
+ "path": "spira_m7/windows/test20k.bin",
20
+ "bytes": 319940,
21
+ "sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22"
22
+ },
23
+ "test_v3": {
24
+ "path": "corpus_v3/test.bin",
25
+ "bytes": 3486653,
26
+ "sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84"
27
+ },
28
+ "queries": {
29
+ "path": "spira_m7/windows/queries.bin",
30
+ "bytes": 27800,
31
+ "sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706"
32
+ },
33
+ "bg1_test": {
34
+ "path": "broad/broad_gutenberg_v1/test.bin",
35
+ "bytes": 894718,
36
+ "sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9"
37
+ },
38
+ "neither_code": {
39
+ "path": "checker/recount/leak16_reconcile_r2/neither_code_concat.bin",
40
+ "bytes": 546020,
41
+ "sha256": "9d07d5ed054b6fc1a327a8f08fceb9ff4f5a5f5b3525c1698b0e52454473acc6",
42
+ "source": "concat tri\u00e9 /workspace/kahnn/data/code/*"
43
+ }
44
+ }
45
+ }
results/hashing/leak16_reconcile_r3/selfcheck_r2.json ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "dir": "/workspace/spira_shared/hashing_gen/precal_ratio_ckpt/hf_ready_run_iii_r2",
3
+ "files": {
4
+ "ADDENDUM.md": {
5
+ "sha256": "33041f014699ad988cb62c82c557b98d5ac3894be7d60f9869f1acd5a217f2a1",
6
+ "max6": 12,
7
+ "win6": [
8
+ "fresh_fr"
9
+ ],
10
+ "max8": 32,
11
+ "win8": [
12
+ "neither_code"
13
+ ]
14
+ },
15
+ "README.md": {
16
+ "sha256": "4735c694807ac56a5a58dac022fd543e5c85ba7a7825041749eb0a586829f977",
17
+ "max6": 12,
18
+ "win6": [
19
+ "fresh_fr",
20
+ "test_v3"
21
+ ],
22
+ "max8": 12,
23
+ "win8": [
24
+ "fresh_fr",
25
+ "test_v3"
26
+ ]
27
+ },
28
+ "REPORT.md": {
29
+ "sha256": "22086158e43e4dd3c430fbc361ba7db072fb5ed71a5e9019c308788257a02925",
30
+ "max6": 13,
31
+ "win6": [
32
+ "fresh_fr",
33
+ "test_v3"
34
+ ],
35
+ "max8": 32,
36
+ "win8": [
37
+ "neither_code"
38
+ ]
39
+ },
40
+ "res.json": {
41
+ "sha256": "23751f0b10d4568549f93c07214a36249e5950cddf07bd6f64049864d355c939",
42
+ "max6": 6,
43
+ "win6": [
44
+ "test20k_old",
45
+ "test_v3"
46
+ ],
47
+ "max8": 6,
48
+ "win8": [
49
+ "test20k_old",
50
+ "test_v3",
51
+ "bg1_test",
52
+ "neither_code"
53
+ ]
54
+ },
55
+ "res_add.json": {
56
+ "sha256": "6398605605d9d5c3950c74b055b7737befc91f0e9f0006a8ef718c300700d4eb",
57
+ "max6": 5,
58
+ "win6": [
59
+ "fc2",
60
+ "fresh_en",
61
+ "fresh_fr",
62
+ "test20k_old",
63
+ "test_v3"
64
+ ],
65
+ "max8": 5,
66
+ "win8": [
67
+ "fc2",
68
+ "fresh_en",
69
+ "fresh_fr",
70
+ "test20k_old",
71
+ "test_v3",
72
+ "bg1_test",
73
+ "neither_code"
74
+ ]
75
+ },
76
+ "rss.py": {
77
+ "sha256": "4dfb1c2ecf0264cad4629b7a6c684fd49b709bfffc244032aa877b025bc1bab7",
78
+ "max6": 13,
79
+ "win6": [
80
+ "test20k_old"
81
+ ],
82
+ "max8": 13,
83
+ "win8": [
84
+ "test20k_old",
85
+ "bg1_test",
86
+ "neither_code"
87
+ ]
88
+ },
89
+ "runner.sh": {
90
+ "sha256": "25854d01fa5b2793d75652d5a67753cda8d03160b973c005ce1b8bd82352a7ab",
91
+ "max6": 11,
92
+ "win6": [
93
+ "fc2"
94
+ ],
95
+ "max8": 17,
96
+ "win8": [
97
+ "neither_code"
98
+ ]
99
+ }
100
+ },
101
+ "peak_rss_mb": 86.71875
102
+ }
results/hashing/lever1/STATUS ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ 2026-10-23 21:22 Hashing lever1: verification flux broad_gutenberg_v1 en cours (delta vs broad_local_v1)
2
+ 2026-10-23 21:32 Hashing lever1: verif OK delta=0 sur 8 fenetres (abs INVALID herite base); manifeste ecrit; M8 = gate Checker 661153 (attend fin 628595), pas de doublon
results/hashing/lever1/manifest_broad_gutenberg_v1.json ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "variant": "broad_gutenberg_v1",
3
+ "author": "SPIRA Hashing (independent; not inside broad/)",
4
+ "corpus_dir": "/workspace/spira_shared/broad/broad_gutenberg_v1",
5
+ "construction": "train.bin = broad_local_v1/train.bin + b'\\n\\n' + corpus_gutenberg_v2/train.bin ; test.bin et oneshot.bin = copies de broad_local_v1 (test20k / fresh_en inchangés)",
6
+ "sources": {
7
+ "broad_local_v1": {
8
+ "train_sha256": "eda07017a87f2b7bbd55c5c2ea23032bf70a38ae7ad75167523228738f2391a1",
9
+ "composition": {
10
+ "en": 28654965,
11
+ "fr": 214337,
12
+ "code": 6860045
13
+ }
14
+ },
15
+ "corpus_gutenberg_v2": {
16
+ "train_sha256": "75afd55a4e800715d6870ec88ed12e5c01a42b6caa53243ad267a35c55525fb3",
17
+ "n_books": 568,
18
+ "en_bytes": 186503118,
19
+ "fr_bytes": 69470991,
20
+ "source": "Project Gutenberg via aleph.pglaf.org (approuvé 23/10 16 h 04)"
21
+ }
22
+ },
23
+ "files": {
24
+ "train": {
25
+ "bytes": 290810502,
26
+ "sha256": "5af6398fc853bce270e430f8336fc2b136318c2e762ead19e92f5d180de083f2"
27
+ },
28
+ "test": {
29
+ "bytes": 894718,
30
+ "sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9"
31
+ },
32
+ "oneshot": {
33
+ "bytes": 119763,
34
+ "sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
35
+ }
36
+ },
37
+ "base_prefix_check": {
38
+ "dir": "/workspace/spira_shared/broad/broad_local_v1",
39
+ "bytes": 34835257,
40
+ "sha256": "eda07017a87f2b7bbd55c5c2ea23032bf70a38ae7ad75167523228738f2391a1",
41
+ "is_exact_prefix": true
42
+ },
43
+ "verification": {
44
+ "script": "hashing_gen/lever1/verify_v3_chunked.py (verify_v3 semantics, streamed; sha256 d6d1905cca4c561b4a22d5bdaae939b8337696106dce71eadf9d0343f11b37d4)",
45
+ "k": 64,
46
+ "overlap64": {
47
+ "fresh_en": {
48
+ "window_bytes": 119763,
49
+ "n_64grams": 119700,
50
+ "hash_hits": 0,
51
+ "confirmed_positions": 0,
52
+ "confirmed_in_base_prefix": 0,
53
+ "delta_added_part": 0,
54
+ "delta_positions_first20": []
55
+ },
56
+ "fresh_fr": {
57
+ "window_bytes": 1088688,
58
+ "n_64grams": 1088625,
59
+ "hash_hits": 0,
60
+ "confirmed_positions": 0,
61
+ "confirmed_in_base_prefix": 0,
62
+ "delta_added_part": 0,
63
+ "delta_positions_first20": []
64
+ },
65
+ "neither_code": {
66
+ "window_bytes": 546036,
67
+ "n_64grams": 545973,
68
+ "hash_hits": 545558,
69
+ "confirmed_positions": 545558,
70
+ "confirmed_in_base_prefix": 545558,
71
+ "delta_added_part": 0,
72
+ "delta_positions_first20": []
73
+ },
74
+ "test20k": {
75
+ "window_bytes": 319940,
76
+ "n_64grams": 319877,
77
+ "hash_hits": 1405,
78
+ "confirmed_positions": 1405,
79
+ "confirmed_in_base_prefix": 1405,
80
+ "delta_added_part": 0,
81
+ "delta_positions_first20": []
82
+ },
83
+ "queries": {
84
+ "window_bytes": 27800,
85
+ "n_64grams": 27737,
86
+ "hash_hits": 0,
87
+ "confirmed_positions": 0,
88
+ "confirmed_in_base_prefix": 0,
89
+ "delta_added_part": 0,
90
+ "delta_positions_first20": []
91
+ },
92
+ "fc2": {
93
+ "window_bytes": 199792,
94
+ "n_64grams": 199729,
95
+ "hash_hits": 0,
96
+ "confirmed_positions": 0,
97
+ "confirmed_in_base_prefix": 0,
98
+ "delta_added_part": 0,
99
+ "delta_positions_first20": []
100
+ },
101
+ "corpus_test": {
102
+ "window_bytes": 894718,
103
+ "n_64grams": 894655,
104
+ "hash_hits": 33766,
105
+ "confirmed_positions": 33766,
106
+ "confirmed_in_base_prefix": 33766,
107
+ "delta_added_part": 0,
108
+ "delta_positions_first20": []
109
+ },
110
+ "corpus_oneshot": {
111
+ "window_bytes": 119763,
112
+ "n_64grams": 119700,
113
+ "hash_hits": 0,
114
+ "confirmed_positions": 0,
115
+ "confirmed_in_base_prefix": 0,
116
+ "delta_added_part": 0,
117
+ "delta_positions_first20": []
118
+ }
119
+ },
120
+ "valid_zero_overlap_absolute": false,
121
+ "delta_zero_all_windows": true,
122
+ "delta_zero_excl_neither_code": true,
123
+ "note": "Absolute overlap all inherited from broad_local_v1 prefix: neither_code 545558/545973, test20k 1405/319877, corpus_test 33766/894655. Gutenberg part adds 0 on every window."
124
+ },
125
+ "checker_manifest_sha256": "5ab579c5d8163a51e2b6dc85c28c2faf49ef4656e6e74d84421c76d9a635fd4c"
126
+ }
results/hashing/lever1/verify_bg1.json ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "corpus": "/workspace/spira_shared/broad/broad_gutenberg_v1",
3
+ "method": "verify_v3 semantics, train streamed in 4M-position chunks",
4
+ "files": {
5
+ "train": {
6
+ "bytes": 290810502,
7
+ "sha256": "5af6398fc853bce270e430f8336fc2b136318c2e762ead19e92f5d180de083f2"
8
+ },
9
+ "test": {
10
+ "bytes": 894718,
11
+ "sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9"
12
+ },
13
+ "oneshot": {
14
+ "bytes": 119763,
15
+ "sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a"
16
+ }
17
+ },
18
+ "overlap64": {
19
+ "fresh_en": {
20
+ "window_bytes": 119763,
21
+ "n_64grams": 119700,
22
+ "hash_hits": 0,
23
+ "confirmed_positions": 0,
24
+ "confirmed_in_base_prefix": 0,
25
+ "delta_added_part": 0,
26
+ "delta_positions_first20": []
27
+ },
28
+ "fresh_fr": {
29
+ "window_bytes": 1088688,
30
+ "n_64grams": 1088625,
31
+ "hash_hits": 0,
32
+ "confirmed_positions": 0,
33
+ "confirmed_in_base_prefix": 0,
34
+ "delta_added_part": 0,
35
+ "delta_positions_first20": []
36
+ },
37
+ "neither_code": {
38
+ "window_bytes": 546036,
39
+ "n_64grams": 545973,
40
+ "hash_hits": 545558,
41
+ "confirmed_positions": 545558,
42
+ "confirmed_in_base_prefix": 545558,
43
+ "delta_added_part": 0,
44
+ "delta_positions_first20": []
45
+ },
46
+ "test20k": {
47
+ "window_bytes": 319940,
48
+ "n_64grams": 319877,
49
+ "hash_hits": 1405,
50
+ "confirmed_positions": 1405,
51
+ "confirmed_in_base_prefix": 1405,
52
+ "delta_added_part": 0,
53
+ "delta_positions_first20": []
54
+ },
55
+ "queries": {
56
+ "window_bytes": 27800,
57
+ "n_64grams": 27737,
58
+ "hash_hits": 0,
59
+ "confirmed_positions": 0,
60
+ "confirmed_in_base_prefix": 0,
61
+ "delta_added_part": 0,
62
+ "delta_positions_first20": []
63
+ },
64
+ "fc2": {
65
+ "window_bytes": 199792,
66
+ "n_64grams": 199729,
67
+ "hash_hits": 0,
68
+ "confirmed_positions": 0,
69
+ "confirmed_in_base_prefix": 0,
70
+ "delta_added_part": 0,
71
+ "delta_positions_first20": []
72
+ },
73
+ "corpus_test": {
74
+ "window_bytes": 894718,
75
+ "n_64grams": 894655,
76
+ "hash_hits": 33766,
77
+ "confirmed_positions": 33766,
78
+ "confirmed_in_base_prefix": 33766,
79
+ "delta_added_part": 0,
80
+ "delta_positions_first20": []
81
+ },
82
+ "corpus_oneshot": {
83
+ "window_bytes": 119763,
84
+ "n_64grams": 119700,
85
+ "hash_hits": 0,
86
+ "confirmed_positions": 0,
87
+ "confirmed_in_base_prefix": 0,
88
+ "delta_added_part": 0,
89
+ "delta_positions_first20": []
90
+ }
91
+ },
92
+ "base": {
93
+ "dir": "/workspace/spira_shared/broad/broad_local_v1",
94
+ "bytes": 34835257,
95
+ "sha256": "eda07017a87f2b7bbd55c5c2ea23032bf70a38ae7ad75167523228738f2391a1",
96
+ "is_exact_prefix": true
97
+ },
98
+ "valid_zero_overlap": false,
99
+ "delta_zero_all_windows": true,
100
+ "delta_zero_excl_neither_code": true
101
+ }
results/hashing/lever1/verify_v3.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """SPIRA Hashing - verification independante (lecture seule) d'un corpus: tailles, sha256, overlap 64 o.
2
+ Usage: verify_v3.py CORPUS_DIR OUT_JSON"""
3
+ import sys, os, json, hashlib, numpy as np
4
+ sys.path.insert(0, "/workspace/spira_shared/checker")
5
+ C, OUT = sys.argv[1:3]; K = 64; P = np.uint64(1099511628211)
6
+ def hashes(b):
7
+ a = np.frombuffer(b, np.uint8).astype(np.uint64); n = len(a) - K + 1
8
+ if n <= 0: return np.zeros(0, np.uint64)
9
+ h = np.zeros(n, np.uint64)
10
+ with np.errstate(over="ignore"):
11
+ for j in range(K): h = h * P + a[j:j+n] + np.uint64(1)
12
+ return h
13
+ 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")}
14
+ try:
15
+ from windows_v2 import freshcode_v2; W["fc2"] = freshcode_v2()
16
+ except Exception as e: W["fc2_ERROR"] = b""; print("fc2 indisponible", e)
17
+ F = {f: open(f"{C}/{f}.bin","rb").read() for f in ("train","test","oneshot") if os.path.exists(f"{C}/{f}.bin")}
18
+ for _k in ("test","oneshot"):
19
+ if _k in F: W["corpus_"+_k] = F[_k]
20
+ rep = {"corpus": C, "files": {f: {"bytes": len(b), "sha256": hashlib.sha256(b).hexdigest()} for f, b in F.items()}, "overlap64": {}}
21
+ ht = hashes(F["train"]); hs = np.sort(ht)
22
+ for k, b in W.items():
23
+ hw = hashes(b); u = np.unique(hw)
24
+ i = np.searchsorted(hs, u); i = np.minimum(i, len(hs)-1); cand = u[hs[i] == u]
25
+ # confirmation octet par octet (anti-collision)
26
+ tset = set(cand.tolist()); pos_t = {}
27
+ for p in np.nonzero(np.isin(ht, cand))[0]: pos_t.setdefault(int(ht[p]), []).append(int(p))
28
+ conf = 0
29
+ for p in np.nonzero(np.isin(hw, cand))[0]:
30
+ seg = b[p:p+K]
31
+ if any(F["train"][q:q+K] == seg for q in pos_t.get(int(hw[p]), ())): conf += 1
32
+ rep["overlap64"][k] = {"window_bytes": len(b), "n_64grams": int(len(hw)), "hash_hits": int(np.isin(hw, cand).sum()), "confirmed_positions": conf}
33
+ print(k, rep["overlap64"][k], flush=True)
34
+ rep["valid_zero_overlap"] = all(v["confirmed_positions"] == 0 for v in rep["overlap64"].values()) and "fc2_ERROR" not in W
35
+ m = f"{C}/corpus_manifest.json" if os.path.exists(f"{C}/corpus_manifest.json") else f"{C}/manifest.json"
36
+ if os.path.exists(m): rep["manifest_checker"] = json.load(open(m))
37
+ json.dump(rep, open(OUT, "w"), indent=1); print("VALID" if rep["valid_zero_overlap"] else "INVALID")