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-qualified Component (id = "{project}:{name}", migrated live on all 4 DBs); the converged ArchitectureWriter (19 upserts, ~30 link methods) behind a rewritten sync_architecture_to_neo4j.py; ADR immutability enforced BOTH layers (writer guard + body_sha conformance gate in kg_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's decisions.md) is graduated into ArchitectureDecision nodes (all Accepted, immutability guard active, both source formats parsed) plus Artifact{adr|design-doc} nodes with DOCUMENTS edges, and the Memgraph semantic twin chunks that prose under the ArchitectureChunk label (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 is ArchitectureChunk, not the draft's SemanticChunk parenthetical — 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 at plans/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 Python neo4j driver package speak the Bolt wire protocol to orchgraph/Memgraph — the library name is not the product. The canonical schema, ArchitectureWriter, and the Component/DEPENDS_ON ontology all run on orchgraph (orchkg database); the semantic twin runs on the same cluster's memgraph database. See the repo's AGENTS.md § Component Boundaries and docs/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:

Diagram projects-orchestrata-ultimate-architecture-ontology-1

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:

Diagram projects-orchestrata-ultimate-architecture-ontology-2

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

  1. One canonical MERGE key per label — every label declares exactly one identity key and one uniqueness constraint, mirroring canonical_schema.py's CANONICAL_MERGE_KEYS.
  2. 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).
  3. ADR immutability — an Accepted ADR's body never changes; evolution happens via SUPERSEDES edges to a new ADR.
  4. Decisions are justified by requirements — JUSTIFIED_BY/FORCED_BY edges are mandatory, not decorative; an unjustified choice is a schema violation the conformance gate can flag.
  5. 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)

  1. ADR immutability → BOTH layers. Writer-side guard (a SET on an Accepted ADR's body raises) plus a body_sha hash stamped at accept time and checked by the conformance gate — prevent and detect, mirroring canonical_schema.check().
  2. 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 a migrate_neo4j_canonical.py extension.
  3. Rule collision → folded. Architecture rules become Constraint{kind:"invariant"}; Rule is reserved for Prolog.
  4. 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.
  5. ArchitectureDecision ≠ Decision. Two labels stay: different lifecycles (immutable-supersede vs mutable runtime), writers, and queries.
  6. CloudService → lazy + curated seed. Only the ~30 services the reference corpus names, tagged neutral_kind; full-catalog ingestion rejected under the ontology's own FORCED_BY doctrine.
  7. Change key → confirmed. OpenSpec owns LABEL_CHANGE; id = "{project}:{change_id}" closes the keyless-label canon gap.
  8. Converged writer → BOTH, phased a→b. Rewrite sync_architecture_to_neo4j.py onto this ontology first (superseded, not patched), then extend the pipeline/session KG writers. Triggers: on-demand /system-design runs 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.