Something went wrong. Try again.
Maps Linux distribution source packages to their upstream repositories, and through them to each other
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869"""Stratified error-analysis sample over the name-join confusion matrices.
differ: pairs (a, b, name) where both resolve to different keys, 8 per distro pair.unres: (distro, name) unresolved while a same-named package elsewhere resolves, 20 for openSUSE and 10 for each other distro.Prints stratum sizes and, per item, every distro's row and evidence for that name.The labels for the 2026-09-28 sample are in errors-2026-09-28.tsv.
Usage: python3 eval/sample.py differ|unres [packages.sqlite]"""import itertools, random, sqlite3, sys
DB = sys.argv[2] if len(sys.argv) > 2 else "data/packages.sqlite"SEED = 20260928DISTROS = ["alpine", "arch", "debian", "opensuse"]db = sqlite3.connect(DB)
def rows(name): out = {} for d, suite, key, basis, home in db.execute( "select distro, suite, coalesce(upstream_key,''), coalesce(basis,''), coalesce(homepage,'') " "from packages where package=? order by distro, suite", (name,)): ev = db.execute( "select source, value, coalesce(key,'') from evidence where distro=? and suite=? and package=? " "order by weight desc", (d, suite, name)).fetchall() out.setdefault(d, (suite, key, basis, home, ev)) return out
def dump(tag, header, name): print(f"[{tag}] {header} name={name}") for d, (suite, key, basis, home, ev) in rows(name).items(): print(f" {d:8} {key or '-'} ({basis or 'unresolved'}) home={home}") seen, n = set(), 0 for src, val, k in ev: if val in seen: continue seen.add(val) n += 1 if n > 6: print(f" ... {len(set(v for _, v, _ in ev)) - 6} more") break print(f" {src}: {val[:110]}" + (f" -> {k}" if k else "")) print()
rng = random.Random(SEED)resolved = {}for d, name, key in db.execute("select distro, package, coalesce(upstream_key,'') from packages"): if key or name not in resolved.get(d, {}): resolved.setdefault(d, {})[name] = key
mode = sys.argv[1]if mode == "differ": for a, b in itertools.combinations(DISTROS, 2): pop = sorted(n for n in resolved[a].keys() & resolved[b].keys() if resolved[a][n] and resolved[b][n] and resolved[a][n] != resolved[b][n]) pick = rng.sample(pop, min(8, len(pop))) print(f"### stratum {a} vs {b}: {len(pop)} differing names, sampled {len(pick)}\n") for i, n in enumerate(sorted(pick)): dump(f"D-{a[:2]}{b[:2]}-{i}", f"{a} vs {b}", n)elif mode == "unres": want = {"opensuse": 20, "debian": 10, "arch": 10, "alpine": 10} for d in DISTROS: pop = sorted(n for n, k in resolved[d].items() if not k and any( resolved[o].get(n) for o in DISTROS if o != d)) pick = rng.sample(pop, want[d]) print(f"### stratum {d} unresolved, a counterpart resolved: {len(pop)} names, sampled {len(pick)}\n") for i, n in enumerate(sorted(pick)): dump(f"U-{d[:2]}-{i}", f"{d} unresolved", n)