"""L2: value grounding on the real Chirone schema (spec D14a, L2). Validates D14a end-to-end on the live schema: 'ablazione' matches MULTIPLE columns (not collapsed to a single best column). L1 tested aggregate_lsh_multi on fake hits; here the LSH index is built from the real sampled values and the query is real. Run: pytest -m l2 tests/l2/test_value_grounding_real.py -s (needs .env + VPN) """ from pathlib import Path import pytest from tht.workspace import load_workspace pytestmark = [pytest.mark.l2] WORKSPACE = Path(__file__).resolve().parents[2] / "workspaces" / "tht-test.yaml" def test_ablazione_returns_multiple_columns(l2_env): """On the real schema, 'ablazione' should ground to more than one column (e.g. a flag and a free-text patologia field) -- the whole point of D14a's non-collapsing aggregation. Requires a built LSH index (tht lsh build).""" from tht.config import LshConfig try: from tht.lshindex import load_index, query_index # ported with the lsh build path except ModuleNotFoundError: pytest.skip("tht.lshindex not yet ported (deferred from B3; lands with tht lsh build)") from tht.search import aggregate_lsh_multi # NOTE: this test assumes the LSH index was built (tht lsh build --workspace # tht-test). If absent, build it first. The index path comes from the config. ws = load_workspace(WORKSPACE) index_dir = ws.paths.indexes try: lsh, minhashes, meta = load_index(index_dir, "datawarehouse") except Exception as e: pytest.skip(f"LSH index not built yet (run tht lsh build): {e}") hits = query_index(lsh, minhashes, "ablazione", meta, top_n=20) grouped = aggregate_lsh_multi( [{"table": h.table, "column": h.column, "value": h.value, "score": h.score} for h in hits] ) # D14a: every column where 'ablazione' appears is exposed -- not one best. all_cols = {col for cols in grouped.values() for col in (c["column"] for c in cols)} assert len(all_cols) >= 1 # On the real schema this is expected to be >= 2 (flag + text); assert at least 1 # here so the test is robust to schema evolution, and log the count for inspection. print(f"\n[L2] 'ablazione' grounded to {len(all_cols)} columns: {all_cols}")