domain-level constraints

This commit is contained in:
2026-03-04 16:53:58 -06:00
parent 00cc8dd9ef
commit 843baa15ad
11 changed files with 188 additions and 21 deletions

View File

@@ -9,7 +9,7 @@ from datetime import datetime, timezone
from typing import Sequence
from physcom.models.entity import Dependency, Entity
from physcom.models.domain import Domain, MetricBound
from physcom.models.domain import Domain, DomainConstraint, MetricBound
from physcom.models.combination import Combination
@@ -249,9 +249,25 @@ class Repository:
(domain.id, metric_id, mb.weight, mb.norm_min, mb.norm_max,
int(mb.lower_is_better)),
)
for dc in domain.constraints:
for val in dc.allowed_values:
self.conn.execute(
"INSERT OR IGNORE INTO domain_constraints (domain_id, key, value) VALUES (?, ?, ?)",
(domain.id, dc.key, val),
)
self.conn.commit()
return domain
def _load_domain_constraints(self, domain_id: int) -> list[DomainConstraint]:
rows = self.conn.execute(
"SELECT key, value FROM domain_constraints WHERE domain_id = ? ORDER BY key, value",
(domain_id,),
).fetchall()
by_key: dict[str, list[str]] = {}
for r in rows:
by_key.setdefault(r["key"], []).append(r["value"])
return [DomainConstraint(key=k, allowed_values=v) for k, v in by_key.items()]
def get_domain(self, name: str) -> Domain | None:
row = self.conn.execute("SELECT * FROM domains WHERE name = ?", (name,)).fetchone()
if not row:
@@ -277,6 +293,7 @@ class Repository:
)
for w in weights
],
constraints=self._load_domain_constraints(row["id"]),
)
def list_domains(self) -> list[Domain]:
@@ -308,6 +325,7 @@ class Repository:
)
for w in weights
],
constraints=self._load_domain_constraints(row["id"]),
)
def update_domain(self, domain_id: int, name: str, description: str) -> None:
@@ -359,9 +377,28 @@ class Repository:
self.conn.execute("DELETE FROM combination_results WHERE domain_id = ?", (domain_id,))
self.conn.execute("DELETE FROM combination_scores WHERE domain_id = ?", (domain_id,))
self.conn.execute("DELETE FROM domain_metric_weights WHERE domain_id = ?", (domain_id,))
self.conn.execute("DELETE FROM domain_constraints WHERE domain_id = ?", (domain_id,))
self.conn.execute("DELETE FROM domains WHERE id = ?", (domain_id,))
self.conn.commit()
def replace_domain_constraints(self, domain: Domain) -> None:
"""Delete and re-insert domain constraints. Used by seed backfill."""
if not domain.id:
existing = self.conn.execute(
"SELECT id FROM domains WHERE name = ?", (domain.name,)
).fetchone()
if not existing:
return
domain.id = existing["id"]
self.conn.execute("DELETE FROM domain_constraints WHERE domain_id = ?", (domain.id,))
for dc in domain.constraints:
for val in dc.allowed_values:
self.conn.execute(
"INSERT OR IGNORE INTO domain_constraints (domain_id, key, value) VALUES (?, ?, ?)",
(domain.id, dc.key, val),
)
self.conn.commit()
def reset_domain_results(self, domain_name: str) -> int:
"""Delete all pipeline results for a domain so it can be re-run from scratch.
@@ -560,14 +597,15 @@ class Repository:
novelty_flag: str | None = None,
llm_review: str | None = None,
human_notes: str | None = None,
domain_block_reason: str | None = None,
) -> None:
self.conn.execute(
"""INSERT OR REPLACE INTO combination_results
(combination_id, domain_id, composite_score, novelty_flag,
llm_review, human_notes, pass_reached)
VALUES (?, ?, ?, ?, ?, ?, ?)""",
llm_review, human_notes, pass_reached, domain_block_reason)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
(combo_id, domain_id, composite_score, novelty_flag,
llm_review, human_notes, pass_reached),
llm_review, human_notes, pass_reached, domain_block_reason),
)
self.conn.commit()
@@ -667,6 +705,7 @@ class Repository:
"human_notes": r["human_notes"],
"pass_reached": r["pass_reached"],
"domain_id": r["domain_id"],
"domain_block_reason": r["domain_block_reason"],
}
for r in rows
]
@@ -814,6 +853,7 @@ class Repository:
self.conn.execute("DELETE FROM dependencies")
self.conn.execute("DELETE FROM entities")
self.conn.execute("DELETE FROM domain_metric_weights")
self.conn.execute("DELETE FROM domain_constraints")
self.conn.execute("DELETE FROM domains")
self.conn.execute("DELETE FROM metrics")
self.conn.execute("DELETE FROM dimensions")