You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Entity identity as a hygm contract the extraction backends apply #442
Should hygm own entity identity (when two mentions are the same node), with the extraction backends applying one shared contract instead of each defining it?
Where it lives today
hygm only declares an identity value per node type: global, chunk or span. What those values mean, and the policies around them, live in unstructured2graph's GLiNER2 backend and depend on how the caller chunks its input:
The key (gliner2_backend.py, _entity_id):
global: global|{type}|{normalized text}
chunk: {chunk hash}|{type}|{normalized text}
span: {chunk hash}|{type}|{offsets}
Normalization is lowercasing plus whitespace collapsing.
A case heuristic: an all-lowercase mention of a global type falls back to chunk scope, to stop generic nouns ("home", "area") becoming hubs.
The user resolver: a User mention is bound to the session's own (:User), retyped to Person, or dropped.
Scope depends on the caller: "chunk" means "per session" only because sessions-graph reconciles each session as a single chunk. A different chunker would silently change the graph's shape.
The type is part of the key, so the same name typed differently becomes two nodes (e.g. "FastAPI" as Artifact and as Organization). That gets worse with:
learned models, where the type set changes between versions;
Merges and the key collide. The aggregation decision (Grill: how a derivation run aggregates into the previous model #434) relabels merged types eagerly. Existing node keys still contain the old type, so after a relabel, new mentions of the same name hash to a different key and create a duplicate, unless the keys are rewritten too.
No aliases: "Postgres" and "PostgreSQL", or "FastAPI" and "Fast API", stay separate.
What hygm could own
The key function and its normalization, with the type kept out of the global key, or mapped through the version chain.
What each scope means, independent of how the caller chunks its input.
The decision of whether a mention is a name or a generic noun, replacing the case check.
Hooks for aliases and merges that ontology version changes can call.
What backends apply: GLiNER2 now, and LightRAG if it is to share the model.
Not decided. Surfaced while building the default model. It touches the relabel step that sessions-graph derive will need.
Question
Should
hygmown entity identity (when two mentions are the same node), with the extraction backends applying one shared contract instead of each defining it?Where it lives today
hygmonly declares anidentityvalue per node type:global,chunkorspan. What those values mean, and the policies around them, live in unstructured2graph's GLiNER2 backend and depend on how the caller chunks its input:The key (
gliner2_backend.py,_entity_id):global|{type}|{normalized text}{chunk hash}|{type}|{normalized text}{chunk hash}|{type}|{offsets}Normalization is lowercasing plus whitespace collapsing.
A case heuristic: an all-lowercase mention of a global type falls back to chunk scope, to stop generic nouns ("home", "area") becoming hubs.
The user resolver: a
Usermention is bound to the session's own(:User), retyped toPerson, or dropped.Scope depends on the caller: "chunk" means "per session" only because sessions-graph reconciles each session as a single chunk. A different chunker would silently change the graph's shape.
Problems this leaves
pytest,uv,ruff,numpy), while a capitalized generic noun at the start of a sentence can. This came up when choosingArtifactas global in the default model (hygm: ship the generic default model learned ontologies start from #441).Artifactand asOrganization). That gets worse with:What hygm could own
Not decided. Surfaced while building the default model. It touches the relabel step that
sessions-graph derivewill need.