Skip to content

Cross-Project Entity Resolution Data Flow

This diagram traces how a local entity in one ecosystem project is resolved against a peer project via the FCC federation layer, culminating in a FederatedEntity, a recorded ModelChange, and an aggregated CrossProjectAssessment. It spans federation/namespaces.py, federation/entities.py, federation/change_tracking.py, objectmodel/mapping.py, and objectmodel/federation.py. The NamespaceRegistry currently lists 11 ecosystems, and VocabularyMapping records drive similarity-scored resolution across their term bases.

The diagram below traces the cross-project resolution pipeline.

flowchart LR
    subgraph Local
        L1[(Project A entity)]
        L2[local_id + namespace]
    end
    subgraph Namespace
        N1[NamespaceRegistry.resolve_uri]
        N2[NamespaceConfig]
        N3[Canonical URI]
    end
    subgraph Resolve
        R1[EntityResolver.resolve]
        R2[(VocabularyMapping store)]
        R3{Mapping found?}
        R4[FederatedEntity]
    end
    subgraph Track
        T1[ChangeTracker.record]
        T2[ModelChange]
        T3[(Audit trail)]
    end
    subgraph Assess
        S1[assess_cross_project]
        S2[CrossProjectAssessment]
    end
    L1 --> L2 --> N1
    N2 --> N1
    N1 --> N3 --> R1
    R1 --> R2 --> R3
    R3 -- yes --> R4
    R3 -- no --> R4
    R4 --> T1 --> T2 --> T3
    R4 --> S1 --> S2

Resolution begins with the local (local_id, namespace) pair. NamespaceRegistry.resolve_uri returns a canonical URI using the registered base_uri and prefix. EntityResolver.resolve(local_id, ns_A, ns_B) then consults the mapping store for a record whose source_vocabulary matches ns_A and target_vocabulary matches ns_B, producing a FederatedEntity(local_id, namespace, canonical_id, resolved, confidence, source_vocabulary, properties).

Every resolution is recorded as a ModelChange for the audit trail, and periodic sweeps across all project facades feed assess_cross_project(facades), which returns a CrossProjectAssessment(project_assessments, cross_project_score, federation_readiness, vocabulary_coverage). Unresolved entities are still emitted with resolved=False and a confidence of zero so governance dashboards can surface coverage gaps.

Data shapes

  • Stage 1 - Local: A (local_id, namespace) tuple drawn from Project A's entity registry.
  • Stage 2 - Namespace: NamespaceRegistry.resolve_uri(namespace, local_id) consults a NamespaceConfig(namespace, prefix, base_uri, version, description) and returns a canonical URI.
  • Stage 3 - Lookup: EntityResolver.resolve queries VocabularyMapping records keyed on (source_vocabulary, target_vocabulary).
  • Stage 4 - Federate: Produces FederatedEntity(local_id, namespace, canonical_id, resolved, confidence, source_vocabulary, properties).
  • Stage 5 - Track: ChangeTracker.record appends a ModelChange(entity_id, change_type, namespace, old_value, new_value, timestamp) to the audit trail.
  • Stage 6 - Assess: assess_cross_project(facades) aggregates per-project assessments into a CrossProjectAssessment(project_assessments, cross_project_score, federation_readiness, vocabulary_coverage).

See also

  • Source: src/fcc/federation/namespaces.py:14, src/fcc/federation/entities.py:12, src/fcc/federation/change_tracking.py:13
  • Source: src/fcc/objectmodel/mapping.py, src/fcc/objectmodel/federation.py:11
  • Related class diagram: ../class-diagrams/federation.md
  • For audience tier: docs/for-professionals/integration-guide.md