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:
Key topics
- Civic / Privacy / Digital Rights
- Civic
- Privacy
- Digital Rights
- AI
- Agentic Web
- Semantic Systems
- Research Archive
- Strategy
Research provenance
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:
- An encyclopedia of stable pages written for people.
- A controlled knowledge graph describing entities and their relationships.
- 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 family | Principal subtypes or roles |
|---|---|
HistoricalEvent | Revolution, Uprising, Protest Wave, Strike Wave, Rebellion, Coup, Transition, Crackdown |
Movement | Movement, Campaign, Coalition, Network |
Person | Leader, Organizer, Scholar, Author, Official, Dissident |
Organization | Party, Union, NGO, Military Unit, Government Body, Media Organization |
Institution | Judiciary, Legislature, Monarchy, Security Apparatus, Electoral System, Emergency Regime |
Concept | Ideology, Mechanism, Outcome Type, Legal Doctrine, Political Concept, Historical Era, Tactic |
Place/Polity | Country, Historical State, Territory, Region, City |
CreativeWork | Book, Article, Research Report, Primary-Source Document, Film, Recording, Photograph |
Collection | Archive Collection, Bibliography, Timeline |
Analysis | Case, Scenario, Question, Deep Analysis |
Dataset | Statistical Dataset, Indicator Series, Corpus |
Observation | Statistical 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 concept | Canonical model | Standalone page policy | Principal relationships |
|---|---|---|---|
| Revolutions | HistoricalEvent + event type Revolution | Named revolutions get pages. “Revolutions” itself is a browse hub and concept page. | occurredIn, involvedMovement, hasParticipant, usedMechanism, resultedIn, documentedBy, partOf |
| Uprisings | HistoricalEvent + event type Uprising | Named uprisings get pages. The generic term may have a concept page. | Same event relationships |
| Movements | Movement | Named, identifiable movements get pages. | operatesIn, alignedWithIdeology, ledBy, usesMechanism, participatedIn, hasOutcome, opposedBy |
| Ideologies | Concept with concept kind Ideology | Recognized ideological traditions generally deserve pages; narrow adjectival descriptors may remain tags. | broader, narrower, related, influenced, adoptedBy, opposedBy |
| Leaders | Person + contextual role Leader | Person page, not separate “leader object.” | leads, memberOf, participatedIn, influenced, authored |
| Institutions | Institution | Reusable institutional forms and historically important named institutions get pages. | enablesMechanism, constrainsMechanism, governedByDoctrine, involvedInScenario, operatesInPolity |
| Mechanisms | Concept kind Mechanism | Reusable causal/operational mechanisms deserve pages; individual instances do not. | enabledByInstitution, constrainedByInstitution, observedInCase, contributesToOutcome |
| Outcomes | Concept kind OutcomeType; specific outcome recorded as statement | Major reusable outcome concepts get pages; each individual occurrence does not. | resultOf, possibleOutcomeOf, associatedWith |
| Countries | Polity/Place, including historical states | Every polity referenced materially should have a page. | containsPlace, predecessor, successor, siteOf, hasInstitution, hasLegalDoctrine |
| Historical eras | Concept kind HistoricalEra | Established or editorially useful periodizations get pages; arbitrary decades remain facets. | associatedEra, precedes, overlaps, appliesToRegion |
| Legal doctrines | Concept kind LegalDoctrine | Distinct doctrines with reusable explanatory value get pages. | appliesInJurisdiction, authorizesInstitution, constrainsInstitution, interpretedBy, derivedFromInstrument |
| Political concepts | Concept kind PoliticalConcept | Substantive concepts get pages. Minor descriptors remain controlled tags. | broader, narrower, related, contrastsWith, appliesTo |
| Books | CreativeWork subtype Book | Books cited or analyzed materially get bibliographic pages. | authoredBy, about, citedBy, influenced, publishedBy |
| Scholars | Person + role Scholar | Scholars materially represented in the research corpus get person pages. | authored, studies, associatedWithInstitution, citedBy |
| Primary sources | Relationship role, usually a CreativeWork, media item, or archival object | Individually catalogued primary materials can get source pages; “primary” is contextual, not immutable. | isPrimarySourceFor, createdBy, heldBy, documents, transcribedAs |
| Cases | Analysis subtype Case | Curated analytical cases get pages. | caseOf, analyzesEvent, analyzesMovement, analyzesMechanism, evaluatesOutcome, cites |
| Scenarios | Analysis subtype Scenario | Only intentionally authored hypothetical/forward-looking scenarios get pages. | assumes, involvesInstitution, usesMechanism, hasPossibleOutcome |
| Questions | Analysis subtype Question | Every substantive answerable research question can have one canonical page. | hasAnswer, hasDeepAnalysis, about, supportedBySource |
| Timelines | Collection / ordered editorial view | Curated timelines with explanatory value get pages; routine chronology should be generated from event data. | includesEvent, about, orderedByDate |
| Archives | Split between ArchiveOrganization and ArchiveCollection | Repository and collection pages should be distinct. | holdsCollection, containsSource, maintainedBy, about |
| Research reports | CreativeWork subtype ResearchReport | Cited or published reports get pages. | authoredBy, usesDataset, analyzes, cites, publishedBy |
| Organizations | Organization | Named bodies relevant to the subject get pages. | participatedIn, memberOf, ledBy, opposedBy, supportedBy, operatesIn |
| Media | CreativeWork/MediaObject | Important articles, films, recordings, photographs, maps or media collections can get pages; individual assets need not all receive prose pages. | createdBy, depicts, documents, publishedBy, isPrimarySourceFor |
| Statistics | Metric/Dataset + Observation rows | Page 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.
| Family | Canonical predicates | Examples |
|---|---|---|
| Classification | instanceOf, classifiedAs, broaderThan, narrowerThan, relatedConcept | Revolution → type of HistoricalEvent |
| Geography | occurredIn, operatesIn, appliesInJurisdiction, locatedIn | Movement → Country |
| Temporal | precededBy, followedBy, overlapsWith, partOfEvent | Uprising → Revolution |
| Participation | participatedIn, ledBy, opposedBy, supportedBy, memberOf | Movement → Leader |
| Ideas | alignedWithIdeology, influencedBy, opposesIdeology | Movement → Ideology |
| Mechanisms | usesMechanism, analyzesMechanism, enablesMechanism, constrainsMechanism | Case → Mechanism |
| Institutions | targetsInstitution, enabledByInstitution, governedByDoctrine, involvesInstitution | Mechanism → Institution |
| Outcomes | resultedIn, hasOutcome, contributesToOutcome, hasPossibleOutcome | Scenario → Outcome |
| Legal | governsInstitution, authorizesInstitution, constrainsInstitution, appliesInJurisdiction | Doctrine → Institution |
| Evidence | documentedBy, isPrimarySourceFor, cites, supportedBy, heldBy | Event → Primary Source |
| Works | authoredBy, publishedBy, about, usesDataset | Book → Scholar |
| Analysis | caseOf, hasAnswer, hasDeepAnalysis, assumesCondition | Question → Answer |
| Collection | contains, includesEvent, partOfCollection | Timeline → Event |
| Data | measures, observesEntity, forPlace, derivedFromDataset | Statistic → Country |
| Identity/mapping | sameAs, exactMatch, closeMatch | BTR 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 relationship | Canonical predicate | Important qualifiers |
|---|---|---|
| Movement → country | operatesIn | from, to, primaryArea, scope |
| Movement → ideology | alignedWithIdeology | from, to, attribution, degree, disputed |
| Movement → outcome | hasOutcome | degree, directness, status, source |
| Case → mechanism | analyzesMechanism | importance, finding, confidence |
| Mechanism → institution | enabledByInstitution, constrainedByInstitution, or targetsInstitution | Do not collapse causal direction into relatedTo |
| Institution → scenario | inverse of involvesInstitution | role, assumption |
| Scenario → outcome | hasPossibleOutcome | probability only if methodologically justified; conditions |
| Legal doctrine → institution | governsInstitution, optionally authorizesInstitution/constrainsInstitution | jurisdiction, from, to, instrument |
| Historical event → primary sources | documentedBy | sourceRole=primary, date, locator, reliabilityNote |
| Question → answer | hasAnswer | revision/version |
| Answer → deep analysis | hasDeepAnalysis | revision/version |
| Deep analysis → sources | cites / supportedBy | locator, 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
®ion=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.
Breadcrumb hierarchy
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?”
Human navigation and related-page logic
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.
Global navigation
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-page rules
“Related pages” should not be hand-maintained except for editorial overrides.
Use a reproducible ranking algorithm.
A good starting score:
| Signal | Suggested 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.
Recommended structured-data mapping
| BuiltToResist entity | Public structured-data mapping |
|---|---|
| Historical Event / Revolution / Uprising | schema:Event + internal btr: type |
| Person / Leader / Scholar | schema:Person |
| Organization | schema:Organization |
| Institution as abstract system | schema:Thing or DefinedTerm + internal type |
| Country / Place | schema:Place / applicable geographic subtype |
| Ideology | schema:DefinedTerm + btr:Ideology |
| Mechanism | schema:DefinedTerm + btr:Mechanism |
| Outcome type | schema:DefinedTerm + btr:Outcome |
| Political concept | schema:DefinedTerm |
| Legal doctrine | schema:DefinedTerm + internal legal type |
| Historical era | schema:DefinedTerm |
| Book | schema:Book |
| Research report | schema:CreativeWork / more specific work type where applicable |
| Primary-source document | appropriate CreativeWork subtype |
| Image | schema:ImageObject |
| Video | schema:VideoObject |
| Audio | schema:AudioObject |
| Dataset / statistical series | schema:Dataset + dcat:Dataset |
| Timeline | schema:CollectionPage / ordered ItemList |
| Question | schema:Question within its Web page representation |
| Answer | schema:Answer |
| Breadcrumbs | schema:BreadcrumbList |
| Browse/index page | schema: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.
| Table | Purpose | Essential fields |
|---|---|---|
entities | One record per identified thing or concept | id, entity_type, preferred_label, summary, status, temporal fields |
entity_types | Governed class registry | code, parent_type, external mappings |
labels | Preferred/alternate/historical names | entity_id, language, label, label_type |
pages | Published human pages | page_id, entity_id, canonical_path, title, body, status, revision |
predicates | Canonical relationship vocabulary | predicate_id, code, domain, range, inverse, qualifier rules |
statements | Entity-to-entity or entity-to-literal assertions | subject, predicate, object, status, rank, dates |
statement_qualifiers | Context of assertions | statement, qualifier predicate, value |
statement_sources | Claim-level provenance | statement, source entity, locator, note |
external_ids | Links to outside authority identifiers | entity, scheme, value, match type |
concept_schemes | Controlled facet vocabularies | scheme ID, title, description |
concept_assignments | Tags/classification | subject, concept, relation/relevance |
media_assets | Hosted or referenced media | entity, media type, URI, rights, creator, alt text |
observations | Statistical datapoints | metric, subject/place, period, value, unit, dataset |
revisions | Editorial history | object, 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:
| Check | Example |
|---|---|
| Domain validity | alignedWithIdeology subject must be a permitted actor type |
| Range validity | object must be Ideology |
| Temporal logic | valid_from cannot follow valid_to |
| Hypothetical isolation | scenario claims must carry hypothetical status |
| Source requirement | contested factual claims require citations |
| Duplicate detection | equivalent statement already exists |
| Self-relation check | disallow nonsensical self-links unless predicate permits |
| Deprecated target check | redirect statements toward canonical merged entity |
| Qualifier validity | only allowed qualifiers for predicate |
| Identity rule | sameAs 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.
Recommended minimum viable BuiltToResist specification
For a site intended to grow beyond 10,000 pages, the minimum viable architecture should therefore commit from the beginning to the following contracts:
| Layer | Minimum contract |
|---|---|
| Identity | Every real entity receives one immutable opaque BTR identifier |
| Publishing | Every entity with substantive editorial treatment has one canonical page |
| Ontology | A small set of core entity families, not one database type for every browse category |
| Taxonomy | SKOS-compatible controlled concept schemes with aliases, scope notes, broader/narrower relations |
| Graph | Governed subject-predicate-object statements |
| Context | Relationship qualifiers for time, place, role, uncertainty, hypothetical status |
| Evidence | Claim-level citations and provenance |
| URLs | Stable /id/ identity separated from mutable human-readable slugs |
| Navigation | Shallow type-oriented breadcrumbs plus multidimensional facets |
| Related pages | Graph-driven, typed, explainable recommendations |
| Historical modeling | Revolutions and uprisings are event classifications under a shared event model |
| People | Leader and Scholar are person roles rather than duplicate person types |
| Sources | Primary-source status is contextual and relational |
| Institutions | Institutions are distinct from organizations |
| Statistics | Dataset/metric pages plus observations; no page-per-datapoint architecture |
| Analysis | First-class Cases, Scenarios and Questions with explicit hypothetical/analytic semantics |
| Structured data | JSON-LD on canonical pages; schema.org plus BuiltToResist vocabulary |
| Data interoperability | SKOS for vocabularies, DCAT for datasets, PROV-compatible provenance, IIIF where archival media warrant it |
| Agents | API, type indexes, JSON-LD, sitemaps, bulk NDJSON/data releases and machine-readable vocabulary |
| Governance | No uncontrolled public tags; no compound categories; predicate registry; entity merge/redirect rules |
| Evolution | A 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.