|
| 1 | +# DDD: Semantic Pipeline — Bounded Contexts |
| 2 | + |
| 3 | +**Date**: 2026-03-25 |
| 4 | + |
| 5 | +## Domain Model |
| 6 | + |
| 7 | +``` |
| 8 | +Markdown Source (Aggregate Root) |
| 9 | + ├── OntologyBlock (Value Object) |
| 10 | + │ ├── is_subclass_of: Vec<String> → "hierarchical" edge, weight 2.5 |
| 11 | + │ ├── has_part: Vec<String> → "structural" edge, weight 1.5 |
| 12 | + │ ├── is_part_of: Vec<String> → "structural" edge, weight 1.5 |
| 13 | + │ ├── requires: Vec<String> → "dependency" edge, weight 1.5 |
| 14 | + │ ├── depends_on: Vec<String> → "dependency" edge, weight 1.5 |
| 15 | + │ ├── enables: Vec<String> → "dependency" edge, weight 1.5 |
| 16 | + │ ├── relates_to: Vec<String> → "associative" edge, weight 1.0 |
| 17 | + │ ├── bridges_to: Vec<String> → "bridge" edge, weight 1.0 |
| 18 | + │ └── bridges_from: Vec<String> → "bridge" edge, weight 1.0 |
| 19 | + ├── Wikilinks (Value Object) → "explicit_link" edge, weight 1.0 |
| 20 | + └── Namespace Prefix (derived) → "namespace" edge, weight 0.3 |
| 21 | +
|
| 22 | +Neo4j (Repository) |
| 23 | + ├── :GraphNode — display nodes |
| 24 | + ├── :OwlClass — ontology concepts |
| 25 | + ├── :EDGE — wikilink + relationship edges (with relation_type, owl_property_iri) |
| 26 | + ├── :SUBCLASS_OF — hierarchy edges |
| 27 | + ├── :RELATES — non-hierarchical ontology edges (NEW) |
| 28 | + └── :OwlAxiom — reasoner output (materialised → SUBCLASS_OF) |
| 29 | +
|
| 30 | +GPU Physics (Domain Service) |
| 31 | + ├── ForceComputeActor — Barnes-Hut forces + edge springs |
| 32 | + │ └── CSR graph: (col_indices, edge_weights, edge_types) |
| 33 | + ├── SemanticForcesActor — type clustering + DAG layout |
| 34 | + │ └── Reads: node type_id (domain), edge_type for spring differentiation |
| 35 | + ├── OntologyConstraintActor — axiom-derived constraints |
| 36 | + │ └── Reads: DisjointWith → separation, SubClassOf → clustering |
| 37 | + ├── ClusteringActor — k-means / louvain |
| 38 | + │ └── Writes: cluster_id per node → app_state.node_analytics |
| 39 | + └── AnomalyDetectionActor — LOF / z-score |
| 40 | + └── Writes: anomaly_score per node → app_state.node_analytics |
| 41 | +
|
| 42 | +Client Rendering (Presentation) |
| 43 | + ├── Binary Protocol V3: [pos, vel, cluster_id, anomaly_score, community_id] |
| 44 | + ├── Node colour: domain palette (AI=#4FC3F7, BC=#81C784, MV=#CE93D8, ...) |
| 45 | + ├── Edge gradient: source_domain_colour → target_domain_colour |
| 46 | + ├── Edge width: relationship weight (2.5 hierarchical → 1.0 associative) |
| 47 | + └── ClusterHulls: convex hull per domain/cluster with domain colour |
| 48 | +``` |
| 49 | + |
| 50 | +## Bounded Contexts |
| 51 | + |
| 52 | +### 1. Ingestion Context |
| 53 | +**Responsibility**: Markdown → Neo4j |
| 54 | +**Files**: github_sync_service.rs, ontology_parser.rs, knowledge_graph_parser.rs, neo4j_ontology_repository.rs, neo4j_adapter.rs |
| 55 | +**Invariant**: Every relationship in an OntologyBlock becomes a Neo4j edge with type and weight |
| 56 | + |
| 57 | +### 2. Physics Context |
| 58 | +**Responsibility**: Neo4j → GPU forces → settled positions |
| 59 | +**Files**: graph_state_actor.rs, force_compute_actor.rs, semantic_forces_actor.rs, ontology_constraint_actor.rs |
| 60 | +**Invariant**: Edge type influences spring strength. Domain membership influences clustering force. |
| 61 | + |
| 62 | +### 3. Analytics Context |
| 63 | +**Responsibility**: GPU clustering/anomaly → client metadata |
| 64 | +**Files**: clustering_actor.rs, anomaly_detection_actor.rs, app_state.rs, binary_protocol.rs |
| 65 | +**Invariant**: Every node has a cluster_id and anomaly_score delivered to the client |
| 66 | + |
| 67 | +### 4. Rendering Context |
| 68 | +**Responsibility**: Positions + metadata → visual output |
| 69 | +**Files**: GraphManager.tsx, ClusterHulls.tsx, GlassEdges, binaryProtocol.ts, graph.worker.ts |
| 70 | +**Invariant**: Edges are coloured by domain gradient. Nodes are coloured by cluster. Hulls wrap clusters. |
| 71 | + |
| 72 | +## Anti-Corruption Layer |
| 73 | + |
| 74 | +None. Single codebase, single data flow. The markdown parser IS the domain model. Everything downstream is a projection of the parsed OntologyBlock. |
| 75 | + |
| 76 | +## Edge Type Enum (shared across all contexts) |
| 77 | + |
| 78 | +```rust |
| 79 | +#[repr(u8)] |
| 80 | +pub enum EdgeType { |
| 81 | + ExplicitLink = 0, // [[wikilink]] |
| 82 | + Hierarchical = 1, // is-subclass-of (rdfs:subClassOf) |
| 83 | + Structural = 2, // has-part, is-part-of |
| 84 | + Dependency = 3, // requires, depends-on, enables |
| 85 | + Associative = 4, // relates-to |
| 86 | + Bridge = 5, // bridges-to, bridges-from |
| 87 | + Namespace = 6, // shared prefix grouping |
| 88 | + Inferred = 7, // whelk reasoner output |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +Weight table: |
| 93 | +| EdgeType | Default Weight | Spring Multiplier | Colour Influence | |
| 94 | +|----------|---------------|-------------------|-----------------| |
| 95 | +| Hierarchical | 2.5 | 2.0x | Strong domain pull | |
| 96 | +| Structural | 1.5 | 1.5x | Medium clustering | |
| 97 | +| Dependency | 1.5 | 1.5x | Medium clustering | |
| 98 | +| Associative | 1.0 | 1.0x | Gentle grouping | |
| 99 | +| Bridge | 1.0 | 0.5x | Cross-domain (weaker) | |
| 100 | +| ExplicitLink | 1.0 | 1.0x | Standard spring | |
| 101 | +| Namespace | 0.3 | 0.3x | Weak grouping | |
| 102 | +| Inferred | 0.8 | 0.8x | Reasoner-derived | |
0 commit comments