resolver: rename reserved LogRecord key 'name' in alias-collision log; artifacts are published, not developed: writer redirects develops→artifact to published_by, canonicalizer closes historic develops edges into artifacts and re-emits published_by
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
3 changed files +18 −1
modified
src/aiatlas/sdk/resolution.py
+1 −1
@@ -134,7 +134,7 @@ class Resolver: | ||
| 134 | 134 | if (r["alias"] or "").strip().lower() in lower_names or variant_key(r["canonical_name"]) == ref_vk: |
| 135 | 135 | safe.append(r) |
| 136 | 136 | else: |
| 137 | − log.info("alias collision refused", extra={"name": ref.name, "candidate": r["canonical_name"]}) | |
| 137 | + log.info("alias collision refused", extra={"ref_name": ref.name, "candidate": r["canonical_name"]}) # `name` is reserved by LogRecord | |
| 138 | 138 | rows = safe |
| 139 | 139 | if not rows: |
| 140 | 140 | return None |
modified
src/aiatlas/sdk/writer.py
+6 −0
@@ -316,6 +316,12 @@ class FactWriter: | ||
| 316 | 316 | oid = await self.resolver.resolve(obj) |
| 317 | 317 | if not sid or not oid or sid == oid: |
| 318 | 318 | return |
| 319 | + if predicate == "develops": | |
| 320 | + # an organisation develops a *model*; a hub repository that is an artifact (quantisation, conversion) is merely published by its org | |
| 321 | + otype = await fetch_one(self.conn, "select entity_type from entities where id = :id", id=oid) | |
| 322 | + if otype and otype["entity_type"] == "artifact": | |
| 323 | + predicate = "published_by" | |
| 324 | + sid, oid = oid, sid | |
| 319 | 325 | conf = confidence or TIER_CONFIDENCE.get(self.tier, "medium") |
| 320 | 326 | existing = await fetch_one(self.conn, "select id, attributes from relations where subject_id = :s and predicate = :p and object_id = :o and valid_to is null", |
| 321 | 327 | s=sid, p=predicate, o=oid) |
modified
src/aiatlas/services/canonical.py
+11 −0
@@ -430,6 +430,17 @@ async def step_artifacts(conn: AsyncConnection, rep: StepReport, apply: bool, *, | ||
| 430 | 430 | if not cid: |
| 431 | 431 | await _review(conn, "unresolved_artifact", [m["id"]], f"'{m['canonical_name']}' is a {kind} artifact but its base model is unknown", |
| 432 | 432 | {"slug": m["slug"], "hf_repo": hf_repo, "variant_key": variant_key(probe)}, apply=apply) |
| 433 | + # an organisation develops a model, not a quantisation/conversion of it: live `develops` edges into artifacts (bartowski, unsloth, | |
| 434 | + # mlx-community… but also official orgs re-packaging their own weights) are closed and replaced by `published_by` | |
| 435 | + scope_sql = "and a.id = any(cast(:ids as text[]))" if scope is not None else "" | |
| 436 | + edges = await fetch_all(conn, f"""select r.id, r.subject_id as org_id, r.object_id as artifact_id, r.source_id, r.tier from relations r | |
| 437 | + join entities a on a.id = r.object_id where r.predicate = 'develops' and r.valid_to is null and a.entity_type = 'artifact' {scope_sql}""", | |
| 438 | + ids=sorted(scope or [])) | |
| 439 | + for e in edges: | |
| 440 | + rep.bump("develops_to_artifact_closed") | |
| 441 | + if apply: | |
| 442 | + await execute(conn, "update relations set valid_to = now() where id = :id", id=e["id"]) | |
| 443 | + await upsert_relation(conn, e["artifact_id"], "published_by", e["org_id"], source_id=e["source_id"] or source_id, tier=e["tier"] or 2) | |
| 433 | 444 | |
| 434 | 445 | |
| 435 | 446 | # ---------------------------------------------------------------------------------------------- step: families |
| 436 | 447 | |