feat(tht): sync-schema-linking projects F4 ledger into schema_linking.json
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
committed by
Marco Pancotti
co-authored by
Claude Opus 4.8
parent
1df5d40d05
commit
00365cc6e6
@@ -181,6 +181,51 @@ def set_schema_linking(
|
||||
return path
|
||||
|
||||
|
||||
def sync_schema_linking(session_id: str, sessions_root: Path) -> Path:
|
||||
"""Project the effective F4 ledger decisions into schema_linking.json.
|
||||
|
||||
candidates/excluded are rebuilt from table_promoted/table_excluded +
|
||||
column_promoted/column_excluded (last decision per subject wins). question,
|
||||
joins, concept_formulas and open_questions are preserved from the existing
|
||||
file when present. The reviewer's curation is thus authoritative and
|
||||
deterministic (no model transcription)."""
|
||||
from tht.phase import effective_decisions
|
||||
|
||||
session_dir = sessions_root / session_id
|
||||
manifest = load_session(session_id, sessions_root)
|
||||
|
||||
existing: dict = {}
|
||||
sl_path = session_dir / "schema_linking.json"
|
||||
if sl_path.exists():
|
||||
existing = json.loads(sl_path.read_text())
|
||||
|
||||
# last decision per subject wins (handles a re-run of the gate).
|
||||
latest: dict[str, str] = {}
|
||||
for d in effective_decisions(session_dir):
|
||||
if d.type in ("table_promoted", "table_excluded", "column_promoted", "column_excluded"):
|
||||
latest[d.subject] = d.type
|
||||
|
||||
candidates: list[dict] = []
|
||||
excluded: list[dict] = []
|
||||
for subject, dtype in latest.items():
|
||||
is_column = "." in subject
|
||||
kind = "column" if is_column else "table"
|
||||
if dtype in ("table_promoted", "column_promoted"):
|
||||
candidates.append({"kind": kind, "name": subject, "decision": "promoted"})
|
||||
else:
|
||||
excluded.append({"kind": kind, "name": subject})
|
||||
|
||||
data = {
|
||||
"question": existing.get("question") or manifest.question,
|
||||
"candidates": candidates,
|
||||
"joins": existing.get("joins", []),
|
||||
"excluded": excluded,
|
||||
"open_questions": existing.get("open_questions", []),
|
||||
"concept_formulas": existing.get("concept_formulas", []),
|
||||
}
|
||||
return set_schema_linking(session_id, data, sessions_root)
|
||||
|
||||
|
||||
def load_session(session_id: str, sessions_root: Path) -> SessionManifest:
|
||||
path = sessions_root / session_id / MANIFEST
|
||||
if not path.exists():
|
||||
|
||||
Reference in New Issue
Block a user