Skip to main content

Authority control

Authority control ensures consistency in the knowledge graph by maintaining canonical records for concepts, people, and organizations. This document covers how authority records are managed and synchronized with external vocabularies.

What is authority control?​

Authority control links variant names and spellings to a single canonical concept:

User searches: "machine learning"
→ Matches authority record: "Machine Learning"
→ Includes aliases: "ML", "statistical learning"
→ Links to: Wikidata Q2539, LCSH sh85079324

This prevents fragmentation where "machine learning", "Machine Learning", and "ML" become separate concepts.

Authority record structure​

Authority records use pub.chive.graph.node with an appropriate subkind. Relationships are stored as separate edge records.

interface GraphNode {
id: string; // Canonical identifier
kind: 'type' | 'object'; // Node classification
subkind: string; // 'field', 'person', 'institution', 'concept'
label: string; // Preferred name
alternateLabels: string[]; // Alternative names (synonyms)
description: string; // Scope note
externalIds: ExternalId[]; // Links to external vocabularies
status: NodeStatus;
createdAt: string;
updatedAt: string;
}

interface ExternalId {
source: string; // 'wikidata', 'lcsh', 'viaf', 'fast', 'orcid', 'ror'
value: string;
}

type NodeStatus = 'proposed' | 'provisional' | 'established' | 'deprecated';

// Relationships are stored as separate edge records
interface GraphEdge {
sourceUri: string; // AT URI of source node
targetUri: string; // AT URI of target node
relationSlug: string; // 'broader', 'narrower', 'related', 'sameAs'
weight: number;
status: string;
}

Graph editors​

Graph editors are responsible for maintaining knowledge graph nodes (including authority records):

Qualifications​

RequirementDescription
KnowledgeFamiliarity with LCSH, FAST, Wikidata
AppointmentAdministrator approval

Responsibilities​

  • Create and maintain knowledge graph nodes
  • Reconcile with external vocabularies
  • Review node and edge proposals
  • Train community on authority standards
  • Vote on graph changes (2.0x weight)

Current graph editors​

Graph editors are listed publicly:

GET /xrpc/pub.chive.governance.listGraphEditors

External vocabulary integration​

Chive synchronizes with external knowledge bases:

VocabularyTypeSync frequency
WikidataGeneral knowledge graphDaily
LCSHLibrary of Congress Subject HeadingsMonthly
VIAFVirtual International Authority FileMonthly
FASTFaceted Application of Subject TerminologyMonthly
RORResearch Organization RegistryWeekly
ORCIDResearcher identifiersReal-time

Reconciliation process​

Local term → Wikidata API → Candidate matches
│
▼
Confidence score
├── High (>0.9): Auto-link
├── Medium (0.7-0.9): Editor review
└── Low (<0.7): Manual reconciliation

Evidence quality tiers​

Reconciliations are scored by evidence quality:

TierScoreEvidence type
Definitive1.0Exact identifier match (DOI, ORCID)
Strong0.9Multiple corroborating sources
Moderate0.7Single authoritative source
Weak0.5Name match only
Tentative0.3Partial match, needs review

Managing authority records​

Creating a record​

Only graph editors can create records directly. Community members propose via the standard proposal process:

{
"$type": "pub.chive.graph.nodeProposal",
"proposalType": "create",
"kind": "object",
"subkind": "institution",
"proposedNode": {
"id": "mit-csail",
"label": "MIT Computer Science and Artificial Intelligence Laboratory",
"alternateLabels": ["MIT CSAIL", "CSAIL"],
"description": "Research laboratory at MIT focused on CS and AI",
"externalIds": [
{ "source": "wikidata", "value": "Q1500407" },
{ "source": "ror", "value": "03fmab257" }
]
},
"rationale": "Major research institution frequently affiliated with Chive authors",
"createdAt": "2025-01-15T10:30:00Z"
}

Updating a record​

Changes to existing records follow the proposal process with a 60% threshold:

Change typeThresholdApprover
Add alternate label60%, 3 votesCommunity
Update description60%, 3 votesCommunity
Link external ID60%, 3 votesGraph editor review
Change label75%, 5 votesGraph editor approval
Merge nodes75%, 7 votesGraph editor approval

Merging records​

When duplicate records are discovered:

  1. Graph editor identifies duplicates
  2. Proposal created with merge rationale
  3. Community votes (75% threshold)
  4. If approved, nodes merged:
    • Keep node with more usage
    • Combine alternate labels
    • Preserve all external IDs
    • Redirect old ID to merged node

Reconciliation workflow​

Monthly sync protocol​

Day 1-3:   Fetch updates from external sources
Day 4-7: Run automated reconciliation
Day 8-14: Graph editors review flagged items
Day 15-20: Community proposal period for new links
Day 21-28: Voting on proposals
Day 28+: Changes enacted

Handling conflicts​

When external sources disagree:

Conflict typeResolution
Name variantsUse most authoritative source's preferred form
Scope differencesDocument scope notes from each source
Hierarchy disagreementsFollow LCSH for subjects, ROR for organizations
Identifier conflictsFlag for graph editor review

Quality assurance​

Validation rules​

Nodes must pass validation:

function validateNode(node: GraphNode): ValidationResult {
const errors: string[] = [];

if (!node.label || node.label.length < 2) {
errors.push('Label required (min 2 characters)');
}

if (node.alternateLabels?.some((a) => a === node.label)) {
errors.push('Alternate label cannot match primary label');
}

if (node.subkind === 'person') {
const hasOrcid = node.externalIds?.some((e) => e.source === 'orcid');
if (!hasOrcid) {
errors.push('Person nodes should have ORCID when available');
}
}

return { valid: errors.length === 0, errors };
}

Edge validation checks for circular relationships separately via graph traversal.

Audit trail​

All changes to nodes are logged:

{
"nodeId": "quantum-computing",
"action": "update",
"changes": {
"alternateLabels": {
"added": ["QC"],
"removed": []
}
},
"actor": "did:plc:editor...",
"timestamp": "2025-01-15T10:30:00Z",
"proposal": "proposal-456"
}

API endpoints​

Search nodes​

GET /xrpc/pub.chive.graph.searchNodes?query=machine+learning&subkind=field

Get node​

GET /xrpc/pub.chive.graph.getNode?id=quantum-computing

Get reconciliations​

GET /xrpc/pub.chive.graph.getNodeReconciliations?id=quantum-computing

Next steps​