Architecture Ontology — the proposed design-knowledge schema
STATUS: RATIFIED 2026-07-19 — phase 1 IMPLEMENTED & MERGED (MR !6, merge
340f3429). All eight rulings were decided 2026-07-19 (MR !4; ruling 8 amended in MR !5). Phase 1 landed the same day: canonical schema Tier J (19 labels → 70 total, 42 relationships → 59, 20 merge keys, 5 indexes); the unified project-qualifiedComponent(id = "{project}:{name}", migrated live on all 4 DBs); the convergedArchitectureWriter(19 upserts, ~30 link methods) behind a rewrittensync_architecture_to_neo4j.py; ADR immutability enforced BOTH layers (writer guard +body_shaconformance gate inkg_schema.py check); the WAFPillar/CloudService curated seed (5 + 30); and the SessionStart full-architecture-sync hook (--seed, backgrounded, never blocks). Verified 236/236 phase-affected tests observed, 0 skipped; live graph conforms. Phase 2 is also IMPLEMENTED & DEPLOYED (2026-07-19): the 20-ADR wiki corpus (this project'sdecisions.md) is graduated intoArchitectureDecisionnodes (allAccepted, immutability guard active, both source formats parsed) plusArtifact{adr|design-doc}nodes withDOCUMENTSedges, and the Memgraph semantic twin chunks that prose under theArchitectureChunklabel (own HNSW index, same codestral-embed-2505/1536 vector space as the code ingest, keyed by the Neo4j id): 20 ADR chunks + 11 design-doc chunks live, prune scoped to own-project/own-prefix. Retrieval proof: "storage access contention" and "fail-closed governance" queries return ADR-020 / ADR-009 at rank 1. The SessionStart hook now runs seed + ADR sync + twin (gated, loud-skip, never blocks). NOTE: the twin label isArchitectureChunk, not the draft'sSemanticChunkparenthetical — that label sits in the ingest pruner's stale-label kill list (rationale recorded in the draft §9.4 implementation note). Project doctrine held: ontology before graph import. The authoritative document lives in the repo atplans/architecture-ontology-draft.md.
TERMINOLOGY CORRECTION (2026-10-20, Mohamed: "we are not using neo4j … make this clear"): the operational knowledge graph is orchgraph — the Memgraph 3.11 fork (HA cluster, Bolt protocol). Neo4j is NOT used anywhere; the Neo4j containers were destroyed 2026-07-27. Every "Neo4j" in this page below is historical naming from before that retirement (the page was ratified 2026-07-19), or is Bolt-client naming: the
neo4j://URI scheme and the Pythonneo4jdriver package speak the Bolt wire protocol to orchgraph/Memgraph — the library name is not the product. The canonical schema,ArchitectureWriter, and theComponent/DEPENDS_ONontology all run on orchgraph (orchkgdatabase); the semantic twin runs on the same cluster'smemgraphdatabase. See the repo'sAGENTS.md§ Component Boundaries anddocs/supervisor-workflow.md§3.
Why this exists
The operational Neo4j KG already reasons over code (functions, classes,
calls, imports), specs (requirements, scenarios, @traces), tests,
and runtime events (sessions, CXP packets, tool calls). What it cannot
represent is the design layer above the code: why a component exists, which
requirement forced a technology choice, what an ADR decided and what it
rejected, what a system is expected to cost, and what its SLOs promise.
The raw material came from the system-design Claude Code skill
(~/workspace/system-design-plugin): its 6-phase design workflow and all 26
reference documents were mined concept-by-concept, and each phase became a
family of node types — the taxonomy was derived from the material, not
invented:
The core ontology
31 node types are touched: 21 new, 4 existing labels extended, 6 reused
as-is. Five are global reference data (WAFPillar, Region,
CloudService, Pattern — plus the fixed pillar set); everything else is
project-scoped, with canonical identity {project}:{natural-key} per the
multi-project invariant. 44 relationships connect them:
Reading the diagram top to bottom tells the design story: a project owns an
architecture made of components; requirements (with BDD scenarios and quality
attributes) justify what the components must do; every technology choice is
gated by the requirement that forces it (FORCED_BY — the skill's "name
the requirement that forces it" rule made structural); ADRs record the
one-way-door decisions with their trade-offs and rejected alternatives;
capacity models inform cost models down to metered line items; SLOs, alerts,
risks, and failure modes carry the operational review; deployments place
components into environments and regions; and OpenSpec changes + design docs
tie the whole thing back to deliverables.
Node families at a glance
| Family (phase) | Node types | New / reuse |
|---|---|---|
| System structure (P0/P3) | Architecture, Component, ApiContract, DataEntity |
2 extended, 2 new |
| Requirements (P1) | Requirement, RequirementItem, Scenario, UserStory, QualityAttribute, Constraint |
4 reused, 2 new |
| Capacity & cost (P2) | CapacityModel, CostModel, CostLineItem |
all new |
| Decisions (P4) | ArchitectureDecision, TradeOff, TechnologyChoice, Pattern |
3 new, 1 extended |
| Operations review (P5) | WAFPillar, Risk, FailureMode, ServiceLevelObjective, Alert |
all new |
| Placement (P5/P6) | Environment, Region, Deployment |
all new |
| Deliverables (P6) | Change, Artifact |
1 extended, 1 reused |
| Reference data (global) | WAFPillar (5 fixed), Region, CloudService, Pattern |
seeded, not project-scoped |
Design principles inherited from the canonical schema
- One canonical MERGE key per label — every label declares exactly one
identity key and one uniqueness constraint, mirroring
canonical_schema.py'sCANONICAL_MERGE_KEYS. - Project-qualified identity by default — the KG holds 100+ projects;
any natural id that recurs across projects gets the
{project}:prefix (the Package/File/Directory precedent). - ADR immutability — an Accepted ADR's body never changes; evolution
happens via
SUPERSEDESedges to a new ADR. - Decisions are justified by requirements —
JUSTIFIED_BY/FORCED_BYedges are mandatory, not decorative; an unjustified choice is a schema violation the conformance gate can flag. - This is Neo4j-only — semantic retrieval over ADR/design-doc prose would live in the Memgraph semantic graph as chunks keyed back to the Neo4j node id (ruling 4 below decides whether that twin gets built).
What it supersedes
scripts/sync_architecture_to_neo4j.py — the current hand-authored
architecture writer — keys Architecture on bare global name and writes
design invariants under the Rule label, colliding with Tier-A Prolog rules.
This ontology project-qualifies the former and moves the latter to
Constraint{kind:"invariant"}, reserving Rule for Prolog. The writer is
superseded, not patched, once the schema is ratified.
The eight rulings (decided 2026-07-19)
- ADR immutability → BOTH layers. Writer-side guard (a
SETon an Accepted ADR's body raises) plus abody_shahash stamped at accept time and checked by the conformance gate — prevent and detect, mirroringcanonical_schema.check(). Component→ UNIFIED and project-qualified. One label,id = "{project}:{name}"; the design-time Component IS the runtime-ownership Component. The 5 live bare-name nodes migrate via amigrate_neo4j_canonical.pyextension.Rulecollision → folded. Architecture rules becomeConstraint{kind:"invariant"};Ruleis reserved for Prolog.- Semantic twin → YES, phase 2. ADR/DesignDoc prose is chunked into the
Memgraph semantic graph keyed by the Neo4j
ArchitectureDecision.id— after phase-1 Neo4j ingestion lands, not blocking it. ArchitectureDecision≠Decision. Two labels stay: different lifecycles (immutable-supersede vs mutable runtime), writers, and queries.CloudService→ lazy + curated seed. Only the ~30 services the reference corpus names, taggedneutral_kind; full-catalog ingestion rejected under the ontology's ownFORCED_BYdoctrine.Changekey → confirmed. OpenSpec ownsLABEL_CHANGE;id = "{project}:{change_id}"closes the keyless-label canon gap.- Converged writer → BOTH, phased a→b. Rewrite
sync_architecture_to_neo4j.pyonto this ontology first (superseded, not patched), then extend the pipeline/session KG writers. Triggers: on-demand/system-designruns write immediately, and session start initiates a full architecture sync (amended 2026-07-19): the whole design corpus is idempotently MERGEd on boot — cheap at this layer's scale, unlike the code graph which stays incremental (SPEC-023) — run backgrounded so session start never blocks on Neo4j, with ruling 1's immutability guard enforced inside it.
Related
- Repo draft (authoritative, full property/constraint tables):
plans/architecture-ontology-draft.md - Skill-vs-volk integration audit:
reports/architect-skill-vs-volk-integration.md— recommends ratifying this ontology as the first integration step for the system-design skill (its ADRs and design docs land here). - knowledge_graph package —
where the canonical schema (
canonical_schema.py, SPEC-106 FR-001) lives. - Decisions — the dated record this ontology's ADR discipline will formalize.