Concepts¶
This page defines the KGIS vocabulary. It is the reference the usage guides point
back to. For authoritative depth, each concept links to the relevant ADR in the
repository's llm/governance/adr/.
Candidate¶
A Candidate is a proposed assertion — never a committed fact. It is the
universal seam between ingestion (KGIS) and curation (KGCS). The candidate model
is a union of variants for the different things ingestion can propose, including:
EntityCandidate— a proposed entity.AttributeAssertionCandidate— a proposed attribute value on an entity.RelationCandidate— a proposed relationship between two entities.ObservationCandidate,IdentityLinkCandidate,DerivedAssertionCandidate,ArtifactCandidate,OntologyCandidate,PlanCandidate— the remaining variants for richer proposals.
Every candidate carries source coordinates, versions, CandidateScores, and
(optionally) evidence references. candidate_ids are content-addressed, which is
what makes re-ingestion idempotent.
CandidateSink¶
CandidateSink is the only write surface anywhere in KGIS. Its contract is
submit(candidates) -> SubmissionResult. Application code gets this surface and
nothing else — there is no direct graph-upsert method to reach for (ADR-0010).
Implementations include:
MemoryCandidateSink— in-memory, for demos and tests.SqliteCandidateLedger— the durable, persistent ledger (below).
Graph mutation happens behind a separate, executor-only GraphMutationStore
that KGIS never exposes and KGCS drives.
The candidate ledger¶
The persistent candidate ledger (SqliteCandidateLedger, ADR-0006 store 1,
ADR-0012) is a durable, replayable, bitemporal record of every submitted
candidate: source coordinates, extractor/model/ontology versions, normalized
payload, evidence refs, quality signals, and a processing state. Uncertain
candidates live here and never appear as ordinary graph nodes — that is the
whole point of the three-store separation.
Row governance: revoke and erase¶
Two governance actions sit on a row, orthogonal to its processing state (ADR-0013):
revoke(candidate_id, reason, actor)— a logical withdrawal. The row and payload are retained; revoked rows are excluded from the default listing but still resolve on direct lookup.LedgerRow.is_revokedexposes the state.erase(candidate_id, reason, actor)— a logical erasure: it nulls the live payload so it can't be read back, while keeping a hash tombstone that proves a record existed and was erased (by whom / why / when).
Erasure is logical, not forensic
erase is not an at-rest or forensic scrub. It withdraws the live payload
and keeps an auditable tombstone. Treat it as a governance/visibility
operation, not as guaranteed byte-level destruction on disk.
Evidence¶
Evidence makes KGIS evidence-first. A candidate can cite the passage, row, or
document it came from via an EvidenceRef that resolves through a
SqliteEvidenceRegistry. Evidence availability is always one of three states:
- PRESENT — the evidence is there (content or a payload hash).
- ABSENT — it is genuinely not there, with an
AbsenceReason(an honest null, not a fake zero). - ERROR — an error occurred fetching it, captured explicitly.
A dangling EvidenceRef raises — evidence is never silently dropped
(ADR-0009). This is what lets a downstream consumer trust that a cited fact can
actually be checked.
Scores: two confidence axes¶
CandidateScores keeps two axes distinct and never collapses them into one
float (ADR-0004 as amended):
source_reliability— how trustworthy the source is. Required, no default.extraction_confidence— how sure this extraction was. Defaults to1.0(legitimate for an exact structured read).
An exact CSV read from a so-so source and a shaky LLM guess from an authoritative source have very different score profiles, and KGIS keeps them distinguishable.
Identity¶
Identity is structural and namespaced: EntityRef{entity_type, namespace, key},
rendered Label:namespace:key (e.g. Athlete:usssa:12345) only at adapter
boundaries. The bare Label:key form is forbidden for cross-project use
because it hides the identifier authority (ADR-0008). Every canonical entity also
has an immutable internal identity ID that survives key corrections, merges, and
splits. semantic_key (entity_semantic_key) gives an entity's stable
type/namespace/key identity.
Identity mode¶
IdentityMode (ADR-0014) is a per-consumer toggle on the ledger:
AUTO_MERGE (default) or REJECT_ONLY, the latter rejecting ambiguous identity
matches at submit() time rather than auto-linking them. An injected
IdentityResolver (a yes/no is_ambiguous oracle) decides ambiguity; full
entity resolution is deferred to a later plan.
Determinism¶
A pipeline is deterministic when you inject a FixedClock and a
DeterministicIdStrategy: same input → byte-identical output. This is a property
of configuration, not of the harness — the defaults (SystemClock,
RandomIdStrategy) are non-deterministic on purpose. Combined with
content-addressed candidate_ids and the durable ledger, determinism gives you
idempotent, replayable, auditable runs.
Ontology and two-tier validation¶
An Ontology declares the allowed entity types, relation types, and attributes.
Validation happens at two tiers (ADR-0015):
- Record-scoped (
RecordValidator) — is this raw row usable at all? - Candidate-scoped (
CandidateValidator, e.g.OntologyCandidateValidator) — does the built candidate fit the ontology?
Record-scoped validation deliberately has no contract type; it is an in-engine concern.