SpiritSafe Integration Architecture
This document describes the current architecture used by gkc.spirit_safe for integrating SpiritSafe artifacts.
Current State
Implemented and committed:
- JSON Entity Profiles are loaded from
still/profiles/<QID>.json. - Value-list artifacts are loaded from
still/value_lists/cache/<QID>.json. - Profile graph traversal is QID/URI-aware and built from embedded
metadata.profile_graphentries. - Curation packet scaffolding is profile-document-driven.
Artifact Layers
SpiritSafe Repository Artifacts
still/profiles/<QID>.jsonstill/value_lists/queries/<QID>.sparqlstill/entities/<QID|PID>.jsonstill/value_lists/cache/<QID>.json
gkc Runtime Layers
load_profile()resolves QID/URI and loads JSON profile documents.load_profile_package()loads primary plus related profiles by traversing embeddedmetadata.profile_graphedges.still_charger.create_curation_packet()builds packet scaffolds from profile documents loaded via SpiritSafe.
Identity Model
SpiritSafe artifacts and curation packets use a dual-key identity model:
name_identifier— primary human-facing key, derived from the DD Wikibasename_identifierproperty (P214). Used as statement slot keys in packet data, graph node identifiers, and profile reference labels.- Full entity URI — immutable canonical identity for joining, provenance, and round-trip mapping to the Wikibase instance. Stored in the
idfield throughout.
QIDs are normalized from URI tails only where file path resolution requires them. Labels are display-only and are never used as join keys.
Registry Metadata Model
Registry discovery reads metadata directly from each JSON profile document.
Relevant metadata fields include:
entitymetadata.labelsmetadata.descriptionsmetadata.statement_countmetadata.profile_graphmetadata.value_list_graph
Profile Graph Model
ProfileGraph consumes embedded profile metadata where edge targets and statements are URIs.
Normalization rules:
target_profileis normalized to target QID.via_statementremains URI-form.relationship_typemaps fromlinkage_type.cardinalityandtraversaldefault to empty dict when omitted.
Packet Scaffolding Model
still_charger.create_curation_packet() and still_charger.build_curation_packet_from_json_profile() produce a two-section packet:
metadata— the complete profile ruleset, unified graph, mint provenance, and SHA-256 integrity digest.data— fillable entity slots.
Top-level packet fields:
packet_id— UUID-based identifieroperation_mode—new,single, orbulkmetadata.primary_profile—name_identifierandid(URI) for the primary profilemetadata.profiles— array of full profile definitions (statements, identification, metadata) for all profiles in packet scopemetadata.graph— unified graph withnodeskeyed byname_identifierandedgesencoding both profile-to-profile and profile-to-value-list relationshipsmetadata.mint—minted_at,generator,gkc_versionmetadata.integrity— SHA-256 digest of canonical metadata JSON; used as fermenter go/no-go gate on re-entrydata.entities— array of entity slots
Entity slots in data.entities carry:
profile— profilename_identifierid— profile URI (canonical entity identity for this slot)- Language-keyed
labels,descriptions,aliasesslots — each value is{"data-value": ""}; no inner language tag statements— object keyed by statementname_identifier, each slot includingid(statement URI),data-type,data-value, and optionallyvalue-list,qualifiers, andreferences
Qualifiers and references are omitted when the profile does not specify them. When used as a reference or qualifier, a statement does not carry its own nested references or qualifiers.
Derived-value hints from SpiritSafe JSON (P213 semantics) appear within statement value objects:
value_source: statement_valuevalue_source_statement: <parent statement URI>
These are derived from DD Wikibase statement-level semantics and are intended for downstream wizard/validation consumers.
Testing Strategy
tests/fixtures/spiritsafe/ now mirrors the current SpiritSafe layout with minimal fixtures:
still/profiles/Q4.json,still/profiles/Q39.jsonstill/entities/Q4.jsonstill/value_lists/cache/Q28.jsonstill/value_lists/queries/Q28.sparql
Theoretical Design Notes
Packet migration tooling — When a long-lived packet returns after SpiritSafe state has changed, a forward migration utility will classify drift and apply approved transforms before re-validation. The metadata.mint fields provide the provenance anchor. Change classification categories (patch_compatible, minor_compatible, migration_required, breaking) and a migration report are the planned output. Not yet implemented.
Fermenter-driven charged packet integration — The charge_packet_from_wikidata_items path in still_charger does not yet use the fermenter evaluator (evaluate_entity) to partition charged statements into conformant/non_conformant/uncovered/missing_required buckets. This is the next implementation step; the fermenter evaluator API is ready. See Cross-Module Contracts for current gap notes.