KB-354A

03 — IU KG Enrichment Foundation (LIVE-APPLIED: iu_relation enrich + v_kg_edges_all) (2026-05-28)

6 min read Revision 1
iukgknowledge-graphdieu39iu-relationuniversal-edgesprojectionlive-appliedprovenanceconfidence2026-05-28

03 — IU KG Enrichment Foundation (LIVE-APPLIED)

This is the first live KG enrichment in the series — applied safely and durably. It advances KG beyond design-only without creating a second graph SoT and with vector OFF.

1. Live reality (verified this run)

  • iu_relation — UUID-native, 60 rows, all contains/active, 0 with provenance, 0 with confidence in metadata, 0 triggers, not a Directus collection. Columns before: id, source_unit_id, target_unit_id, relation_type, relation_subtype, relation_status, operation_ref, source_version_id, target_version_id, metadata(jsonb), valid_from, valid_to, created_by, created_at.
  • universal_edges — integer-keyed (id/source_id/target_id are integer), 2199 rows, edge_types BELONGS_TO,CONTAINS,USES across 22 source_collections (the non-IU object graph). Already carries provenance jsonb, confidence numeric, valid_time tstzrange. Cannot reference UUID IU by design.

Conclusion: two complementary graphs. iu_relation = the IU/legal-unit graph (uuid). universal_edges = the non-IU object graph (int). Neither should absorb the other (that would create a hidden SoT).

2. What was applied (committed + durable-verified)

Method: dress-rehearse in BEGIN..ROLLBACK (proved parse + rollback: cols 14→19→14), then real BEGIN..COMMIT, then fresh-connection verify via read channel.

(a) Enrich iu_relation in place — additive nullable, Đ39-aligned:

ALTER TABLE public.iu_relation
  ADD COLUMN IF NOT EXISTS provenance     jsonb,
  ADD COLUMN IF NOT EXISTS confidence     numeric,
  ADD COLUMN IF NOT EXISTS evidence       jsonb,
  ADD COLUMN IF NOT EXISTS assertion_mode text,
  ADD COLUMN IF NOT EXISTS valid_time     tstzrange;

Zero behavior change to the 60 existing rows (all new cols NULL). COMMENTs added documenting Đ39 + additive date + backfill path.

(b) Read-only unified projection — no SoT duplication, security_invoker=true (caller's privileges; no escalation):

CREATE OR REPLACE VIEW public.v_kg_edges_all WITH (security_invoker = true) AS
SELECT 'iu_relation'::text AS edge_source, r.id::text AS edge_id,
       r.source_unit_id::text AS source_ref, 'information_unit'::text AS source_collection,
       r.target_unit_id::text AS target_ref, 'information_unit'::text AS target_collection,
       upper(r.relation_type) AS edge_type, r.relation_subtype AS edge_subtype,
       r.relation_status AS status, r.confidence,
       COALESCE(r.valid_time, tstzrange(r.valid_from, r.valid_to)) AS valid_time,
       r.provenance, r.metadata, r.created_by, r.created_at
FROM public.iu_relation r
UNION ALL
SELECT 'universal_edges'::text, e.id::text,
       e.source_collection||':'||e.source_id::text, e.source_collection,
       e.target_collection||':'||e.target_id::text, e.target_collection,
       e.edge_type, e.edge_subtype, e.status, e.confidence, e.valid_time,
       e.provenance, e.metadata, NULL::text, e.date_created
FROM public.universal_edges e;
GRANT SELECT ON public.v_kg_edges_all TO context_pack_readonly;

Verification (fresh connection): v_kg_edges_all = 2259 rows (60 iu_relation + 2199 universal_edges); 5 new iu_relation columns present; information_unit=219, iu_relation=60, universal_edges=2199 all unchanged; gates all_safe=true, never_flip_intact=true.

3. Rollback (authored, one-shot)

DROP VIEW IF EXISTS public.v_kg_edges_all;
ALTER TABLE public.iu_relation
  DROP COLUMN IF EXISTS provenance, DROP COLUMN IF EXISTS confidence,
  DROP COLUMN IF EXISTS evidence,   DROP COLUMN IF EXISTS assertion_mode,
  DROP COLUMN IF EXISTS valid_time;

No data depends on the new columns (all NULL); the view holds no data. Fully reversible with no trace beyond catalog.

4. Why this is not a second SoT

  • The view reads the two existing SoTs; it stores nothing.
  • IU edges remain owned by iu_relation; non-IU edges remain owned by universal_edges.
  • No migration of IU rows into universal_edges (that integer-keyed move would lose UUID identity and create a shadow copy).
  • Vector remains OFF (iu_core.vector_sync_enabled=false, never_flip intact).

5. Đ39 alignment & relation vocab

  • Đ39 v2.3 A8: "provenance-or-quarantine." The new provenance/confidence/evidence/assertion_mode columns give iu_relation first-class slots to satisfy this on future writes; existing rows are contains lineage (low-risk) and can be backfilled.
  • 8 atom-rule relation vocab (from information-atom-law): IDENTITY, BELONGS_TO, CONTAINS, DEPENDS_ON, USED_BY, TRANSITIVE, PEERS, SIMILAR. Today iu_relation uses only contains; universal_edges uses BELONGS_TO/CONTAINS/USES. The projection uppercases relation_type so both align to the atom vocab. Vocab expansion (adding DEPENDS_ON/USED_BY/etc. to a relation-type vocab table with allowed transitions) is the next governed step — see doc 09 prompt 3.

6. Forward path (next macro, now unblocked)

IU_KG_RELATION_BACKFILL_AND_VOCAB_EXPANSION_LIVE_300000X:

  1. Add a governed iu_relation_type_vocab (8 atom rules + symmetry/transitivity flags), under Đ39.
  2. Backfill provenance/confidence for the 60 contains edges from their operation_ref/lifecycle evidence.
  3. Add a writer function fn_iu_relation_assert(...) enforcing provenance-or-quarantine on new edges (gated).
  4. Optionally extend v_kg_edges_all with a graph_layer discriminator and symmetry-group resolution. All additive, all reversible, vector stays OFF.

7. Verdict

KG foundation: LIVE-APPLIED, materially beyond design-only. Unified read surface exists now; Đ39 enrichment slots exist now; SoT integrity preserved; reversible. Remaining work (vocab table, backfill, gated writer) is sequenced and safe.

Back to Knowledge Hub knowledge/dev/reports/architecture/iu-pilot-cr-kg-recon-authority-live-assembly-superbundle-2026-05-28/03-iu-kg-enrichment-foundation.md