Skip to content

Federated Map

Global Systemic Injustice Graph

What it is

Multiple independent ClearTrace instances opt-in to share graph metadata (not raw docs) to a global map service. The service aggregates nodes/edges and renders a live, explorable “systemic injustices” network.
Data shared (safe-by-default)
Nodes: entity_id_public, name, kind (org/person/project/case), country, sector, risk_grade, public_dossier_url.
Edges: source_id_public, target_id_public, relation_type (subsidiary_of, funded_by, litigated_in, reported_by, partner_of), evidence_count_public, first_seen_at, last_verified_at.
Flags: repeat_offender, under_investigation, verified_pct.
No private evidence, PII, or unverified content is shared—only summaries + URLs to public dossiers.

Minimal API (per instance → hub)

POST /federation/export
Body: { nodes: [...], edges: [...], instance_signature, schema_version }
Auth: signed JWT or mTLS; key scoped to “federation:write”.
GET /federation/map
Returns merged graph (paged or by tile).
GET /federation/instance/:id/health
Heartbeat & last-sync time.

Identity & deduping

Each instance derives entity_id_public = sha256(instance_namespace + local_entity_uuid).
Optional entity claims (e.g., legal name + country + registry number) allow the hub to probabilistically merge duplicates across instances.
Conflict strategy: keep both nodes, add a “possible duplicate” edge; stewards can confirm merges.

Governance & consent

Opt-in per instance with a toggle + policy acceptance.
Publish a Federation Charter: what’s shared, how merges work, takedown & appeals, audit cadence.
Reputation for instances (uptime, data quality, verified ratio) → used to weight map confidence.

Privacy & safety

Strip PII, redact testimony, share only verified or closed case aggregates by default.
Allow per-edge masking if a jurisdiction requires it.
Rate limits + abuse detection on the hub.

UI/UX (global map)

Filters: domain (ecological/social/political/economic/cultural), sector, geography, risk.
Layers: entities, cases, relationships, time slider (evolution).
Provenance chip: “From 5 instances • 34 verified items” → links to source dossiers.
Hubs & repeat offenders: auto-highlight central nodes.
Story paths: save & share curated walks (like Kumu “views”).

MVP build (2–4 sprints)

Schema additions (local):
public_entities.claims_json (legal_name, registry_no, iso_country).
public_relationships.publicity_level (public/internal/redacted).
entity_federation_opt_in (bool).
Export view (local):
SQL view federation_graph_v that outputs the safe node/edge payloads.
Hub service (tiny):
Simple Node/Go service + Postgres/Neo4j.
Validates signatures, version, and schema; stores nodes/edges with instance_id.
Dedup logic (v1):
Exact match on claims; fuzzy on (legal_name + country); else mark possible_duplicate.
Map front end:
Cytoscape.js/D3 force layout, filters, search, provenance chips.
Docs & consent:
Federation Charter + instance setup guide.

Versioning & integrity

Include schema_version, exported_at, and a bundle hash of the payload.
Hub keeps snapshot history for rollback & audits.

Risks & mitigations

Conflicting claims: show both; require additional verification to merge.
Jurisdictional constraints: per-edge redaction + instance-level geo policies.
Spam/poisoning: instance allowlist, human steward review for new instances, anomaly detection.

Roadmap

v2: Federated search API, multilingual labels, signed provenance attestations per edge.
v3: Cross-instance alerts (when a repeat offender appears elsewhere), curated “systems lenses” (sector packs), and public embed for campaigns.


1) Tiny OpenAPI spec (YAML)

openapi: 3.0.3 info: title: ClearTrace Federation Hub API version: 0.1.0 description: > Minimal endpoints for federated graph exchange across ClearTrace instances. servers: - url: https://hub.cleartrace.example security: - ApiKeyAuth: [] - BearerAuth: [] components: securitySchemes: ApiKeyAuth: type: apiKey in: header name: X-API-Key BearerAuth: type: http scheme: bearer bearerFormat: JWT schemas: Node: type: object required: [id, label, kind] properties: id: { type: string, description: Public-safe id (instance-scoped hash) } label: { type: string } kind: { type: string, enum: [entity, person, project, case] } country: { type: string, nullable: true } sector: { type: string, nullable: true } risk_grade: { type: string, enum: [low, medium, high, unknown], nullable: true } dossier_url: { type: string, format: uri, nullable: true } created_at: { type: string, format: date-time, nullable: true } Edge: type: object required: [id, source, target, type] properties: id: { type: string } source: { type: string } target: { type: string } type: { type: string, enum: [subsidiary_of, funded_by, partner_of, litigated_in, reported_by, related_to] } evidence_count: { type: integer, minimum: 0, default: 0 } first_seen_at: { type: string, format: date-time, nullable: true } last_verified_at: { type: string, format: date-time, nullable: true } GraphBundle: type: object properties: nodes: type: array items: { $ref: '#/components/schemas/Node' } edges: type: array items: { $ref: '#/components/schemas/Edge' } ExportPayload: type: object required: [nodes, edges, instance_id, schema_version, exported_at, bundle_hash] properties: instance_id: { type: string, description: short id for the sending instance } schema_version: { type: string, example: "0.1.0" } exported_at: { type: string, format: date-time } bundle_hash: { type: string, description: sha256 of canonicalized payload } nodes: type: array items: { $ref: '#/components/schemas/Node' } edges: type: array items: { $ref: '#/components/schemas/Edge' } Health: type: object properties: instance_id: { type: string } last_exported_at: { type: string, format: date-time, nullable: true } status: { type: string, enum: [ok, stale, unknown], default: ok }
paths: /federation/map: get: summary: Get merged federated graph security: [] # public-readable map; adjust if needed parameters: - in: query name: since schema: { type: string, format: date } description: Filter edges by last_verified_at >= since - in: query name: sector schema: { type: string } - in: query name: country schema: { type: string } - in: query name: risk schema: { type: string, enum: [low, medium, high, unknown] } responses: '200': description: Merged graph content: application/json: schema: { $ref: '#/components/schemas/GraphBundle' }
/federation/export: post: summary: Push a safe graph bundle from an instance to the hub security: - ApiKeyAuth: [] - BearerAuth: [] requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/ExportPayload' } responses: '202': description: Accepted for ingestion
/federation/instance/{instance_id}/health: get: summary: Get last-seen status for an instance parameters: - in: path name: instance_id required: true schema: { type: string } responses: '200': description: Health info content: application/json: schema: { $ref: '#/components/schemas/Health' }
Want to print your doc?
This is not the way.
Try clicking the ··· in the right corner or using a keyboard shortcut (
CtrlP
) instead.