sorter: weak tier and tokenless adoption need a shared rare token; pool scan takes best accepted entry

This commit is contained in:
2026-10-07 06:08:40 +02:00
parent a995937c4b
commit e13412a5fe
2 changed files with 136 additions and 21 deletions
+59 -1
View File
@@ -24,6 +24,12 @@ CATALOG = {
{"name": "Guardian Squad", "system": "Warhammer 40,000",
"group": "Xenos Armies", "faction": "Aeldari",
"class": "Battleline", "aliases": []},
{"name": "Rangers", "system": "Warhammer 40,000",
"group": "Xenos Armies", "faction": "Aeldari",
"class": "Battleline", "aliases": []},
{"name": "Dark Reapers", "system": "Warhammer 40,000",
"group": "Xenos Armies", "faction": "Aeldari",
"class": "Aspect Warriors", "aliases": []},
]
}
@@ -121,6 +127,57 @@ def test_cross_system_needs_token_containment():
shutil.rmtree(root); shutil.rmtree(library)
def test_weak_needs_shared_token():
"""Sub-threshold hit with zero shared words is a fluke: reject.
'frontline squad' vs 'Guardian Squad' scores 0.552 but shares no
token - it must NOT re-home, while 'guardian weapon team' (0.588,
shares 'guardian') is accepted weak.
"""
root = Path(tempfile.mkdtemp(prefix="sorter_test_src_"))
pack = root / "Aeldari Pack"
write(pack / "frontline squad" / "f.stl")
write(pack / "guardian weapon team" / "g.stl")
library = make_lib()
(root / "extract_manifest.jsonl").write_text(json.dumps({
"archive": str(root / "Aeldari Pack.zip"),
"dest": "Aeldari Pack", "unit": "Aeldari Pack.zip",
}), encoding="utf-8")
files = sorted((root / "Aeldari Pack").rglob("*"))
items = sort_plan(files, library, get_catalog(), provenance={
"Aeldari Pack": "Aeldari Pack.zip"}, root=root)
by_name = {i.name: i for i in items}
f = by_name["f.stl"]
assert f.match_kind == "implicit", (f.match_kind, f.target)
assert "frontline squad" in str(f.target)
g = by_name["g.stl"]
assert g.match_kind == "weak" and g.confidence == "low"
shutil.rmtree(root); shutil.rmtree(library)
def test_tokenless_needs_bonus():
"""Same-faction adoption without a shared word needs +0.08.
'Aeldari Rangers' (0.667 vs 'Dark Reapers', tokenless) must not adopt
Dark Reapers; it instead adopts 'Rangers' (0.636, shares 'ranger').
"""
root = Path(tempfile.mkdtemp(prefix="sorter_test_src_"))
pack = root / "Aeldari Pack"
write(pack / "Aeldari Rangers" / "r.stl")
library = make_lib()
(root / "extract_manifest.jsonl").write_text(json.dumps({
"archive": str(root / "Aeldari Pack.zip"),
"dest": "Aeldari Pack", "unit": "Aeldari Pack.zip",
}), encoding="utf-8")
files = sorted((root / "Aeldari Pack").rglob("*"))
items = sort_plan(files, library, get_catalog(), provenance={
"Aeldari Pack": "Aeldari Pack.zip"}, root=root)
it = next(i for i in items if i.name == "r.stl")
assert it.match_kind == "catalog" and it.unit == "Rangers", \
(it.match_kind, it.unit, it.match_score)
shutil.rmtree(root); shutil.rmtree(library)
def test_nonprov_rehome():
"""Loose noise file inside a named dir re-homes to the dir's unit."""
root = Path(tempfile.mkdtemp(prefix="sorter_test_src_"))
@@ -164,7 +221,8 @@ def load_catalog_path():
def main():
catalog = load_catalog_path()
for fn in (test_prov_dir_rehome, test_prov_weak_tier, test_nonprov_rehome,
test_cross_system_needs_token_containment, test_apply_weak_doc):
test_cross_system_needs_token_containment, test_apply_weak_doc,
test_weak_needs_shared_token, test_tokenless_needs_bonus):
fn()
print("OK", fn.__name__)