Civic / Privacy / Digital Rights

BuiltToResist: Information Architecture for a 10,000+ Page Encyclopedia of Revolution and Resistance

Report summary

BuiltToResist should be designed as three systems layered on top of one another , rather than as one giant hierarchy:

Status
Research archive item
Category
Civic / Privacy / Digital Rights
Length
5,700 words
Reading time
26 minutes
Report type
architecture

Key topics

  • Civic / Privacy / Digital Rights
  • Civic
  • Privacy
  • Digital Rights
  • AI
  • Agentic Web
  • Semantic Systems
  • Research Archive
  • Strategy

Research provenance

Archive status
Research archive item
Content identity
sha256:934d0dd6af4ed4a1f5e5ab2d6949253209e9dbdcf2653b95753a172b1d7764e9

For citation, use the report title and canonical URL. Archival presence does not establish authorship or promote report statements into portfolio evidence.

Source availability: 31 citation markers in the source export have no recoverable source links. Those markers are omitted from this reader; any supplied bibliography and ordinary links remain. Check the original sources before relying on the cited claims.

This page renders the archived Markdown as safe, formatted HTML. It is background research and does not become a portfolio claim without evidence review.

Full report

On this page

Architectural foundation

BuiltToResist should be designed as three systems layered on top of one another, rather than as one giant hierarchy:

  1. An encyclopedia of stable pages written for people.
  2. A controlled knowledge graph describing entities and their relationships.
  3. A research/evidence layer recording sources, provenance, uncertainty, temporal scope, and competing interpretations.

That separation is the central design decision. A conventional category tree is too brittle for a subject in which one event can simultaneously belong to several countries, periods, ideological traditions, movements, institutional contexts, mechanisms, and scholarly debates. SKOS was explicitly designed for thesauri, taxonomies, classification schemes, subject headings, concept schemes, labels, broader/narrower relationships, associative relationships, and cross-vocabulary mappings; its model is therefore a strong foundation for BuiltToResist's controlled vocabularies, but it should not replace the richer factual graph.

The recommended conceptual model is:

                     ┌────────────────────────────┐
                     │       Human Web Page       │
                     │ title, prose, navigation   │
                     └─────────────┬──────────────┘
                                   │ describes
                                   ▼
                     ┌────────────────────────────┐
                     │           Entity           │
                     │ stable ID + canonical data │
                     └─────────────┬──────────────┘
                                   │
                 ┌─────────────────┼─────────────────┐
                 │                 │                 │
                 ▼                 ▼                 ▼
            Statement         Concept/Tag       External ID
        subject-predicate-   controlled term    Wikidata/DOI/
             object                              ISBN/VIAF/etc.
                 │
          ┌──────┴──────┐
          ▼             ▼
      Qualifiers     Citations
     time, place,    source + locator
     role, status,
     uncertainty

This “qualified statement” approach is particularly important for historical and political knowledge. Wikidata uses essentially the same architecture: a statement contains a property-value assertion and can carry qualifiers, references, and ranks so that the assertion can be contextualized rather than flattened into an unconditional fact. Its qualifier model explicitly supports temporal limits, methods, roles, and other contextual information that cannot be represented adequately in a bare subject-predicate-object triple.

For BuiltToResist, that means:

Do not store “Movement X → Ideology Y” as an unqualified truth whenever the real claim is “Movement X was characterized as Ideology Y by Source Z during Period T, with disputed status.”

The database should be able to represent both.

The most important modeling distinctions

Page, entity, concept, and tag are not synonyms.

A page is a publication object: something readers visit.

An entity is a thing BuiltToResist identifies independently: the French Revolution, Václav Havel, Solidarity, martial law, elite defection, a book, an archive collection, a research dataset.

A concept is a special kind of entity representing an idea or classification term: authoritarianism, general strike, regime defection, constitutional emergency powers, negotiated transition.

A tag is a controlled assignment of a concept to another entity or page for filtering or retrieval. The tag should normally point to a concept ID rather than exist as uncontrolled text.

A category is primarily a human-navigation construct: “Revolutions,” “Mechanisms,” “Primary Sources,” “Latin America.” It should not become a parallel factual ontology.

A relationship is an assertion between entities.

A source is evidence for a claim.

A role is contextual rather than necessarily an intrinsic entity type. “Leader,” “scholar,” and especially “primary source” fall into this category.

This distinction eliminates much of the taxonomy explosion that otherwise appears once the encyclopedia reaches thousands of pages.

One ontology, multiple views

The site should have a relatively small set of underlying entity classes:

Core entity familyPrincipal subtypes or roles
HistoricalEventRevolution, Uprising, Protest Wave, Strike Wave, Rebellion, Coup, Transition, Crackdown
MovementMovement, Campaign, Coalition, Network
PersonLeader, Organizer, Scholar, Author, Official, Dissident
OrganizationParty, Union, NGO, Military Unit, Government Body, Media Organization
InstitutionJudiciary, Legislature, Monarchy, Security Apparatus, Electoral System, Emergency Regime
ConceptIdeology, Mechanism, Outcome Type, Legal Doctrine, Political Concept, Historical Era, Tactic
Place/PolityCountry, Historical State, Territory, Region, City
CreativeWorkBook, Article, Research Report, Primary-Source Document, Film, Recording, Photograph
CollectionArchive Collection, Bibliography, Timeline
AnalysisCase, Scenario, Question, Deep Analysis
DatasetStatistical Dataset, Indicator Series, Corpus
ObservationStatistical observation; normally not a standalone page

This is intentionally much smaller than the user's list of page families. The public information architecture can expose “Leaders,” “Books,” “Legal Doctrines,” “Statistics,” and similar categories, while the underlying model avoids creating a new fundamental object class every time a new navigation view is desired.

That pattern is consistent with schema.org's own inheritance strategy: broad types such as Thing, CreativeWork, Event, Organization, Person, and Place are specialized without requiring each website concept to become a wholly separate data architecture.

For political-event data specifically, it is useful to keep the underlying event model separate from interpretive aggregate labels. ACLED, for example, treats the individual event as its fundamental unit and records actors, location, date, event type and subtype separately; users can then aggregate and filter across actors, geography, time, and type. BuiltToResist should not copy ACLED's event taxonomy, but the architectural lesson is valuable: store the underlying dimensions separately instead of putting every historical episode into one mutually exclusive folder.

Recommended principle:

**Ontology describes what things are.

Relationships describe how they connect.

Tags describe facets.

Categories organize navigation.

Pages explain them to people.**

Canonical taxonomy and page policy

The complete BuiltToResist taxonomy should be organized for readers into seven broad browse domains while using the smaller entity ontology underneath.

BuiltToResist
│
├── History
│   ├── Revolutions
│   ├── Uprisings
│   ├── Other Historical Events
│   ├── Countries & Polities
│   ├── Historical Eras
│   └── Timelines
│
├── Movements & Actors
│   ├── Movements
│   ├── Leaders
│   ├── Organizations
│   ├── Institutions
│   └── Scholars
│
├── Ideas & Law
│   ├── Ideologies
│   ├── Political Concepts
│   └── Legal Doctrines
│
├── Dynamics
│   ├── Mechanisms
│   └── Outcomes
│
├── Analysis
│   ├── Cases
│   ├── Scenarios
│   └── Questions
│
├── Evidence
│   ├── Primary Sources
│   ├── Books
│   ├── Archives
│   └── Media
│
└── Research & Data
    ├── Research Reports
    ├── Statistics
    └── Datasets

That is a navigation hierarchy, not the ontology. A scholar remains a Person; “Scholar” is their role. A revolution remains a HistoricalEvent; “Revolution” is its event classification. A book remains a CreativeWork.

Complete treatment of the requested taxonomy

Requested conceptCanonical modelStandalone page policyPrincipal relationships
RevolutionsHistoricalEvent + event type RevolutionNamed revolutions get pages. “Revolutions” itself is a browse hub and concept page.occurredIn, involvedMovement, hasParticipant, usedMechanism, resultedIn, documentedBy, partOf
UprisingsHistoricalEvent + event type UprisingNamed uprisings get pages. The generic term may have a concept page.Same event relationships
MovementsMovementNamed, identifiable movements get pages.operatesIn, alignedWithIdeology, ledBy, usesMechanism, participatedIn, hasOutcome, opposedBy
IdeologiesConcept with concept kind IdeologyRecognized ideological traditions generally deserve pages; narrow adjectival descriptors may remain tags.broader, narrower, related, influenced, adoptedBy, opposedBy
LeadersPerson + contextual role LeaderPerson page, not separate “leader object.”leads, memberOf, participatedIn, influenced, authored
InstitutionsInstitutionReusable institutional forms and historically important named institutions get pages.enablesMechanism, constrainsMechanism, governedByDoctrine, involvedInScenario, operatesInPolity
MechanismsConcept kind MechanismReusable causal/operational mechanisms deserve pages; individual instances do not.enabledByInstitution, constrainedByInstitution, observedInCase, contributesToOutcome
OutcomesConcept kind OutcomeType; specific outcome recorded as statementMajor reusable outcome concepts get pages; each individual occurrence does not.resultOf, possibleOutcomeOf, associatedWith
CountriesPolity/Place, including historical statesEvery polity referenced materially should have a page.containsPlace, predecessor, successor, siteOf, hasInstitution, hasLegalDoctrine
Historical erasConcept kind HistoricalEraEstablished or editorially useful periodizations get pages; arbitrary decades remain facets.associatedEra, precedes, overlaps, appliesToRegion
Legal doctrinesConcept kind LegalDoctrineDistinct doctrines with reusable explanatory value get pages.appliesInJurisdiction, authorizesInstitution, constrainsInstitution, interpretedBy, derivedFromInstrument
Political conceptsConcept kind PoliticalConceptSubstantive concepts get pages. Minor descriptors remain controlled tags.broader, narrower, related, contrastsWith, appliesTo
BooksCreativeWork subtype BookBooks cited or analyzed materially get bibliographic pages.authoredBy, about, citedBy, influenced, publishedBy
ScholarsPerson + role ScholarScholars materially represented in the research corpus get person pages.authored, studies, associatedWithInstitution, citedBy
Primary sourcesRelationship role, usually a CreativeWork, media item, or archival objectIndividually catalogued primary materials can get source pages; “primary” is contextual, not immutable.isPrimarySourceFor, createdBy, heldBy, documents, transcribedAs
CasesAnalysis subtype CaseCurated analytical cases get pages.caseOf, analyzesEvent, analyzesMovement, analyzesMechanism, evaluatesOutcome, cites
ScenariosAnalysis subtype ScenarioOnly intentionally authored hypothetical/forward-looking scenarios get pages.assumes, involvesInstitution, usesMechanism, hasPossibleOutcome
QuestionsAnalysis subtype QuestionEvery substantive answerable research question can have one canonical page.hasAnswer, hasDeepAnalysis, about, supportedBySource
TimelinesCollection / ordered editorial viewCurated timelines with explanatory value get pages; routine chronology should be generated from event data.includesEvent, about, orderedByDate
ArchivesSplit between ArchiveOrganization and ArchiveCollectionRepository and collection pages should be distinct.holdsCollection, containsSource, maintainedBy, about
Research reportsCreativeWork subtype ResearchReportCited or published reports get pages.authoredBy, usesDataset, analyzes, cites, publishedBy
OrganizationsOrganizationNamed bodies relevant to the subject get pages.participatedIn, memberOf, ledBy, opposedBy, supportedBy, operatesIn
MediaCreativeWork/MediaObjectImportant articles, films, recordings, photographs, maps or media collections can get pages; individual assets need not all receive prose pages.createdBy, depicts, documents, publishedBy, isPrimarySourceFor
StatisticsMetric/Dataset + Observation rowsPage per indicator/series or dataset; not one page per datapoint.measures, observes, forPlace, forPeriod, derivedFromDataset

Several categories should be roles, not entity classes

This prevents important semantic errors.

Leader is a role of a person in relation to a movement, organization, or event:

Person A
  └─ leads → Movement B
       qualifier: 1980–1989
       qualifier: role = chair

A person might simultaneously be a scholar, dissident, government official, organizer, author, and movement leader.

Scholar is likewise a person role or professional classification.

Primary source is especially important to model relationally. A memoir can be a primary source for the author's participation in an event and a secondary interpretation of an earlier period. Calling the work intrinsically “PrimarySource” would erase that distinction. The canonical assertion should therefore be:

CreativeWork BTR-...
   └─ isPrimarySourceFor → HistoricalEvent BTR-...

rather than:

CreativeWork type = permanently-primary-source

The browse page /primary-sources/ can simply query all works having one or more isPrimarySourceFor statements.

Revolutions and uprisings should not be separate database universes

Both should inherit from HistoricalEvent.

HistoricalEvent
├── Revolution
├── Uprising
├── Rebellion
├── ProtestWave
├── StrikeWave
├── Coup
├── Transition
├── Crackdown
└── OtherEvent

An event can carry more than one scholarly classification if necessary:

Event: BTR000042
classification: Uprising
  source: Scholar A
  rank: preferred

classification: Revolution
  source: Scholar B
  status: disputed

The point is not to decide every historiographical dispute in the database schema. It is to make the schema capable of preserving the dispute. Qualified statements and source references are the appropriate architecture for that requirement.

Institutions and organizations must remain distinct

This is one of the most consequential distinctions in the ontology.

An organization is an actor or body:

Supreme Court of Country X
Trade Union Y
Army Z
Political Party Q
Ministry of Interior

An institution is a durable system of rules, offices, practices, authority, or political structure:

constitutional review
bicameral legislature
military conscription
emergency rule
competitive elections
monarchy
federalism
civil service

A particular body can be related to an institutional form, but they should not be interchangeable.

For example:

Supreme Court of X       → Organization
constitutional judiciary → Institution
judicial review           → LegalDoctrine / PoliticalConcept

This allows queries such as:

“Find cases involving constitutional courts where judicial review constrained an emergency-powers mechanism.”

That query becomes difficult if “court,” “judiciary,” and “judicial review” are flattened into the same category.

What deserves a page

An entity should normally receive a standalone encyclopedia page when at least one of the following is true and it passes the identity test below:

It is a named historical entity of independent importance; it is likely to be a search destination; it needs explanation beyond a one-line definition; it has meaningful inbound or outbound graph relationships; it is repeatedly cited across the encyclopedia; or it is an editorial object deliberately created by BuiltToResist, such as a case, question, timeline, scenario, or report.

The identity test is stricter:

Can an editor state clearly what this thing is, distinguish it from neighboring things, assign it a stable ID, and cite independent evidence for it?

If yes, it can become an entity.

For reusable concepts, a useful promotion threshold is:

Distinct definition                    required
At least 2 reliable supporting sources required
At least 3 substantive uses/inbound links preferred
Meaning beyond a simple facet          required
Likely to receive explanatory prose    preferred

Major concepts can be promoted before reaching the usage threshold; the threshold is a governance heuristic rather than a law.

What should remain a tag or field

Do not create pages merely because a descriptor appears frequently.

Good tag/facet candidates include:

  • geographic region;
  • century or decade;
  • violent/nonviolent classification of a particular episode;
  • success status;
  • source format;
  • language;
  • research theme;
  • protest tactic subtype;
  • institutional sector;
  • degree of certainty;
  • editorial workflow status.

Some terms begin as controlled tags and later become pages. The underlying ID should survive that promotion.

For example, elite-defection might initially be a mechanism tag. When enough cases and literature accumulate, its Concept entity can receive an explanatory page without requiring any retagging because the tag assignments already reference the same concept ID.

Tags should therefore be concept-backed, not strings.

Instead of:

tags = ["elite defection", "military", "regime change"]

store:

tags = [
  BTR-C-00118,
  BTR-C-00043,
  BTR-C-00331
]

with each concept carrying a preferred label, alternate labels, definition, concept scheme, and broader/narrower relationships. SKOS explicitly provides preferred, alternate and hidden labels as well as broader, narrower and related concept relationships, making it well suited to this layer.

Canonical relationships and graph schema

The heart of BuiltToResist should be a small governed relationship registry, rather than hundreds of ad hoc predicates invented page by page.

Canonical relationship families

The MVP should aim for roughly 25–40 well-defined predicates. New predicates should require schema review.

FamilyCanonical predicatesExamples
ClassificationinstanceOf, classifiedAs, broaderThan, narrowerThan, relatedConceptRevolution → type of HistoricalEvent
GeographyoccurredIn, operatesIn, appliesInJurisdiction, locatedInMovement → Country
TemporalprecededBy, followedBy, overlapsWith, partOfEventUprising → Revolution
ParticipationparticipatedIn, ledBy, opposedBy, supportedBy, memberOfMovement → Leader
IdeasalignedWithIdeology, influencedBy, opposesIdeologyMovement → Ideology
MechanismsusesMechanism, analyzesMechanism, enablesMechanism, constrainsMechanismCase → Mechanism
InstitutionstargetsInstitution, enabledByInstitution, governedByDoctrine, involvesInstitutionMechanism → Institution
OutcomesresultedIn, hasOutcome, contributesToOutcome, hasPossibleOutcomeScenario → Outcome
LegalgovernsInstitution, authorizesInstitution, constrainsInstitution, appliesInJurisdictionDoctrine → Institution
EvidencedocumentedBy, isPrimarySourceFor, cites, supportedBy, heldByEvent → Primary Source
WorksauthoredBy, publishedBy, about, usesDatasetBook → Scholar
AnalysiscaseOf, hasAnswer, hasDeepAnalysis, assumesConditionQuestion → Answer
Collectioncontains, includesEvent, partOfCollectionTimeline → Event
Datameasures, observesEntity, forPlace, derivedFromDatasetStatistic → Country
Identity/mappingsameAs, exactMatch, closeMatchBTR concept → external vocabulary

Use sameAs sparingly for genuine identity. Conceptual correspondences that are merely very similar should instead use something like SKOS exactMatch or closeMatch; SKOS deliberately distinguishes several mapping relationships.

Canonical versions of the relationships requested

The examples in the brief should be formalized as follows:

Requested relationshipCanonical predicateImportant qualifiers
Movement → countryoperatesInfrom, to, primaryArea, scope
Movement → ideologyalignedWithIdeologyfrom, to, attribution, degree, disputed
Movement → outcomehasOutcomedegree, directness, status, source
Case → mechanismanalyzesMechanismimportance, finding, confidence
Mechanism → institutionenabledByInstitution, constrainedByInstitution, or targetsInstitutionDo not collapse causal direction into relatedTo
Institution → scenarioinverse of involvesInstitutionrole, assumption
Scenario → outcomehasPossibleOutcomeprobability only if methodologically justified; conditions
Legal doctrine → institutiongovernsInstitution, optionally authorizesInstitution/constrainsInstitutionjurisdiction, from, to, instrument
Historical event → primary sourcesdocumentedBysourceRole=primary, date, locator, reliabilityNote
Question → answerhasAnswerrevision/version
Answer → deep analysishasDeepAnalysisrevision/version
Deep analysis → sourcescites / supportedBylocator, claim supported

Why directional predicates matter

Avoid a universal relatedTo relationship except as a last-resort editorial association.

These are materially different:

Institution → enables → Mechanism
Institution → constrains → Mechanism
Movement    → targets → Institution
Mechanism   → undermines → Institution

Flattening all four into relatedTo makes the graph visually dense while destroying most of its analytical value.

The rule should be:

If editors would want to filter, rank, infer, or phrase the relationship differently, it deserves a semantically specific predicate.

At the same time, avoid creating predicates like:

temporaryLeaderOf
formerLeaderOf
coLeaderOf
actingLeaderOf
regionalLeaderOf

Use:

leads

plus qualifiers:

role = acting leader
scope = regional
from = ...
to = ...

This is exactly the kind of contextual information that qualified-statement architectures are designed to represent.

Every significant relationship should be a statement

The core statement record should support:

statement_id
subject_entity_id
predicate_id
object_entity_id | object_literal

assertion_status
rank
confidence

valid_from
valid_to
date_precision
place_id

created_at
updated_at
reviewed_at

And zero or more:

qualifiers[]
citations[]

Recommended assertion_status vocabulary:

asserted
disputed
uncertain
inferred
attributed
hypothetical
deprecated

This is particularly important for scenarios. No scenario relationship should accidentally enter the graph as a historical assertion.

For example:

Scenario: General strike under emergency rule
  hasPossibleOutcome → negotiated transition
  assertion_status   → hypothetical

versus:

HistoricalEvent: Event X
  resultedIn → negotiated transition
  assertion_status → asserted

A single status field prevents an enormous class of semantic errors in downstream AI and graph applications.

Provenance should attach to individual claims

Citations should not exist only as a bibliography at the bottom of a page. The graph should know which source supports which assertion.

Recommended pattern:

STATEMENT S-4831
subject:     Movement A
predicate:   alignedWithIdeology
object:      Ideology B

qualifier:
  from: 1977
  to: 1984

citation:
  source_id: WORK-2041
  locator: pp. 113–117
  note: author's characterization

W3C PROV-O exists specifically to represent provenance information, while the broader W3C Data on the Web recommendations emphasize persistent identifiers, metadata, versioning and provenance as foundations of reusable, trustworthy data.

BuiltToResist does not need to expose native PROV-O internally on day one, but its schema should be PROV-compatible so provenance can later be exported cleanly.

Graph model

At a logical level:

(:Entity)-[:STATEMENT]->(:Entity)

is insufficient because the relationship itself needs data.

The canonical logical representation is:

(Entity)
   │ subject
   ▼
(Statement) ── predicate ──> (Predicate)
   │
   ├── object ─────────────> (Entity or Literal)
   ├── qualifier ──────────> (Qualifier)
   └── citation ───────────> (Source Entity)

A relational database can implement that structure perfectly well; a separate graph database is not required for the MVP. The same records can later be projected into RDF, a property graph, or a graph-search index.

Domain and range rules

Every predicate should itself have metadata:

predicate:
  code: alignedWithIdeology
  label: aligned with ideology
  inverse_label: ideology of movement
  domain: [Movement, Organization]
  range: [Ideology]
  symmetric: false
  transitive: false
  source_required: true
  allowed_qualifiers:
    - from
    - to
    - attribution
    - certainty

Invalid relationships can then be prevented automatically.

For example:

Movement → alignedWithIdeology → Country

would fail validation because Country is outside the predicate's range.

Special handling for outcomes and mechanisms

Mechanism pages should describe reusable processes, such as:

elite defection
general-strike disruption
security-force fragmentation
information blockade
repression
sanctions pressure
negotiated pact
parallel institution building

A particular military unit defecting on a particular date is not a new “mechanism.” It is an event or evidence that the general mechanism occurred.

Similarly, Outcome should usually mean a reusable outcome class:

regime collapse
leadership replacement
constitutional reform
policy concession
negotiated transition
movement suppression
civil-war escalation
territorial secession
stalemate

An actual instance is represented by the relationship:

Event X → resultedIn → constitutional reform

with qualifiers that identify the specific reform.

This prevents the ontology from developing thousands of one-off “outcome concepts.”

URLs, entity identity, tags, categories, and breadcrumbs

BuiltToResist should separate persistent machine identity from human-readable page location.

W3C guidance on Web identifiers emphasizes simplicity, stability, and manageability, including avoiding implementation-specific pieces in persistent identifiers. W3C also explicitly distinguishes the URI identifying a thing from the HTML or machine-readable document describing that thing.

Stable entity IDs

Use opaque, semantically neutral IDs:

BTR00000001
BTR00000002
BTR00000003

Do not encode the entity's current type, country, date, or title into its immutable ID.

Bad:

REV-FRANCE-1789-0001
MOV-POLAND-1980-0021

Those identifiers become wrong when classification changes.

Better:

BTR00018427

with properties:

type = HistoricalEvent
event_type = Revolution
preferred_label = French Revolution

Recommended identifiers:

Entity:     BTR00018427
Statement:  BTRS00049281
Predicate:  BTRP00000117
Page:       BTRPG00003341
Revision:   BTRR00099120
Dataset:    BTRD00000073

The prefixes should distinguish technical object classes only, not historical interpretation.

Persistent identifier URLs

Give every entity a permanent identifier URI:

/id/BTR00018427

That URI should remain valid even when page titles or sections change.

The corresponding human page could be:

/event/french-revolution

and machine representation:

/api/v1/entities/BTR00018427

The three should explicitly identify one another.

/id/BTR00018427
        │
        ├── describes/links → /event/french-revolution
        └── data            → /api/v1/entities/BTR00018427

Persistent URIs are also recommended by W3C for datasets and identifiers inside datasets because they enable durable citation, linking, and reuse; the guidance also encourages linking to existing external identifiers when appropriate.

Human URL structure

Do not replicate all 24 taxonomy types as independent technical silos. Use a smaller family structure.

Recommended canonical page paths:

/event/french-revolution
/event/hungarian-uprising-1956

/movement/solidarity-poland
/movement/people-power-movement

/person/vaclav-havel
/person/hannah-arendt

/organization/solidarity-trade-union
/organization/congress-of-south-african-trade-unions

/institution/constitutional-court
/institution/emergency-rule

/concept/nonviolent-resistance
/concept/elite-defection
/concept/liberalism
/concept/martial-law
/concept/regime-change

/place/poland
/place/czechoslovakia

/work/from-dictatorship-to-democracy
/work/declaration-of-the-rights-of-man

/case/...
/scenario/...
/question/...
/timeline/...
/archive/...
/dataset/...

The browse hubs retain the terminology readers expect:

/revolutions/
/uprisings/
/movements/
/ideologies/
/leaders/
/institutions/
/mechanisms/
/outcomes/
/countries/
/eras/
/legal-doctrines/
/political-concepts/
/books/
/scholars/
/primary-sources/
/cases/
/scenarios/
/questions/
/timelines/
/archives/
/research-reports/
/organizations/
/media/
/statistics/

A browse hub is a query/view, not necessarily a fundamental type.

Thus:

/leaders/

lists Person entities that possess leader relationships.

/scholars/

lists Person entities with scholar roles.

/primary-sources/

lists works and media that have isPrimarySourceFor relationships.

That is a major anti-explosion mechanism.

Slug policy

Human-facing slugs should be:

  • lowercase;
  • ASCII normalized where necessary;
  • hyphenated;
  • concise;
  • disambiguated only when required.

Examples:

/person/jose-marti
/event/russian-revolution
/event/russian-revolution-1905
/movement/solidarity-poland

The slug is not the identity. A renamed page simply receives a 301 redirect from its old route while retaining the same BTR... ID.

External identifiers

Each entity may carry many external identifiers:

Wikidata QID
VIAF
ISNI
Library of Congress identifier
ISBN
DOI
ORCID
GeoNames
national archive identifier
university repository identifier
dataset DOI

Store these in a repeatable external-ID table:

entity_id
identifier_scheme
identifier_value
identifier_uri
match_type

Recommended match_type:

same
exactConceptMatch
closeConceptMatch
related

This reflects the distinction between actual entity identity and vocabulary mapping. SKOS provides mappings such as exactMatch, closeMatch, broadMatch, narrowMatch, and relatedMatch, specifically enabling concept systems to interoperate without pretending every correspondence is strict identity.

Category strategy

Only a small number of editorially governed navigation categories should exist.

Recommended major category schemes:

Content family
Event type
Geography
Historical period
Ideological family
Mechanism family
Institutional domain
Outcome family
Source/evidence type
Research theme

Categories must not proliferate into every possible combination.

Never manually create categories like:

20th-century-left-wing-revolutions-in-latin-america
successful-nonviolent-anti-authoritarian-movements
military-defection-cases-in-eastern-europe

Those are faceted queries:

/event/?era=20th-century
       &region=latin-america
       &ideology=left

or curated editorial landing pages if they genuinely deserve narrative treatment.

This single rule prevents thousands of near-empty intersection categories.

Controlled tag schemes

Public tags should belong to an explicit ConceptScheme.

Example:

TagScheme: mechanism
  ├── elite behavior
  │   ├── elite split
  │   └── elite defection
  ├── coercion
  │   ├── repression
  │   └── selective repression
  └── collective action
      ├── mass mobilization
      └── strike disruption

Separate scheme:

TagScheme: outcome
  ├── regime transformation
  │   ├── leadership replacement
  │   └── regime collapse
  ├── policy change
  └── repression

SKOS ConceptScheme, Concept, broader, narrower, related, prefLabel, altLabel, and scopeNote directly support this architecture.

Every controlled term should carry:

concept_id
preferred_label
alternate_labels[]
definition
scope_note
scheme
broader_concept[]
related_concept[]
status
created_at
reviewed_at

The scope_note is crucial. For example:

Preferred label: elite defection

Scope note:
Use when members of an incumbent political, military, economic,
or bureaucratic elite withdraw material support from the ruling
coalition. Do not use merely for public criticism by an individual.

That makes the taxonomy usable consistently by editors and agents.

Historical eras should be associative, not rigid containers

Historical periods vary across region and scholarly tradition.

Therefore:

Event → associatedEra → Cold War

is safer than assuming an event is ontologically “inside” exactly one era.

An era can have approximate dates and geographical scope:

HistoricalEra
  start_date
  end_date
  date_precision
  applicable_region[]
  broader_era[]
  scope_note

The same event may belong legitimately to multiple overlapping periodizations.

Countries need historical-polity modeling

Do not maintain only a list of present-day countries.

Use:

Place
 └── Polity
      ├── CurrentCountry
      ├── HistoricalState
      ├── Colony
      ├── Territory
      └── DisputedPolity

with:

predecessor
successor
valid_from
valid_to
capital
territory

Then an event can be located in the polity that existed at the time, while geographical relationships can also point toward present-day locations where useful.

Breadcrumbs should represent one comprehensible editorial path, not every possible graph relationship. Google describes a breadcrumb as the page's position in the site's hierarchy, allowing users to move upward through that hierarchy.

Recommended examples:

Home
› History
› Revolutions
› French Revolution
Home
› Ideas & Law
› Ideologies
› Anarchism
Home
› Dynamics
› Mechanisms
› Elite Defection
Home
› Evidence
› Books
› From Dictatorship to Democracy
Home
› Analysis
› Questions
› Why do security forces defect?

Keep canonical breadcrumbs shallow: normally Home + two or three meaningful levels.

Do not make geography part of the breadcrumb for every page:

Home > Europe > Eastern Europe > Poland > 1980s > Movements > Solidarity

That is a taxonomy trap. Poland, Eastern Europe, and the 1980s should be facets and contextual links.

Every page can nevertheless display a context panel:

Country: Poland
Era: Cold War
Ideology: multiple
Mechanisms: strikes, elite negotiation
Outcome: negotiated transition

Breadcrumbs answer “where am I in the site?”

Facets answer “what is this connected to?”

A graph-driven encyclopedia should still feel simple to a human visitor. The graph belongs underneath the interface; the primary navigation should expose recognizable research journeys.

A scalable primary navigation could be:

Explore
History
Movements & Actors
Ideas & Law
Dynamics
Evidence
Analysis
Research & Data
Search

Explore should be the principal discovery interface rather than an enormous category tree.

Its facets should include:

Entity type
Country / polity
Region
Date range
Historical era
Event type
Movement
Ideology
Mechanism
Institution
Outcome
Legal doctrine
Source type
Research theme

Users should be able to construct questions such as:

Revolutions in Europe, 1900–2000, involving military defections and resulting in regime change.

or:

Cases involving labor movements, general strikes, and negotiated transitions.

The database can answer those from graph dimensions without any bespoke “category page.”

Entity-page template

Most substantive entity pages should share a stable anatomy:

Title
Aliases / alternate names
One-sentence definition

Lead summary
Key facts / entity card

Main narrative
  Background
  Development / operation
  Significance
  Interpretations / disputes

Structured relationships
  People
  Movements
  Events
  Countries
  Ideas
  Institutions
  Mechanisms
  Outcomes

Chronology, when relevant

Primary sources
Scholarship / further reading

Data / statistics, when relevant

Related pages
Revision and citation information

Not every type needs every block. Type-specific modules should extend this shell.

A mechanism page, for example, should emphasize:

Definition
Scope / exclusions
Causal logic
Conditions
Observed cases
Institutions that enable/constrain it
Possible outcomes
Competing interpretations
Evidence

A country page should emphasize:

Historical polities
Revolutions and uprisings
Movements
Institutions
Legal doctrines
Organizations
Timeline
Research
Data

A book page should emphasize:

Bibliographic record
Author
Summary
Principal arguments
Subjects
Events/cases discussed
Reception/importance
Citations elsewhere on BuiltToResist

Questions as a distinct editorial architecture

Questions are extremely useful for both readers and agents because they map natural-language research intent onto encyclopedia evidence.

A canonical question page should be:

Question
   ↓
Direct Answer
   ↓
Deep Analysis
   ↓
Counterarguments / uncertainty
   ↓
Examples / cases
   ↓
Sources
   ↓
Related Questions

In the knowledge graph:

Question
  ├─ hasAnswer ────────> AnswerBlock
  ├─ about ────────────> Concept / Event / Mechanism
  └─ relatedQuestion ──> Question

AnswerBlock
  └─ hasDeepAnalysis ──> AnalysisBlock

AnalysisBlock
  ├─ cites ────────────> Source
  ├─ usesCase ─────────> Case
  └─ discusses ────────> Entity

AnswerBlock and AnalysisBlock do not initially need their own public pages. Give them stable fragment or content IDs:

/question/why-do-security-forces-defect#answer
/question/why-do-security-forces-defect#analysis

and internal IDs:

BTRBLOCK000492
BTRBLOCK000493

Promote a block to a full page only if it becomes independently reusable or citable.

This preserves the requested:

Question → answer → deep analysis → sources

without creating thousands of tiny pages.

Timelines should usually be generated views

A historical event should have a date in the event graph once.

A timeline then selects and orders those events:

Timeline
  ├─ includesEvent → Event A [order 1]
  ├─ includesEvent → Event B [order 2]
  └─ includesEvent → Event C [order 3]

Do not copy event descriptions into separate timeline records.

Only curated timelines with explanatory framing deserve independent pages:

/timeline/fall-of-communism-eastern-europe

A purely automatic “events in 1987” view can remain a generated query page.

Archive architecture

“Archive” is ambiguous and should be split.

Archive Organization
National Archives of ...
Library of ...
University collection repository

versus:

Archive Collection
Papers of Person X
Movement Y Collection
Underground Press Collection

The graph becomes:

ArchiveOrganization
  └─ holdsCollection → ArchiveCollection
                         └─ containsSource → PrimarySource

This matters because repository, collection, and document have different metadata and different relationships.

For digitized archival objects, IIIF is a particularly valuable interoperability layer. IIIF Presentation defines Collections containing Collections or Manifests, with Manifests organizing canvases and annotations, which maps naturally to digital collections, scanned documents, pages, images, transcripts, and annotations.

Statistics architecture

Do not model:

“Population of Country X in 1974 = 12,391,000”

as a standalone encyclopedia page.

Use:

Metric
  ↓
Dataset / Series
  ↓
Observation

Example:

Metric: protest fatalities
Dataset: BTR Political Mobilization Indicators
Observation:
  subject = Event X
  place = Country Y
  period = 1989
  value = 31
  unit = persons
  method = ...
  source = ...
  uncertainty = ...

Standalone pages belong to:

  • the metric definition;
  • the dataset;
  • a meaningful statistical series or visualization;
  • occasionally a major research finding.

Datapoints live in the data layer.

DCAT is designed for cataloguing datasets and data services and supports identifiers, titles, creators, publishers, themes, keywords, landing pages, versions and related metadata. It explicitly supports SKOS concept schemes for thematic dataset classification, making a DCAT-compatible catalog a strong fit for BuiltToResist's statistical layer.

“Related pages” should not be hand-maintained except for editorial overrides.

Use a reproducible ranking algorithm.

A good starting score:

SignalSuggested weight
Explicit direct graph relationship+40
Same mechanism+25
Same event or movement+25
Same specific institution+20
Same outcome+18
Same country/polity+15
Same ideology+12
Temporally overlapping+10
Shared sources/citations+8
Same broad era+5
Editorial featured relationship+20

Then apply diversity constraints:

maximum related results: 10
maximum same-type results: 4
prefer at least 3 different entity families
deduplicate aliases / redirects
exclude current page
exclude deprecated entities
downrank weak matches based only on broad era or country

Most importantly, show the reason:

Elite Defection
Related because:
Mechanism observed in this case
Polish Round Table Talks
Related because:
Same movement · same country · direct event relationship

This makes the graph legible rather than mysterious.

Context-specific relations should outrank similarity

A reader on a movement page is generally better served by:

Leaders
Events
Ideologies
Mechanisms
Outcomes
Primary Sources

than by ten other pages that happen to share the tag “Cold War.”

Therefore related-page ranking should prioritize typed direct relationships, then increasingly broad similarity signals.

Structured data and agent-readable architecture

BuiltToResist should treat machine-readable access as a first-class publication format, not an afterthought.

The Web standards picture is complementary:

  • Schema.org / JSON-LD for page-level semantic markup;
  • SKOS for controlled vocabularies;
  • PROV-O-compatible provenance for claim origin and derivation;
  • DCAT for datasets and services;
  • IIIF for digital primary-source collections and media;
  • persistent HTTP identifiers for entities;
  • an API and bulk downloads for complete access.

W3C's Data on the Web guidance explicitly recommends persistent identifiers, machine-readable standardized formats, multiple representations, APIs, metadata, vocabulary reuse, subsets and bulk downloads.

JSON-LD on every canonical page

Every canonical page should emit JSON-LD whose @id is the permanent entity identifier, not merely the current page URL.

Conceptual example:

{
  "@context": [
    "https://schema.org",
    {
      "btr": "https://builtoresist.org/vocab/"
    }
  ],
  "@id": "https://builtoresist.org/id/BTR00018427",
  "@type": ["Event", "btr:Revolution"],
  "name": "Example Revolution",
  "url": "https://builtoresist.org/event/example-revolution",
  "startDate": "1989-01-01",
  "endDate": "1989-12-31"
}

Schema.org provides generic types for entities including CreativeWork, Book, audio/image/video objects, Event, Organization, Person, and Place.

Google recommends JSON-LD for structured data, recommends using the most specific applicable type, and requires structured data to represent the actual visible content rather than hidden or unrelated information. Structured-data implementation should therefore mirror the page rather than becoming a second hidden encyclopedia.

BuiltToResist entityPublic structured-data mapping
Historical Event / Revolution / Uprisingschema:Event + internal btr: type
Person / Leader / Scholarschema:Person
Organizationschema:Organization
Institution as abstract systemschema:Thing or DefinedTerm + internal type
Country / Placeschema:Place / applicable geographic subtype
Ideologyschema:DefinedTerm + btr:Ideology
Mechanismschema:DefinedTerm + btr:Mechanism
Outcome typeschema:DefinedTerm + btr:Outcome
Political conceptschema:DefinedTerm
Legal doctrineschema:DefinedTerm + internal legal type
Historical eraschema:DefinedTerm
Bookschema:Book
Research reportschema:CreativeWork / more specific work type where applicable
Primary-source documentappropriate CreativeWork subtype
Imageschema:ImageObject
Videoschema:VideoObject
Audioschema:AudioObject
Dataset / statistical seriesschema:Dataset + dcat:Dataset
Timelineschema:CollectionPage / ordered ItemList
Questionschema:Question within its Web page representation
Answerschema:Answer
Breadcrumbsschema:BreadcrumbList
Browse/index pageschema:CollectionPage / ItemList

Do not equate “can be expressed in schema.org” with “will receive a search-engine rich result.” Google explicitly states that correct structured markup does not guarantee a rich result.

For dataset pages specifically, dataset structured metadata can expose elements such as the name, description, creator, and distribution formats, and Google documents this metadata as a mechanism for dataset discovery.

Internal vocabulary namespace

Publish BuiltToResist's own controlled semantics:

/vocab/
/vocab/Movement
/vocab/Revolution
/vocab/Mechanism
/vocab/hasOutcome
/vocab/analyzesMechanism

and a machine-readable vocabulary document:

/vocab/btr.ttl
/vocab/btr.jsonld

This vocabulary should define:

Classes
Predicates
Domain/range rules
Inverse predicates
Concept schemes
Status vocabularies
Version
Change log

The site can then use established standards where they fit and btr: extensions where they do not.

Agent-readable indexes

A modern encyclopedia should expose deterministic machine inventories, rather than expecting agents to discover everything through HTML crawling.

Recommended endpoints:

/sitemap.xml

/api/v1/entities
/api/v1/entities/{id}
/api/v1/statements
/api/v1/search
/api/v1/concepts
/api/v1/changes

/data/catalog.jsonld
/data/entities.ndjson
/data/statements.ndjson
/data/concepts.jsonld
/data/datasets/

/index/events.json
/index/movements.json
/index/people.json
/index/concepts.json
/index/works.json
/index/sources.json
/index/datasets.json

/vocab/btr.jsonld
/vocab/btr.ttl

Each machine index should minimally expose:

id
type
preferred_label
canonical_url
updated_at
language
status

and permit pagination or cursor traversal.

Sitemap strategy

Use a sitemap index split by stable content families:

/sitemaps/events.xml
/sitemaps/movements.xml
/sitemaps/people.xml
/sitemaps/concepts.xml
/sitemaps/places.xml
/sitemaps/works.xml
/sitemaps/analysis.xml
/sitemaps/datasets.xml

Sitemaps are explicitly intended to tell search engines which site URLs are available for crawling and can include update metadata.

The sitemap should list canonical public pages, not every faceted query permutation.

Bulk data export

Publish versioned dumps:

/data/releases/2026-09/entities.ndjson
/data/releases/2026-09/statements.ndjson
/data/releases/2026-09/concepts.jsonld
/data/releases/2026-09/citations.ndjson

plus:

manifest.json
checksums
license
schema_version
created_at
previous_release

This gives research tools and agents a much more reliable interface than scraping HTML. It also aligns with W3C recommendations for bulk downloads, machine-readable formats, metadata, APIs, and version-aware data publication.

Content negotiation

The permanent resource ID can optionally support content negotiation:

GET /id/BTR00018427
Accept: text/html
→ human representation

Accept: application/ld+json
→ linked-data representation

Alternatively, the identifier can redirect to explicitly linked HTML and JSON-LD resources. W3C documents both the distinction between entity identifiers and description-document identifiers and the value of explicitly linking the relevant URIs.

A DCAT catalog for research assets

Publish:

/data/catalog.jsonld

containing catalog records for:

datasets
statistical series
bulk knowledge-graph dumps
research corpora
API data services

DCAT's Catalog, Dataset, DataService, Distribution, and CatalogRecord structures are directly suited to this requirement, including versions, landing pages, identifiers, publishers, licenses, themes, and related metadata.

IIIF for archives and scanned sources

Where BuiltToResist hosts or interoperates with digitized archival material:

Archive Collection
      ↓
IIIF Collection
      ↓
Manifest
      ↓
Canvas
      ↓
page/image/audio/video
      ↓
annotations/transcription

IIIF Presentation explicitly models Collections, Manifests, Canvases, annotation pages, and ordered ranges, making it well suited to books, manuscripts, posters, newspapers, photographs and archival sequences.

Optional agent convenience file

An llms.txt-style file can be supplied as a convenience index, but it should never be the authoritative representation of the encyclopedia.

For example:

/llms.txt

might point agents toward:

API documentation
entity index
knowledge-graph vocabulary
bulk dumps
citation policy
content license

No fact should exist only in this file. The durable machine contract should remain HTTP pages, JSON-LD, stable identifiers, sitemaps, APIs, and downloadable data.

Minimum viable schema and governance for 10,000+ pages

The minimum viable implementation should be entity-centric, relationship-centric, and provenance-aware from day one. Trying to retrofit identifiers and structured relationships after thousands of articles exist is considerably harder than allowing prose complexity to grow on top of a stable data core.

Core database schema

A practical MVP requires roughly the following tables.

TablePurposeEssential fields
entitiesOne record per identified thing or conceptid, entity_type, preferred_label, summary, status, temporal fields
entity_typesGoverned class registrycode, parent_type, external mappings
labelsPreferred/alternate/historical namesentity_id, language, label, label_type
pagesPublished human pagespage_id, entity_id, canonical_path, title, body, status, revision
predicatesCanonical relationship vocabularypredicate_id, code, domain, range, inverse, qualifier rules
statementsEntity-to-entity or entity-to-literal assertionssubject, predicate, object, status, rank, dates
statement_qualifiersContext of assertionsstatement, qualifier predicate, value
statement_sourcesClaim-level provenancestatement, source entity, locator, note
external_idsLinks to outside authority identifiersentity, scheme, value, match type
concept_schemesControlled facet vocabulariesscheme ID, title, description
concept_assignmentsTags/classificationsubject, concept, relation/relevance
media_assetsHosted or referenced mediaentity, media type, URI, rights, creator, alt text
observationsStatistical datapointsmetric, subject/place, period, value, unit, dataset
revisionsEditorial historyobject, revision, author/editor, timestamp, change note

This is enough to build the site without locking the project into a page-centric CMS model.

Canonical entity record

A generic entity should minimally support:

id
entity_type
preferred_label
short_label
description
status

start_date
end_date
date_precision

created_at
updated_at
reviewed_at

Do not add 100 nullable columns to entities.

Type-specific fields can live in extensions:

event_details
person_details
work_details
place_details
dataset_details

or equivalent normalized tables.

Minimum event record

entity_id
event_type
start_date
end_date
date_precision

locations[]
participants[]
parent_event[]
classifications[]

Location and participants should be relationships, not comma-separated fields.

Minimum concept record

Concepts should still use the common entity table, with additional taxonomy data:

entity_id
concept_kind
concept_scheme
preferred_label
alternate_labels[]
scope_note
broader[]
narrower[]
related[]

The SKOS distinction between concepts, concept schemes, collections, labels, semantic relations and mapping relations provides a mature model for precisely this purpose.

Minimum work/source record

entity_id
work_type
title
creator[]
publication_date
publisher
language
identifier[]
rights
digital_copy[]
archive_collection[]

“Primary source” should then remain a relationship:

work_id
  isPrimarySourceFor
event_id

Minimum dataset/statistics record

Dataset
  id
  title
  creator
  publisher
  description
  temporal_coverage
  geographic_coverage
  methodology
  license
  version
  distributions[]

and separate:

Observation
  metric_id
  subject_id
  place_id
  period_start
  period_end
  value
  unit
  uncertainty
  method
  dataset_id

DCAT already defines a catalog model with datasets, distributions, catalog records, data services and metadata such as identifiers, titles, creators, publishers, versions and landing pages; BuiltToResist should map its public data catalog to that model instead of inventing an incompatible dataset standard.

Relationship validation rules

Every statement should pass several automatic checks:

CheckExample
Domain validityalignedWithIdeology subject must be a permitted actor type
Range validityobject must be Ideology
Temporal logicvalid_from cannot follow valid_to
Hypothetical isolationscenario claims must carry hypothetical status
Source requirementcontested factual claims require citations
Duplicate detectionequivalent statement already exists
Self-relation checkdisallow nonsensical self-links unless predicate permits
Deprecated target checkredirect statements toward canonical merged entity
Qualifier validityonly allowed qualifiers for predicate
Identity rulesameAs requires stronger evidence than closeMatch

The anti-taxonomy-explosion rules

These should be written into the editorial handbook as hard governance principles.

Use one canonical entity, not duplicate entities by context.

Do not create:

Elite Defection in Revolutions
Elite Defection in Uprisings
Elite Defection in Nonviolent Campaigns

Create:

Elite Defection

and relationships to relevant cases.

Never create compound tags when facets can be combined.

Bad:

1980s-Polish-nonviolent-labor-movements

Good:

decade = 1980s
country = Poland
tactic = nonviolent action
actor base = labor
entity type = Movement

Keep the public browse tree shallow.

The graph can be highly connected and SKOS concepts can have broader/narrower relationships, but the visible site hierarchy should rarely exceed roughly three meaningful levels beneath Home.

Prefer qualifiers over new predicates.

Do not create formerLeaderOf, interimLeaderOf, coLeaderOf if leads plus role/time qualifiers represents the distinction.

Prefer roles over duplicate entity types.

Leader and Scholar → Person.

Primary Source → relationship role of a work/media item.

Current Country and Historical State → subtypes/roles of Polity.

Prefer generated collections over permanent category pages.

“Revolutions in Africa in the 1970s” is a query unless editors intentionally write a substantive synthesis around that grouping.

Use controlled tags only.

Public editors should not be able to introduce arbitrary new tags merely by typing a string. They should select an existing concept, propose an alias, or submit a new concept for taxonomy review.

Separate synonyms from concepts.

These:

labor movement
labour movement

are normally labels for one concept, not two tags.

SKOS's preferred and alternate-label model is specifically suited to that requirement.

Merge first; specialize only with evidence.

Before creating a new mechanism or outcome concept, editors should answer:

Is this truly different from an existing concept?
Can the difference be stated in one sentence?
Will users need to query them separately?
Is there literature distinguishing them?

If not, use an existing concept plus qualifiers.

Promotion lifecycle for tags

A concept can progress without changing identity:

Controlled Tag
      ↓
Concept with definition
      ↓
Concept with relationships
      ↓
Full encyclopedia page

Example:

BTR00083211 = selective repression

At first:

no page
used as controlled mechanism tag

Later:

/concept/selective-repression

The same BTR00083211 remains underneath both states.

This architecture makes “does this deserve a page?” an editorial decision rather than a database migration.

Entity lifecycle

Use explicit states:

draft
review
published
disputed
deprecated
merged
redirected

Never delete an identifier merely because two entities were later judged to be identical.

Instead:

BTR000381 → mergedInto → BTR000227

and preserve the old identifier as a redirect/tombstone record.

Stable identifiers are a core recommendation of Web data best practice because persistence enables references and citations to remain meaningful over time.

Minimum relationship set to launch

The site does not need hundreds of predicates before publication. The following set is enough to support nearly all relationships in the brief:

instanceOf
classifiedAs
broaderThan
narrowerThan
relatedConcept

occurredIn
operatesIn
partOfEvent
precededBy
followedBy

participatedIn
ledBy
memberOf
supportedBy
opposedBy

alignedWithIdeology

usesMechanism
analyzesMechanism
enabledByInstitution
constrainedByInstitution
targetsInstitution

hasOutcome
resultedIn
hasPossibleOutcome

governsInstitution
appliesInJurisdiction

documentedBy
isPrimarySourceFor
cites
heldBy

authoredBy
publishedBy
about

caseOf
involvesInstitution
hasAnswer
hasDeepAnalysis

contains
includesEvent

measures
derivedFromDataset

Several can later be specialized when actual editorial use proves the need.

Minimum controlled concept schemes

Start with these schemes:

event-type
ideology
mechanism
outcome
institutional-domain
legal-domain
historical-era
geographic-region
tactic
source-type
research-theme
assertion-status

Do not create a separate “tag system” for every page family.

Minimum page templates

At launch, BuiltToResist can cover the requested universe with roughly ten reusable templates:

Event
Movement
Person
Organization/Institution
Concept
Place/Polity
Work/Source
Analysis
Collection/Timeline/Archive
Dataset/Statistics

The 24 requested public categories become views or subtypes of those templates.

This is substantially more scalable than maintaining 24 independently designed content architectures.

The canonical model in compact form

The entire architecture can ultimately be summarized as:

ENTITY
│
├── HistoricalEvent
│   ├── Revolution
│   └── Uprising
│
├── Movement
├── Person
├── Organization
├── Institution
├── Place / Polity
│
├── Concept
│   ├── Ideology
│   ├── Mechanism
│   ├── Outcome
│   ├── LegalDoctrine
│   ├── PoliticalConcept
│   └── HistoricalEra
│
├── CreativeWork
│   ├── Book
│   ├── ResearchReport
│   ├── SourceDocument
│   └── Media
│
├── Analysis
│   ├── Case
│   ├── Scenario
│   └── Question
│
├── Collection
│   ├── Timeline
│   └── ArchiveCollection
│
└── Dataset
    ├── MetricSeries
    └── Observation

Every entity then connects through:

ENTITY
   ↓
STATEMENT
   ├── predicate
   ├── object
   ├── qualifiers
   └── citations

while every published article connects through:

PAGE
  ├── describes → ENTITY
  ├── sections
  ├── citations
  ├── breadcrumb
  ├── JSON-LD
  └── related-page query

and discovery is generated through:

CONCEPT SCHEMES
  +
RELATIONSHIPS
  +
FACETS
  +
SEARCH

rather than thousands of manually maintained cross-categories.

For a site intended to grow beyond 10,000 pages, the minimum viable architecture should therefore commit from the beginning to the following contracts:

LayerMinimum contract
IdentityEvery real entity receives one immutable opaque BTR identifier
PublishingEvery entity with substantive editorial treatment has one canonical page
OntologyA small set of core entity families, not one database type for every browse category
TaxonomySKOS-compatible controlled concept schemes with aliases, scope notes, broader/narrower relations
GraphGoverned subject-predicate-object statements
ContextRelationship qualifiers for time, place, role, uncertainty, hypothetical status
EvidenceClaim-level citations and provenance
URLsStable /id/ identity separated from mutable human-readable slugs
NavigationShallow type-oriented breadcrumbs plus multidimensional facets
Related pagesGraph-driven, typed, explainable recommendations
Historical modelingRevolutions and uprisings are event classifications under a shared event model
PeopleLeader and Scholar are person roles rather than duplicate person types
SourcesPrimary-source status is contextual and relational
InstitutionsInstitutions are distinct from organizations
StatisticsDataset/metric pages plus observations; no page-per-datapoint architecture
AnalysisFirst-class Cases, Scenarios and Questions with explicit hypothetical/analytic semantics
Structured dataJSON-LD on canonical pages; schema.org plus BuiltToResist vocabulary
Data interoperabilitySKOS for vocabularies, DCAT for datasets, PROV-compatible provenance, IIIF where archival media warrant it
AgentsAPI, type indexes, JSON-LD, sitemaps, bulk NDJSON/data releases and machine-readable vocabulary
GovernanceNo uncontrolled public tags; no compound categories; predicate registry; entity merge/redirect rules
EvolutionA concept can move from tag → structured concept → full page without changing its ID

The governing idea is simple: BuiltToResist should not be built as 10,000 articles with tags attached. It should be built as a durable graph of identifiable historical entities, concepts, claims and evidence, with 10,000+ human-readable pages rendered on top of it. SKOS supplies the vocabulary architecture; qualified statements supply the historical nuance; persistent identifiers make the knowledge durable; provenance makes claims auditable; DCAT and IIIF make research assets interoperable; and structured JSON-LD/API surfaces make the same encyclopedia intelligible to search engines, researchers, and AI agents. Those choices align closely with established Web recommendations for linked knowledge organization, persistent identifiers, machine-readable publication, APIs, standardized vocabularies, provenance, and reusable data.