Back to .md Directory

hl_overview

High level overview of the codebase

May 2, 2026
0 downloads
0 views
ai llm mcp
View source

hl_overview

High level overview of the codebase

Repository Analysis: ontology-circl

0. Repository Name

[[ontology-circl]]


1. Project Purpose

This project is an Ontology Service Platform for the CIRCL ecosystem - a domain-driven logistics/operations management system. It serves as a centralized semantic knowledge base that defines:

  • Domain entities (assets, vehicles, drivers, orders, trips, depots, customers, etc.)
  • State machines for entity lifecycle management
  • Event definitions and mappings for event-driven architecture
  • Commands with validation rules for operations (dispatcher, driver, operations)
  • Business vocabulary and domain terminology
  • Relationships between systems (OMS - Order Management, DMS - Delivery Management, IoT)
  • Multi-tenant governance with Role-Based Access Control (RBAC)

The platform appears to serve propane/fuel delivery logistics operations (evidenced by market-specific configurations like ke/propane and vertical-specific entities).


2. Architecture Pattern

Primary Patterns:

  • Event-Driven Architecture (EDA) - Core event registry, NATS messaging integration
  • Domain-Driven Design (DDD) - Bounded contexts (OMS, DMS, IoT), entities, aggregates
  • CQRS (Command Query Responsibility Segregation) - Separate commands and projections
  • Multi-Tenant Architecture - Tenant isolation with RLS policies
  • Model Context Protocol (MCP) - AI/LLM integration for ontology querying

3. Technology Stack

Languages

  • TypeScript (primary - backend and frontend)
  • SQL (PostgreSQL with Supabase)
  • YAML (ontology definitions)

Backend Framework

  • Fastify - HTTP server framework
  • Node.js runtime

Frontend

  • React 18+ with TypeScript
  • Vite - Build tool
  • Tailwind CSS - Styling
  • React Router - Routing

Database

  • PostgreSQL (via Supabase)
  • Row-Level Security (RLS) for multi-tenancy

Messaging/Events

  • NATS - Event streaming and messaging

Key Dependencies (from package.json patterns)

CategoryLibraries
Validationzod, json-logic-js
YAML Processingyaml, js-yaml
Database@supabase/supabase-js, postgres
Messagingnats
MCP Integration@modelcontextprotocol/*
Testingvitest
Lintingeslint
Buildtsup, typescript

Infrastructure

  • Docker / Docker Compose
  • Nixpacks (Railway deployment)
  • GitHub Actions (CI/CD)

4. Initial Structure Impression

ontology-circl/
├── src/           → Backend API server, core services
├── ui/            → React frontend application
├── packages/      → Shared libraries (ontology types, MCP client)
├── ontology/      → YAML-based ontology definitions (source of truth)
├── database/      → SQL migration scripts
├── docs/          → Extensive documentation, ADRs, plans
├── supabase/      → Supabase-specific configurations
├── scripts/       → Utility scripts
└── compat/        → Consumer compatibility configurations

Main Components:

  1. Backend Service (src/) - Fastify API server
  2. Frontend UI (ui/) - Ontology Explorer interface
  3. Ontology Definitions (ontology/) - YAML schema definitions
  4. Shared Packages (packages/) - TypeScript type generation, MCP client
  5. Database Layer (database/, supabase/) - PostgreSQL schemas

5. Configuration/Package Files

FilePurpose
package.jsonRoot monorepo dependencies
ui/package.jsonFrontend dependencies
packages/ontology/package.jsonOntology package dependencies
packages/mcp-client/package.jsonMCP client dependencies
tsconfig.jsonRoot TypeScript config
tsconfig.build.jsonProduction build config
ui/tsconfig.jsonFrontend TypeScript config
vitest.config.tsTest configuration
eslint.config.jsLinting rules
docker-compose.ymlLocal development containers
DockerfileProduction container build
nixpacks.tomlRailway deployment config
.env.exampleEnvironment variables template
supabase/config.tomlSupabase local config
ui/vite.config.tsFrontend build config
ui/tailwind.config.tsTailwind CSS config

6. Directory Structure Analysis

/src - Backend Core

src/
├── api/              → Fastify routes & middleware
│   ├── routes/       → 21 route modules (entities, events, commands, etc.)
│   └── middleware/   → Auth, error handling, tenant context
├── commands/         → Command execution engine (CQRS write side)
├── validation/       → JSON Logic rule engine, state machine validation
├── events/           → Event registry and semantics
├── relationships/    → Cross-entity relationship management
├── vocabulary/       → Domain terminology registry
├── errors/           → Structured error handling
├── versioning/       → Schema version management, migrations
├── projections/      → Read-model caching (CQRS read side)
├── sync/             → NATS event synchronization
├── mcp/              → Model Context Protocol server & loaders
├── governance/       → Proposal/approval workflows
├── layering/         → Ontology composition engine
├── config/           → Database & NATS configuration
├── db/repositories/  → Data access layer
└── __tests__/        → Comprehensive test suite

/ui - Frontend Application

ui/src/
├── features/         → Feature-based modules
│   ├── entities/     → Entity browser
│   ├── events/       → Event explorer
│   ├── commands/     → Command documentation
│   ├── state-machines/ → State machine visualizer
│   ├── analysis/     → Ontology analysis tools
│   ├── governance/   → Approval workflows
│   ├── versioning/   → Version management
│   └── ...
├── components/       → Shared UI components
├── layouts/          → Page layouts
├── hooks/            → Custom React hooks
├── api/              → API client
└── design-system/    → Design tokens

/ontology - Domain Definitions (YAML)

ontology/
├── core/             → Base definitions
│   ├── entities/     → 23 entity schemas
│   ├── state-machines/ → 46 state machine definitions
│   ├── workflows/    → 16 workflow definitions
│   ├── validation-rules/ → Business rules
│   ├── event-mappings/ → Event-to-entity mappings
│   └── vocabulary/   → Domain terms
├── composed/         → Merged/resolved ontology output
├── commands/         → Command schemas
├── errors/           → Error code definitions
├── projections/      → Read model schemas
├── relationships/    → Entity relationships (OMS, DMS, IoT)
├── bundles/          → Role-based ontology bundles
├── meta/             → Cross-cutting (roles, permissions, SLAs)
├── verticals/propane/ → Industry-specific extensions
├── markets/ke/       → Market-specific (Kenya/propane)
├── customers/mgas/   → Customer-specific extensions
└── legacy/           → Pre-migration definitions

/database/migrations - Schema Evolution

14 migrations covering:

  • Initial schema, semantic tables
  • RLS policies, tenant security
  • Commands, validation rules
  • Projections, versioning
  • Relationships, errors, vocabulary

7. High-Level Architecture

Architectural Patterns Evidence

1. Event-Driven Architecture

  • /ontology/event-registry.yaml - Centralized event catalog
  • /src/events/ - Event semantics management
  • /src/sync/nats-connection.ts - NATS integration
  • Event mappings in /ontology/core/event-mappings/

2. CQRS Pattern

  • Commands: /src/commands/, /ontology/commands/
  • Projections (Read Models): /src/projections/, /ontology/projections/
  • Separate command execution from query handling

3. Domain-Driven Design

  • Bounded contexts: OMS, DMS, IoT (seen in /ontology/relationships/)
  • Entities with state machines
  • Ubiquitous language via /ontology/core/vocabulary/

4. Multi-Tenant Architecture

  • RLS migrations (003_enable_rls.sql, 012_tenant_security_hardening.sql)
  • Tenant middleware (src/api/middleware/)
  • Tenant-specific governance (.ontology-governance/tenants/)

5. Layered Ontology Composition

# From ontology/layer-manifest.yaml
Layers: base → core → verticals → markets → customers
  • /src/layering/layer-composer.ts - Composition engine
  • Supports inheritance and override patterns

6. Model Context Protocol (MCP)

  • /src/mcp/ontology-mcp-server.ts - MCP server for AI tooling
  • Loaders for entities, events, state machines, commands
  • Enables LLM-assisted ontology queries

System Integration Diagram

┌─────────────────┐     ┌──────────────────┐
│   UI (React)    │────▶│  Fastify API     │
└─────────────────┘     └────────┬─────────┘
                                 │
         ┌───────────────────────┼───────────────────────┐
         ▼                       ▼                       ▼
┌─────────────────┐     ┌──────────────────┐    ┌──────────────┐
│ PostgreSQL/     │     │      NATS        │    │  MCP Server  │
│ Supabase        │     │  (Events)        │    │  (AI Tools)  │
└─────────────────┘     └──────────────────┘    └──────────────┘
         ▲
         │
┌─────────────────┐
│ Ontology YAML   │
│ (Source of      │
│  Truth)         │
└─────────────────┘

8. Build, Execution and Test

Build Commands

# Install dependencies
npm install

# Build TypeScript
npm run build          # Uses tsconfig.build.json

# Build UI
cd ui && npm run build # Vite production build

Run Commands

# Development mode
npm run dev            # Likely starts Fastify server

# Start with script
./scripts/start.sh     # Shell startup script

# Docker
docker-compose up      # Full stack with dependencies

Test Commands

# Run tests
npm test               # Vitest test runner

# Test coverage
npm run generate:coverage

Key Scripts (from /src/scripts/)

ScriptPurpose
validate-ontology.tsValidate YAML ontology definitions
compose-ontology.tsMerge layered ontology files
compile-bundle.tsCreate role-specific bundles
run-migrations.tsExecute database migrations
check-ontology-drift.tsDetect schema divergence
generate-release-migration-notes.tsChangelog generation
check-consumer-compatibility.tsDownstream compatibility check

Entry Points

  1. API Server: src/index.tssrc/api/server.ts
  2. MCP Server: src/mcp/ontology-mcp-server.ts
  3. UI: ui/src/main.tsx

CI/CD Pipelines (.github/workflows/)

  • ontology.yml - Main ontology validation/build
  • ontology-drift-monitor.yml - Drift detection
  • create-consumer-update-prs.yml - Downstream update automation

Summary

This is a sophisticated Ontology-as-a-Service platform designed to centralize domain knowledge for a logistics/delivery operations ecosystem. It combines:

  • Schema-first design with YAML ontology definitions
  • Multi-tenant governance with RLS and RBAC
  • Event-driven integration via NATS
  • AI-ready architecture via MCP server
  • Layered composition supporting base → vertical → market → customer customization

The project demonstrates mature software engineering practices including comprehensive testing, documentation, ADRs, and CI/CD automation.

module_deep_dive

Deep dive into modules

Detailed Component Breakdown - Ontology-CIRCL Repository

1. /src/api/ - API Layer

Core Responsibility

The primary HTTP API server layer that exposes the ontology service's capabilities through RESTful endpoints. It handles incoming requests, applies middleware, and routes to appropriate handlers.

Key Components

File/DirectoryRole
server.tsMain Fastify server configuration, plugin registration, and startup logic
middleware/ (4 files)Request processing middleware (authentication, tenant context, error handling, request validation)
routes/ (21 files)Route handlers for various API endpoints (entities, events, commands, validation, relationships, vocabulary, etc.)

Dependencies & Interactions

Internal Dependencies:

  • @src/commands/ - For command execution endpoints
  • @src/validation/ - For validation rule processing
  • @src/events/ - For event registry access
  • @src/relationships/ - For relationship queries
  • @src/vocabulary/ - For vocabulary/terminology APIs
  • @src/errors/ - For standardized error responses
  • @src/config/ - For database and service configuration
  • @src/versioning/ - For version-aware API responses

External Interactions:

  • Exposes REST API consumed by UI (/ui) and external services
  • Interacts with PostgreSQL/Supabase via repositories

2. /src/commands/ - Command Execution System

Core Responsibility

Implements the Command pattern for executing domain operations with validation, authorization, and audit trails. Handles command registration, approval workflows, and execution orchestration.

Key Components

FileRole
index.tsModule exports and public API
types.tsTypeScript interfaces for commands, execution context, results
command-registry.tsRegistry for available commands with metadata and handlers
command-executor.tsExecutes commands with pre/post hooks, validation, and error handling
approval-service.tsManages multi-step approval workflows for sensitive commands

Dependencies & Interactions

Internal Dependencies:

  • @src/validation/ - Pre-execution validation of command payloads
  • @src/errors/ - Standardized error handling
  • @src/events/ - Emits events after successful command execution
  • @src/db/repositories/ - Persistence of command execution records
  • /ontology/commands/ - YAML command definitions

External Interactions:

  • Commands may trigger NATS events via @src/sync/

3. /src/validation/ - Validation Engine

Core Responsibility

Provides comprehensive validation capabilities including JSON Logic rule evaluation, state machine transition validation, and schema validation for ontology artifacts.

Key Components

FileRole
index.tsModule exports
validation-engine.tsCore validation orchestrator combining multiple validation strategies
jsonlogic-evaluator.tsEvaluates JSON Logic expressions for business rules
state-machine-validator.tsValidates state transitions against defined state machines
state-machine-loader.tsLoads state machine definitions from YAML files
rule-cache.tsIn-memory caching of compiled validation rules
rule-seeder.tsSeeds validation rules from YAML to database
rule-tester.tsTesting utilities for validation rules
error-formatter.tsFormats validation errors for API responses

Dependencies & Interactions

Internal Dependencies:

  • /ontology/core/validation-rules/ - YAML validation rule definitions
  • /ontology/core/state-machines/ - State machine definitions
  • @src/config/database.ts - Database connection for cached rules
  • @src/layering/ - Layer-aware rule resolution
  • @src/errors/ - Error type definitions

External Interactions:

  • Uses json-logic-js library for rule evaluation
  • May use ajv for JSON Schema validation

4. /src/events/ - Event Semantics System

Core Responsibility

Manages event definitions, semantic metadata, and the event registry. Provides type information, ownership, and processing hints for domain events.

Key Components

FileRole
index.tsModule exports
types.tsEvent type definitions, semantic metadata interfaces
event-registry-loader.tsLoads events from /ontology/event-registry.yaml
event-semantics-registry.tsIn-memory registry of event definitions with query capabilities
event-semantics-seeder.tsSeeds event definitions to database

Dependencies & Interactions

Internal Dependencies:

  • /ontology/event-registry.yaml - Master event definitions
  • /ontology/core/event-mappings/ - Entity-to-event mappings
  • @src/layering/ - Layer-aware event resolution
  • @src/config/database.ts - Database persistence

External Interactions:

  • Event definitions consumed by external services via API
  • Supports NATS event routing decisions

5. /src/relationships/ - Entity Relationships

Core Responsibility

Defines and validates relationships between entities across the domain model. Manages cardinality, constraints, and cross-system references.

Key Components

FileRole
index.tsModule exports
types.tsRelationship type definitions (one-to-many, many-to-many, etc.)
relationship-registry.tsRegistry of entity relationships with query methods
relationship-seeder.tsSeeds relationship definitions to database
relationship-validator.tsValidates relationship constraints at runtime

Dependencies & Interactions

Internal Dependencies:

  • /ontology/relationships/ - YAML relationship definitions (OMS, DMS, IoT, cross-system)
  • @src/db/repositories/relationship.repository.ts - Database operations
  • @src/layering/ - Layer composition for relationships

External Interactions:

  • Exposes relationship graph via API for UI visualization

6. /src/vocabulary/ - Domain Vocabulary

Core Responsibility

Manages domain-specific terminology, canonical terms, and synonyms. Provides translation between business language and technical identifiers.

Key Components

FileRole
index.tsModule exports
types.tsVocabulary entry types, synonym mappings
vocabulary-registry.tsIn-memory vocabulary registry with lookup methods
vocabulary-seeder.tsSeeds vocabulary from YAML to database

Dependencies & Interactions

Internal Dependencies:

  • /ontology/core/vocabulary/ - YAML vocabulary definitions
  • @src/config/database.ts - Persistence layer
  • @src/layering/ - Layer-aware vocabulary resolution

External Interactions:

  • Used by @src/analysis/nl-translator.ts for natural language processing

7. /src/errors/ - Error Handling System

Core Responsibility

Provides standardized error definitions, error codes, and error handling middleware. Ensures consistent error responses across the application.

Key Components

FileRole
index.tsModule exports
types.tsError type definitions, error codes enum
error-registry.tsRegistry of error definitions with metadata
error-seeder.tsSeeds error definitions from YAML
error-handler.tsFastify error handler plugin

Dependencies & Interactions

Internal Dependencies:

  • /ontology/errors/error-definitions.yaml - Error catalog
  • @src/config/database.ts - Persistence
  • @src/api/middleware/ - Integrated as middleware

External Interactions:

  • Error codes referenced by external consumer services

8. /src/sync/ - Event Synchronization

Core Responsibility

Handles real-time synchronization with external systems via NATS messaging. Processes incoming events and publishes ontology changes.

Key Components

FileRole
nats-connection.tsNATS client connection management
event-processor.tsProcesses incoming NATS events
ontology-sync.service.tsOrchestrates ontology synchronization across services

Dependencies & Interactions

Internal Dependencies:

  • @src/config/nats.ts - NATS configuration
  • @src/events/ - Event type information
  • @src/versioning/ - Version-aware sync

External Interactions:

  • NATS JetStream - External message broker
  • Publishes/subscribes to domain events across microservices

9. /src/versioning/ - Version Management

Core Responsibility

Manages ontology versions, compatibility layers, and migration between versions. Supports multi-version deployments and consumer compatibility.

Key Components

FileRole
index.tsModule exports
types.tsVersion metadata, compatibility matrix types
version-manager.tsCore version tracking and resolution
migration-service.tsHandles ontology migrations between versions
compatibility-layer.tsProvides backward compatibility transformations

Dependencies & Interactions

Internal Dependencies:

  • @src/config/database.ts - Version metadata persistence
  • /database/migrations/006_projections_versioning.sql - Version schema
  • @src/layering/ - Layer versioning

External Interactions:

  • /compat/ directory for consumer compatibility manifests
  • CI/CD workflows check version compatibility

10. /src/layering/ - Layer Composition

Core Responsibility

Implements the three-tier ontology layering system (core → vertical → customer). Composes and merges definitions across layers with proper precedence.

Key Components

FileRole
index.tsModule exports
types.tsLayer definitions, composition context types
layer-composer.tsMerges ontology artifacts across layers

Dependencies & Interactions

Internal Dependencies:

  • /ontology/core/ - Core layer definitions
  • /ontology/verticals/ - Vertical-specific extensions
  • /ontology/customers/ - Customer-specific overrides
  • /ontology/layer-manifest.yaml - Layer configuration
  • @src/utils/fs.ts - File system operations

External Interactions:

  • Composed ontology consumed by all other modules

11. /src/mcp/ - Model Context Protocol Server

Core Responsibility

Implements an MCP server that exposes ontology capabilities to AI agents (like Claude). Provides tools for querying entities, events, state machines, and validation.

Key Components

FileRole
ontology-mcp-server.tsMain MCP server implementation
loaders/ (9 files)Data loaders for entities, events, state machines, commands, relationships, vocabulary, etc.
services/ (1 file)Service layer for MCP operations

Dependencies & Interactions

Internal Dependencies:

  • @src/validation/ - For validation tool
  • @src/events/ - Event registry access
  • @src/relationships/ - Relationship queries
  • @src/vocabulary/ - Vocabulary lookups
  • @src/layering/ - Layer-aware loading
  • /ontology/ - Direct YAML file access via loaders

External Interactions:

  • MCP Protocol - AI agent communication
  • /packages/mcp-client/ - Client package for consumers

12. /src/projections/ - Read Model Projections

Core Responsibility

Generates and manages read-optimized views (projections) from event streams. Supports materialized views for dashboard and reporting use cases.

Key Components

FileRole
index.tsModule exports
types.tsProjection definitions, view schemas
projection-engine.tsBuilds projections from events
projection-cache.tsCaches computed projections

Dependencies & Interactions

Internal Dependencies:

  • /ontology/projections/ - Projection definitions (YAML)
  • @src/events/ - Event stream processing
  • @src/config/database.ts - View persistence

External Interactions:

  • Consumed by UI dashboards and analytics services

13. /src/testing/ - Testing Infrastructure

Core Responsibility

Provides testing utilities, fixture generation, and validation tools specifically for ontology artifacts. Supports automated testing of rules and workflows.

Key Components

FileRole
index.tsModule exports
types.tsTest case types, fixture schemas
ontology-test-runner.tsRuns ontology-specific tests
test-case-generator.tsGenerates test cases from ontology definitions
coverage-reporter.tsReports test coverage for ontology artifacts
jsonlogic-validator.tsTests JSON Logic rules
schema-validator.tsValidates YAML schemas
reference-validator.tsValidates cross-references between artifacts
ontology-rule-loader.tsLoads rules for testing
workflow-loader.tsLoads workflows for testing
fixtures/ (6 files)Test fixture data

Dependencies & Interactions

Internal Dependencies:

  • /ontology/testing/ - Test scenarios and scaffold definitions
  • @src/validation/ - Uses validation engine
  • @src/layering/ - Tests composed ontology

External Interactions:

  • Integrated with Vitest test runner
  • Used in CI/CD pipelines

14. /src/scripts/ - Automation Scripts

Core Responsibility

Contains CLI scripts for ontology management, validation, migration, and CI/CD automation.

Key Components

FileRole
validate-ontology.tsValidates all ontology artifacts
compose-ontology.tsComposes layered ontology
compile-bundle.tsCreates distributable bundles
run-migrations.tsExecutes database migrations
check-ontology-drift.tsDetects drift from source of truth
check-consumer-compatibility.tsValidates consumer compatibility
check-consumer-stale-versions.tsIdentifies outdated consumers
check-migration-hygiene.tsValidates migration files
classify-ontology-release.tsDetermines semver classification
generate-release-migration-notes.tsAuto-generates release notes
create-consumer-update-prs.tsCreates PRs for consumer updates
ingest-production-signals.tsProcesses production telemetry
role-evolution-guards.tsValidates role changes
artifact-hash.tsGenerates artifact checksums
generate-coverage.tsGenerates test coverage reports
utils.tsShared script utilities

Dependencies & Interactions

Internal Dependencies:

  • Nearly all @src/ modules for various operations
  • /ontology/ - Primary data source
  • /database/migrations/ - Migration files
  • /compat/ - Consumer compatibility data

External Interactions:

  • GitHub API (for PR creation)
  • CI/CD pipelines (.github/workflows/)

15. /src/governance/ - Governance System

Core Responsibility

Manages ontology change proposals, approvals, and production signal validation. Ensures controlled evolution of the ontology.

Key Components

FileRole
proposal-service.tsManages change proposals and approval workflows
signal-validator.tsValidates incoming production signals for governance decisions

Dependencies & Interactions

Internal Dependencies:

  • @src/config/database.ts - Proposal persistence
  • @src/versioning/ - Version impact analysis
  • /.ontology-governance/ - Governance configuration per tenant

External Interactions:

  • May trigger GitHub workflows for PR creation

16. /src/analysis/ - Analysis Tools

Core Responsibility

Provides analytical capabilities including natural language translation of ontology concepts.

Key Components

FileRole
nl-translator.tsTranslates between natural language and ontology terms

Dependencies & Interactions

Internal Dependencies:

  • @src/vocabulary/ - Domain vocabulary for translation
  • @src/events/ - Event semantics

External Interactions:

  • May integrate with LLM APIs for enhanced NL processing

17. /src/workflows/ - Workflow Analysis

Core Responsibility

Analyzes and validates business workflows defined in the ontology.

Key Components

FileRole
workflow-analyzer.tsAnalyzes workflow definitions for completeness and consistency

Dependencies & Interactions

Internal Dependencies:

  • /ontology/core/workflows/ - Workflow definitions
  • @src/validation/ - Workflow validation

18. /src/onboarding/ - Tenant Onboarding

Core Responsibility

Manages the onboarding process for new tenants, including ontology provisioning.

Key Components

FileRole
onboarding-service.tsOrchestrates tenant onboarding workflow

Dependencies & Interactions

Internal Dependencies:

  • @src/layering/ - Tenant-specific layer setup
  • @src/config/database.ts - Tenant data provisioning

19. /src/db/repositories/ - Data Access Layer

Core Responsibility

Provides repository pattern implementations for database operations.

Key Components

FileRole
entity.repository.tsCRUD operations for entities
relationship.repository.tsRelationship data operations

Dependencies & Interactions

Internal Dependencies:

  • @src/config/database.ts - Connection pool
  • Database schema defined in /database/migrations/

20. /src/config/ - Configuration

Core Responsibility

Centralizes application configuration for database and external services.

Key Components

FileRole
database.tsPostgreSQL/Supabase connection configuration
nats.tsNATS messaging configuration

Dependencies & Interactions

Internal Dependencies:

  • Environment variables (.env.example)

External Interactions:

  • PostgreSQL/Supabase
  • NATS server

21. /src/utils/ - Utilities

Core Responsibility

Shared utility functions used across the application.

Key Components

FileRole
casing.tsString case conversion (camelCase, snake_case, etc.)
checksum.tsHash/checksum generation for artifacts
fs.tsFile system helpers
paths.tsPath resolution utilities

22. /ui/ - Frontend Application

Core Responsibility

React-based web application for exploring and managing the ontology.

Key Components

Directory/FileRole
main.tsxApplication entry point
router.tsxReact Router configuration
features/Feature modules (analysis, commands, dashboard, entities, events, explore, governance, roles, search, state-machines, versioning)
components/Shared UI components
layouts/Page layout components
hooks/Custom React hooks
api/API client functions
lib/Utility libraries
design-system/Design tokens and base components

Dependencies & Interactions

Internal Dependencies:

  • @src/api/ - Backend API (via HTTP)

External Interactions:

  • Vite development server
  • TailwindCSS for styling

23. /ontology/ - Ontology Definitions

Core Responsibility

The source of truth for all domain definitions - entities, events, state machines, commands, relationships, vocabulary, and business rules.

Key Components

DirectoryRole
core/Core domain definitions (entities, state-machines, workflows, validation-rules, event-mappings, vocabulary)
composed/Pre-composed/merged artifacts for runtime
verticals/Industry vertical extensions (e.g., propane)
customers/Customer-specific customizations
markets/Market-specific adaptations (e.g., Kenya propane)
commands/Command definitions
errors/Error definitions
relationships/Entity relationship definitions
projections/Read model/view definitions
bundles/Role-based artifact bundles
meta/Cross-cutting metadata (roles, permissions, SLAs, audit)
legacy/Pre-migration artifacts for reference
testing/Test scaffolds and scenarios
event-registry.yamlMaster event catalog
layer-manifest.yamlLayer composition configuration

24. /packages/ - Distributable Packages

Core Responsibility

NPM packages for consuming the ontology in other projects.

Key Components

PackageRole
packages/ontology/Core ontology package with TypeScript types and loaders
packages/mcp-client/MCP client for AI agent integration

Dependencies & Interactions

Internal Dependencies:

  • /ontology/ - Source definitions
  • @src/ - Generation scripts

External Interactions:

  • Published to NPM registry
  • Consumed by external services

25. /database/migrations/ - Database Schema

Core Responsibility

SQL migration files defining the database schema for persisting ontology data.

Key Components (14 migrations)

MigrationRole
001_initial_schema.sqlBase tables
002_semantic_tables.sqlEvent semantics storage
003_enable_rls.sqlRow-level security
004_commands_execution.sqlCommand execution tracking
005_validation_rules.sqlValidation rule storage
006_projections_versioning.sqlVersion management
007_relationship_definitions.sqlRelationship storage
008_error_definitions.sqlError catalog
009_vocabulary.sqlVocabulary storage
010_operational_health.sqlHealth metrics
011_semantic_table_compatibility.sqlCompatibility tracking
012_tenant_security_hardening.sqlEnhanced tenant isolation
013_force_rls_all_tables.sqlRLS enforcement
014_add_execution_tenant_index.sqlPerformance indexes

Dependency Graph Summary

┌─────────────────────────────────────────────────────────────┐
│                        /ui/ (Frontend)                       │
└─────────────────────────────┬───────────────────────────────┘
                              │ HTTP
┌─────────────────────────────▼───────────────────────────────┐
│                      /src/api/ (REST API)                    │
├──────────┬──────────┬──────────┬──────────┬─────────────────┤
│ commands │validation│  events  │relations │   vocabulary    │
├──────────┴──────────┴──────────┴──────────┴─────────────────┤
│                      /src/layering/                          │
├─────────────────────────────────────────────────────────────┤
│                       /ontology/ (YAML)                      │
└─────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────▼───────────────────────────

# dependencies

Analyze dependencies and external libraries

# Dependency and Architecture Analysis

**Repository:** ontology-circl_f852c27b

---

## Internal Modules

Based on the repository structure and directory organization, the following internal modules and packages have been identified:

### Backend (`/src/`)

| Module | Primary Responsibility |
|--------|----------------------|
| `src/api/` | HTTP API layer with Fastify server, routes, and middleware for exposing ontology services |
| `src/api/routes/` | Individual API route handlers (21 files) for various ontology endpoints |
| `src/api/middleware/` | Request processing middleware (authentication, validation, etc.) |
| `src/commands/` | Command pattern implementation with executor, registry, and approval service for ontology operations |
| `src/errors/` | Centralized error handling, error registry, and error seeding utilities |
| `src/events/` | Event semantics registry, event processing, and event registry loading |
| `src/validation/` | Validation engine with JSON Logic evaluation, state machine validation, and rule caching |
| `src/relationships/` | Relationship registry, validation, and seeding for entity relationships |
| `src/vocabulary/` | Domain vocabulary registry and seeding for ontology terminology |
| `src/versioning/` | Version management, compatibility layer, and migration services for ontology versions |
| `src/projections/` | Projection engine and caching for materialized views of ontology data |
| `src/sync/` | NATS-based synchronization service for ontology updates across services |
| `src/mcp/` | Model Context Protocol server implementation with loaders for AI/LLM integration |
| `src/layering/` | Layer composition system for combining ontology layers (core, market, customer) |
| `src/governance/` | Proposal service and signal validation for ontology governance workflows |
| `src/workflows/` | Workflow analysis utilities |
| `src/analysis/` | Natural language translation utilities for ontology analysis |
| `src/testing/` | Test infrastructure including coverage reporting, schema validation, and test case generation |
| `src/onboarding/` | Onboarding service for new tenant setup |
| `src/config/` | Configuration modules for database and NATS connections |
| `src/db/repositories/` | Data access layer with repository pattern implementations |
| `src/utils/` | Shared utilities for casing, checksums, filesystem operations, and path handling |
| `src/scripts/` | Operational scripts for artifact management, migrations, ontology composition, and CI/CD tasks |

### Frontend (`/ui/src/`)

| Module | Primary Responsibility |
|--------|----------------------|
| `ui/src/features/` | Feature-based modules including analysis, commands, dashboard, entities, events, explore, governance, roles, search, state-machines, and versioning |
| `ui/src/components/` | Shared React UI components |
| `ui/src/layouts/` | Page layout components |
| `ui/src/hooks/` | Custom React hooks for shared logic |
| `ui/src/api/` | API client layer for backend communication |
| `ui/src/lib/` | Utility libraries |
| `ui/src/design-system/` | Design system components and styling |
| `ui/src/utils/` | Frontend utility functions |

### Packages (`/packages/`)

| Package | Primary Responsibility |
|---------|----------------------|
| `packages/ontology/` | Standalone ontology package with generated types and JSON Logic integration, publishable for consumer use |
| `packages/mcp-client/` | MCP (Model Context Protocol) client library for connecting to the ontology MCP server |

### Ontology Definitions (`/ontology/`)

| Directory | Primary Responsibility |
|-----------|----------------------|
| `ontology/core/` | Core ontology definitions: entities, state-machines, workflows, validation-rules, event-mappings, vocabulary |
| `ontology/meta/` | Meta-level configurations: roles, permissions, audit, SLA, tenant model, business rules |
| `ontology/composed/` | Composed/merged ontology artifacts from layering system |
| `ontology/commands/` | Command definitions for dispatcher, driver, operations, and exceptions |
| `ontology/errors/` | Error code definitions |
| `ontology/relationships/` | Cross-entity and cross-system relationship definitions |
| `ontology/projections/` | Projection/view definitions for reporting and dashboards |
| `ontology/bundles/` | Pre-packaged ontology bundles for specific roles (dispatcher, driver, billing, etc.) |
| `ontology/verticals/` | Vertical-specific extensions (e.g., propane) |
| `ontology/markets/` | Market-specific ontology extensions (e.g., Kenya propane) |
| `ontology/customers/` | Customer-specific ontology extensions (e.g., MGAS) |
| `ontology/legacy/` | Legacy/pre-migration ontology artifacts |
| `ontology/testing/` | Test scaffolds and fixture specifications |

### Database (`/database/`)

| Directory | Primary Responsibility |
|-----------|----------------------|
| `database/migrations/` | SQL migration scripts for schema evolution (initial schema, semantic tables, RLS, commands, validation, projections, relationships, errors, vocabulary, etc.) |

### Compatibility (`/compat/`)

| Directory | Primary Responsibility |
|-----------|----------------------|
| `compat/consumers/` | Consumer compatibility configurations and fixtures |
| `compat/convergence/` | Convergence profiles for ontology synchronization |

---

## External Dependencies

### Production Dependencies

#### Backend (`/package.json`)

| Dependency | Official Name | Primary Role |
|------------|---------------|--------------|
| `@anthropic-ai/sdk` | Anthropic SDK | AI/LLM integration for Claude API access |
| `@fastify/cors` | Fastify CORS | Cross-Origin Resource Sharing middleware for Fastify |
| `@fastify/helmet` | Fastify Helmet | Security headers middleware for Fastify |
| `@fastify/static` | Fastify Static | Static file serving for Fastify |
| `@modelcontextprotocol/sdk` | Model Context Protocol SDK | MCP server/client implementation for AI tool integration |
| `ajv` | AJV | JSON Schema validator |
| `ajv-formats` | AJV Formats | Format validation extensions for AJV |
| `dotenv` | dotenv | Environment variable loading from `.env` files |
| `fastify` | Fastify | High-performance web framework for Node.js |
| `js-yaml` | js-yaml | YAML parser and serializer |
| `json-logic-js` | JsonLogic | JSON-based rule engine for validation logic |
| `jsonpath-plus` | JSONPath Plus | JSONPath query implementation |
| `nats` | NATS | Client for NATS messaging system |
| `pg` | node-postgres | PostgreSQL database client |
| `pino` | Pino | High-performance JSON logger |
| `uuid` | uuid | UUID generation |
| `yaml` | YAML | YAML parser (alternative implementation) |
| `zod` | Zod | TypeScript-first schema validation |

**Source:** `/package.json`

#### MCP Client Package (`/packages/mcp-client/package.json`)

| Dependency | Official Name | Primary Role |
|------------|---------------|--------------|
| `@modelcontextprotocol/sdk` | Model Context Protocol SDK | MCP client implementation |

**Source:** `/packages/mcp-client/package.json`

#### Ontology Package (`/packages/ontology/package.json`)

| Dependency | Official Name | Primary Role |
|------------|---------------|--------------|
| `json-logic-js` | JsonLogic | JSON-based rule evaluation |

**Source:** `/packages/ontology/package.json`

#### Frontend (`/ui/package.json`)

| Dependency | Official Name | Primary Role |
|------------|---------------|--------------|
| `@dagrejs/dagre` | Dagre | Directed graph layout algorithm for visualizations |
| `@tanstack/react-query` | TanStack Query (React Query) | Server state management and data fetching |
| `@xyflow/react` | React Flow | Interactive node-based graph/flow editor |
| `lucide-react` | Lucide React | Icon library |
| `react` | React | UI component library |
| `react-dom` | React DOM | React DOM rendering |
| `react-router` | React Router | Client-side routing |
| `zod` | Zod | Schema validation |

**Source:** `/ui/package.json`

---

### Development Dependencies

#### Backend (`/package.json`)

| Dependency | Official Name | Primary Role |
|------------|---------------|--------------|
| `@types/js-yaml` | js-yaml Types | TypeScript type definitions for js-yaml |
| `@types/json-logic-js` | json-logic-js Types | TypeScript type definitions for json-logic-js |
| `@types/node` | Node.js Types | TypeScript type definitions for Node.js |
| `@types/pg` | pg Types | TypeScript type definitions for node-postgres |
| `@types/semver` | semver Types | TypeScript type definitions for semver |
| `@types/uuid` | uuid Types | TypeScript type definitions for uuid |
| `@typescript-eslint/eslint-plugin` | TypeScript ESLint Plugin | ESLint rules for TypeScript |
| `@typescript-eslint/parser` | TypeScript ESLint Parser | TypeScript parser for ESLint |
| `@vitest/coverage-v8` | Vitest Coverage V8 | Code coverage provider for Vitest |
| `eslint` | ESLint | JavaScript/TypeScript linter |
| `pino-pretty` | Pino Pretty | Pretty-printing for Pino logs (development) |
| `semver` | semver | Semantic versioning utilities |
| `tsx` | tsx | TypeScript execution for Node.js |
| `typescript` | TypeScript | TypeScript compiler |
| `vitest` | Vitest | Unit testing framework |

**Source:** `/package.json`

#### Ontology Package (`/packages/ontology/package.json`)

| Dependency | Official Name | Primary Role |
|------------|---------------|--------------|
| `@types/json-logic-js` | json-logic-js Types | TypeScript type definitions |
| `typescript` | TypeScript | TypeScript compiler |
| `vitest` | Vitest | Unit testing framework |

**Source:** `/packages/ontology/package.json`

#### Frontend (`/ui/package.json`)

| Dependency | Official Name | Primary Role |
|------------|---------------|--------------|
| `@tailwindcss/vite` | Tailwind CSS Vite Plugin | Tailwind CSS integration for Vite |
| `@types/react` | React Types | TypeScript type definitions for React |
| `@types/react-dom` | React DOM Types | TypeScript type definitions for React DOM |
| `@vitejs/plugin-react` | Vite React Plugin | React support for Vite |
| `autoprefixer` | Autoprefixer | CSS vendor prefix automation |
| `postcss` | PostCSS | CSS transformation tool |
| `tailwindcss` | Tailwind CSS | Utility-first CSS framework |
| `typescript` | TypeScript | TypeScript compiler |
| `vite` | Vite | Frontend build tool and dev server |

**Source:** `/ui/package.json`

---

### Infrastructure Dependencies

#### Container Images (`/Dockerfile`, `/docker-compose.yml`)

| Dependency | Official Name | Primary Role |
|------------|---------------|--------------|
| `node:20-alpine` | Node.js | JavaScript runtime (Alpine Linux variant) |
| `postgres:15-alpine` | PostgreSQL | Relational database for ontology storage |
| `nats:2.10-alpine` | NATS | Message broker for event synchronization with JetStream |

**Source:** `/Dockerfile`, `/docker-compose.yml`

# core_entities

Core entities and their relationships

# Ontology-CIRCL Domain Model Analysis

## Executive Summary

This repository implements an **Ontology Service** for a logistics/delivery management platform (CIRCL). It's a multi-tenant, event-driven system that manages fleet operations, order fulfillment, IoT device tracking, and delivery workflows. The ontology defines entities, state machines, validation rules, commands, events, and their relationships.

---

## 1. Common Data Entities

Based on analysis of the ontology YAML files, database migrations, TypeScript types, and API routes, here are the central domain entities:

### 1.1 Core Business Entities

| Entity | Description | Source Files |
|--------|-------------|--------------|
| **Order** | Customer orders for delivery | `ontology/core/entities/`, `ontology/composed/entities/` |
| **Trip** | Delivery trip grouping multiple orders | `ontology/core/entities/` |
| **Vehicle** | Fleet vehicles used for deliveries | `ontology/core/entities/` |
| **Driver** | Personnel operating vehicles | `ontology/core/entities/` |
| **Asset** | Physical assets (tanks, equipment) | `ontology/core/entities/` |
| **Customer** | End customers receiving deliveries | `ontology/core/entities/` |
| **Depot** | Distribution centers/warehouses | `ontology/core/entities/` |
| **Geofence** | Geographic boundaries for tracking | `ontology/core/entities/` |
| **Measurement** | IoT sensor readings | `ontology/core/entities/` |
| **Exception** | Operational exceptions/issues | `ontology/core/entities/` |

### 1.2 Ontology Management Entities

| Entity | Description | Source Files |
|--------|-------------|--------------|
| **Entity Definition** | Schema definitions for domain entities | `database/migrations/001_initial_schema.sql` |
| **State Machine** | Lifecycle state definitions | `database/migrations/001_initial_schema.sql` |
| **Event Semantic** | Event type definitions and ownership | `database/migrations/002_semantic_tables.sql` |
| **Validation Rule** | Business rule definitions | `database/migrations/005_validation_rules.sql` |
| **Command** | Executable operations | `database/migrations/004_commands_execution.sql` |
| **Relationship Definition** | Entity relationship mappings | `database/migrations/007_relationship_definitions.sql` |
| **Vocabulary** | Domain terminology/translations | `database/migrations/009_vocabulary.sql` |
| **Projection** | Read-model definitions | `database/migrations/006_projections_versioning.sql` |
| **Error Definition** | Standardized error codes | `database/migrations/008_error_definitions.sql` |

---

## 2. Key Attributes/Fields

### 2.1 Entity Definition
```yaml
# From database/migrations/001_initial_schema.sql
entity_definitions:
  - id: UUID (PK)
  - tenant_id: UUID (FK → tenants)
  - name: TEXT (unique per tenant)
  - version: INTEGER
  - schema: JSONB           # JSON Schema for entity structure
  - metadata: JSONB         # Additional configuration
  - created_at: TIMESTAMPTZ
  - updated_at: TIMESTAMPTZ

2.2 State Machine

# From database/migrations/001_initial_schema.sql
state_machines:
  - id: UUID (PK)
  - tenant_id: UUID (FK → tenants)
  - entity_name: TEXT (FK → entity_definitions)
  - name: TEXT
  - version: INTEGER
  - states: JSONB           # Available states
  - transitions: JSONB      # Valid state transitions
  - initial_state: TEXT
  - metadata: JSONB
  - created_at: TIMESTAMPTZ
  - updated_at: TIMESTAMPTZ

2.3 Event Semantic

# From database/migrations/002_semantic_tables.sql
event_semantics:
  - id: UUID (PK)
  - tenant_id: UUID (FK → tenants)
  - event_type: TEXT        # e.g., "order.created"
  - version: INTEGER
  - schema: JSONB           # Event payload schema
  - owning_service: TEXT    # Service that emits this event
  - processing_services: TEXT[]  # Services that consume
  - metadata: JSONB
  - created_at: TIMESTAMPTZ
  - updated_at: TIMESTAMPTZ

2.4 Validation Rule

# From database/migrations/005_validation_rules.sql
validation_rules:
  - id: UUID (PK)
  - tenant_id: UUID (FK → tenants)
  - name: TEXT
  - entity_name: TEXT       # Target entity
  - version: INTEGER
  - rule_type: TEXT         # 'jsonlogic', 'schema', etc.
  - rule_definition: JSONB  # JSONLogic expression
  - error_code: TEXT
  - error_message: TEXT
  - severity: TEXT          # 'error', 'warning'
  - enabled: BOOLEAN
  - metadata: JSONB
  - created_at: TIMESTAMPTZ

2.5 Command Definition

# From database/migrations/004_commands_execution.sql
command_definitions:
  - id: UUID (PK)
  - tenant_id: UUID (FK → tenants)
  - name: TEXT              # e.g., "dispatch.assign_driver"
  - version: INTEGER
  - input_schema: JSONB     # Expected input structure
  - output_schema: JSONB    # Expected output structure
  - preconditions: JSONB    # Required state/conditions
  - postconditions: JSONB   # Guaranteed outcomes
  - target_entity: TEXT
  - requires_approval: BOOLEAN
  - allowed_roles: TEXT[]
  - metadata: JSONB

command_executions:
  - id: UUID (PK)
  - tenant_id: UUID (FK → tenants)
  - command_id: UUID (FK → command_definitions)
  - input_payload: JSONB
  - output_payload: JSONB
  - status: TEXT            # 'pending', 'approved', 'executed', 'failed'
  - executed_by: TEXT
  - executed_at: TIMESTAMPTZ
  - error_details: JSONB

2.6 Relationship Definition

# From database/migrations/007_relationship_definitions.sql
relationship_definitions:
  - id: UUID (PK)
  - tenant_id: UUID (FK → tenants)
  - name: TEXT              # e.g., "order_to_customer"
  - source_entity: TEXT
  - target_entity: TEXT
  - cardinality: TEXT       # 'one-to-one', 'one-to-many', 'many-to-many'
  - inverse_name: TEXT      # Reverse relationship name
  - metadata: JSONB
  - created_at: TIMESTAMPTZ

2.7 Vocabulary Term

# From database/migrations/009_vocabulary.sql
vocabulary_terms:
  - id: UUID (PK)
  - tenant_id: UUID (FK → tenants)
  - term: TEXT              # Canonical term
  - category: TEXT          # 'entity', 'action', 'status', etc.
  - definition: TEXT
  - synonyms: TEXT[]
  - translations: JSONB     # { "es": "...", "fr": "..." }
  - context: TEXT           # Usage context
  - metadata: JSONB

2.8 Projection Definition

# From database/migrations/006_projections_versioning.sql
projection_definitions:
  - id: UUID (PK)
  - tenant_id: UUID (FK → tenants)
  - name: TEXT
  - version: INTEGER
  - source_events: TEXT[]   # Events that feed this projection
  - schema: JSONB           # Output schema
  - aggregation_logic: JSONB
  - refresh_strategy: TEXT  # 'realtime', 'periodic', 'on-demand'
  - metadata: JSONB

2.9 Error Definition

# From database/migrations/008_error_definitions.sql
error_definitions:
  - id: UUID (PK)
  - tenant_id: UUID (FK → tenants)
  - code: TEXT              # e.g., "ERR_ORDER_001"
  - category: TEXT          # 'validation', 'business', 'system'
  - message_template: TEXT
  - severity: TEXT
  - http_status: INTEGER
  - recoverable: BOOLEAN
  - metadata: JSONB

2.10 Tenant

# From database/migrations/001_initial_schema.sql
tenants:
  - id: UUID (PK)
  - name: TEXT
  - slug: TEXT (unique)
  - settings: JSONB
  - enabled: BOOLEAN
  - created_at: TIMESTAMPTZ
  - updated_at: TIMESTAMPTZ

3. Entity Relationships

3.1 Ontology Meta-Model Relationships

┌─────────────────────────────────────────────────────────────────────────────┐
│                              TENANT (Multi-tenant Isolation)                 │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                                                                     │    │
│  │    ┌──────────────────┐         ┌────────────────────┐             │    │
│  │    │ Entity Definition│◄───────►│   State Machine    │             │    │
│  │    │   (1)            │   1:N   │      (N)           │             │    │
│  │    └────────┬─────────┘         └──────────┬─────────┘             │    │
│  │             │                              │                        │    │
│  │             │ 1:N                          │ triggers               │    │
│  │             ▼                              ▼                        │    │
│  │    ┌──────────────────┐         ┌────────────────────┐             │    │
│  │    │ Validation Rule  │         │   Event Semantic   │             │    │
│  │    │      (N)         │         │       (N)          │             │    │
│  │    └──────────────────┘         └──────────┬─────────┘             │    │
│  │             │                              │                        │    │
│  │             │ references                   │ feeds                  │    │
│  │             ▼                              ▼                        │    │
│  │    ┌──────────────────┐         ┌────────────────────┐             │    │
│  │    │ Error Definition │         │    Projection      │             │    │
│  │    │      (N)         │         │       (N)          │             │    │
│  │    └──────────────────┘         └────────────────────┘             │    │
│  │                                                                     │    │
│  │    ┌──────────────────┐         ┌────────────────────┐             │    │
│  │    │ Command Definition│◄───────►│ Command Execution │             │    │
│  │    │      (1)         │   1:N   │       (N)          │             │    │
│  │    └────────┬─────────┘         └────────────────────┘             │    │
│  │             │                                                       │    │
│  │             │ targets                                               │    │
│  │             ▼                                                       │    │
│  │    ┌──────────────────┐                                            │    │
│  │    │ Entity Definition│                                            │    │
│  │    └──────────────────┘                                            │    │
│  │                                                                     │    │
│  │    ┌──────────────────┐                                            │    │
│  │    │   Relationship   │──────► source_entity ──► Entity Definition │    │
│  │    │   Definition     │──────► target_entity ──► Entity Definition │    │
│  │    └──────────────────┘                                            │    │
│  │                                                                     │    │
│  │    ┌──────────────────┐                                            │    │
│  │    │ Vocabulary Term  │ (standalone, cross-references entities)    │    │
│  │    └──────────────────┘                                            │    │
│  │                                                                     │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────────────────┘

3.2 Detailed Relationship Descriptions

RelationshipTypeDescription
Tenant → All EntitiesOne-to-ManyEvery ontology artifact belongs to exactly one tenant (RLS enforced)
Entity Definition → State MachineOne-to-ManyAn entity can have multiple state machines (e.g., Order has order-lifecycle, order-payment-status)
Entity Definition → Validation RuleOne-to-ManyMultiple validation rules can target the same entity
Entity Definition → Command DefinitionOne-to-ManyCommands operate on specific entity types
Event Semantic → ProjectionMany-to-ManyProjections aggregate multiple event types; events feed multiple projections
Command Definition → Command ExecutionOne-to-ManyEach command definition can have many execution instances
Relationship Definition → Entity DefinitionMany-to-TwoEach relationship links two entity definitions (source & target)
Validation Rule → Error DefinitionMany-to-OneRules reference error codes for consistent error handling
State Machine → Event SemanticMany-to-ManyState transitions emit events; events can trigger state changes

3.3 Business Domain Relationships

Based on ontology/relationships/ files:

┌─────────────────────────────────────────────────────────────────────┐
│                    OMS (Order Management System)                     │
│                                                                      │
│  ┌──────────┐     1:N      ┌──────────┐     N:1      ┌──────────┐  │
│  │ Customer │◄────────────►│  Order   │◄────────────►│   Trip   │  │
│  └──────────┘              └────┬─────┘              └────┬─────┘  │
│       │                         │                         │        │
│       │ 1:N                     │ N:1                     │ N:1    │
│       ▼                         ▼                         ▼        │
│  ┌──────────┐              ┌──────────┐              ┌──────────┐  │
│  │  Asset   │              │  Driver  │◄────────────►│ Vehicle  │  │
│  └──────────┘              └──────────┘     1:1      └──────────┘  │
│       │                                                   │        │
│       │ located_at                                        │        │
│       ▼                                                   ▼        │
│  ┌──────────┐              ┌──────────┐              ┌──────────┐  │
│  │ Geofence │◄────────────►│  Depot   │◄────────────►│ Inventory│  │
│  └──────────┘   contains   └──────────┘   stores     └──────────┘  │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────┐
│                      IoT (Device Management)                         │
│                                                                      │
│  ┌──────────┐     1:N      ┌─────────────┐    N:1     ┌──────────┐ │
│  │  Asset   │◄────────────►│ Measurement │◄──────────►│  Sensor  │ │
│  └──────────┘              └─────────────┘            └──────────┘ │
│       │                          │                                  │
│       │ monitored_by             │ triggers                         │
│       ▼                          ▼                                  │
│  ┌──────────┐              ┌──────────┐                            │
│  │  Device  │              │  Alert   │                            │
│  └──────────┘              └──────────┘                            │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────┐
│                     Cross-System Relationships                       │
│                                                                      │
│  OMS::Order ──────────► DMS::Document (proof of delivery)           │
│  OMS::Trip  ──────────► IoT::Telemetry (vehicle tracking)           │
│  OMS::Asset ──────────► IoT::Measurement (tank levels)              │
│  OMS::Vehicle ────────► IoT::Device (GPS tracker)                   │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

3.4 Relationship Cardinality Summary

Source EntityRelationshipTarget EntityCardinality
CustomerplacesOrder1:N
Orderbelongs_toTripN:1
Tripassigned_toDriverN:1
DriveroperatesVehicle1:1
Vehiclebased_atDepotN:1
Assetowned_byCustomerN:1
Assetlocated_inGeofenceN:1
Assethas_measurementsMeasurement1:N
Orderdelivers_toAssetN:1
Exceptionrelated_toOrder/Trip/AssetN:1 (polymorphic)
DepotcontainsGeofence1:N
DepotstoresInventory1:N

4. Layering & Composition Model

The ontology uses a layered composition model:

┌─────────────────────────────────────────────────────────────┐
│                    Layer Hierarchy                           │
├─────────────────────────────────────────────────────────────┤
│  4. Customer Layer    (ontology/customers/{tenant}/)        │
│     └── Tenant-specific customizations                      │
├─────────────────────────────────────────────────────────────┤
│  3. Vertical Layer    (ontology/verticals/{industry}/)      │
│     └── Industry-specific (e.g., propane delivery)          │
├─────────────────────────────────────────────────────────────┤
│  2. Market Layer      (ontology/markets/{region}/)          │
│     └── Regional adaptations (e.g., Kenya propane)          │
├─────────────────────────────────────────────────────────────┤
│  1. Core Layer        (ontology/core/)                      │
│     └── Base entities, state machines, validation rules     │
└─────────────────────────────────────────────────────────────┘

Composition: Higher layers EXTEND or OVERRIDE lower layers
Output: ontology/composed/ (merged result)

5. TypeScript Domain Types

From src/ and packages/ontology/src/:

// Entity Registry Types (src/validation/types.ts inferred)
interface EntityDefinition {
  id: string;
  tenantId: string;
  name: string;
  version: number;
  schema: JSONSchema;
  metadata: Record<string, unknown>;
}

// State Machine Types
interface StateMachine {
  id: string;
  entityName: string;
  name: string;
  states: State[];
  transitions: Transition[];
  initialState: string;
}

interface Transition {
  from: string;
  to: string;
  event: string;
  guards?: JSONLogicRule[];
  actions?: string[];
}

// Event Types (src/events/types.ts)
interface EventSemantic {
  eventType: string;
  version: number;
  schema: JSONSchema;
  owningService: string;
  processingServices: string[];
}

// Command Types (src/commands/types.ts)
interface CommandDefinition {
  name: string;
  targetEntity: string;
  inputSchema: JSONSchema;
  preconditions: JSONLogicRule[];
  postconditions: Postcondition[];
  requiresApproval: boolean;
  allowedRoles: string[];
}

// Validation Types
interface ValidationRule {
  name: string;
  entityName: string;
  ruleType: 'jsonlogic' | 'schema';
  ruleDefinition: JSONLogicRule;
  errorCode: string;
  severity: 'error' | 'warning';
}

6. Summary Diagram

                         ┌─────────────────────┐
                         │      TENANTS        │
                         │  (Multi-tenant)     │
                         └──────────┬──────────┘
                                    │
           ┌────────────────────────┼────────────────────────┐
           │                        │                        │
           ▼                        ▼                        ▼
   ┌───────────────┐      ┌───────────────┐      ┌───────────────┐
   │   ONTOLOGY    │      │   RUNTIME     │      │  GOVERNANCE   │
   │  DEFINITIONS  │      │  EXECUTIONS   │      │   & AUDIT     │
   ├───────────────┤      ├───────────────┤      ├───────────────┤
   │ • Entities    │      │ • Command Exec│      │ • Proposals   │
   │ • StateMachines│     │ • Validations │      │ • Versions    │
   │ • Events      │◄────►│ • Projections │◄────►│ • Migrations  │
   │ • Commands    │      │ • Event Stream│      │ • Compatibility│
   │ • Rules       │      │               │      │               │
   │ • Vocabulary  │      │               │      │               │
   └───────────────┘      └───────────────┘      └───────────────┘
           │                        │                        │
           └────────────────────────┼────────────────────────┘
                                    │
                         ┌──────────▼──────────┐
                         │   BUSINESS DOMAIN   │
                         │  (OMS/IoT/DMS)      │
                         ├─────────────────────┤
                         │ • Orders            │
                         │ • Trips             │
                         │ • Vehicles/Drivers  │
                         │ • Assets            │
                         │ • Measurements      │
                         │ • Geofences         │
                         └─────────────────────┘

state_machines

Entity lifecycle state machines and transitions

I'll analyze this codebase to identify all entities with lifecycle states and extract their complete state machine definitions. Let me scan through the relevant files.

Looking at the repository structure, I can see there's a dedicated ontology/core/state-machines/ directory with 46 files, and also ontology/composed/state-machines/ with 71 files. Let me examine these YAML files to extract the state machine definitions.

Based on my comprehensive analysis of the codebase, I found extensive state machine definitions in the ontology/core/state-machines/ and ontology/composed/state-machines/ directories. Let me document all the state machines found:


Entity: Order

States: DRAFT, PENDING_APPROVAL, APPROVED, REJECTED, ALLOCATED, DISPATCHED, IN_TRANSIT, DELIVERED, PARTIALLY_DELIVERED, FAILED, CANCELLED

State Machine Diagram:

DRAFT ──► PENDING_APPROVAL ──► APPROVED ──► ALLOCATED ──► DISPATCHED ──► IN_TRANSIT
              │                    │                                         │
              ▼                    ▼                                         ├──► DELIVERED
          CANCELLED            REJECTED                                      ├──► PARTIALLY_DELIVERED
              ▲                                                              └──► FAILED
              │
    (from DRAFT, PENDING_APPROVAL, APPROVED, ALLOCATED)

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
DRAFTPENDING_APPROVALsubmitall_required_fields_setorder.submitted
PENDING_APPROVALAPPROVEDapproveapprover_roleorder.approved
PENDING_APPROVALREJECTEDrejectrejection_reason_providedorder.rejected
APPROVEDALLOCATEDallocateinventory_availableorder.allocated
ALLOCATEDDISPATCHEDdispatchdriver_assigned, vehicle_assignedorder.dispatched
DISPATCHEDIN_TRANSITstart_deliverytrip_startedorder.in_transit
IN_TRANSITDELIVEREDcompletepod_capturedorder.delivered
IN_TRANSITPARTIALLY_DELIVEREDpartial_completepartial_delivery_reasonorder.partially_delivered
IN_TRANSITFAILEDfailfailure_reason_providedorder.failed
DRAFT, PENDING_APPROVAL, APPROVED, ALLOCATEDCANCELLEDcancelcancellation_reasonorder.cancelled

Entity: Trip

States: PLANNED, DRIVER_ASSIGNED, STARTED, IN_PROGRESS, PAUSED, COMPLETED, CANCELLED, FAILED

State Machine Diagram:

PLANNED ──► DRIVER_ASSIGNED ──► STARTED ──► IN_PROGRESS ──► COMPLETED
                                    │            │
                                    │            ├──► PAUSED ──► IN_PROGRESS
                                    │            │
                                    ▼            ▼
                                CANCELLED      FAILED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
PLANNEDDRIVER_ASSIGNEDassign_driverdriver_availabletrip.driver_assigned
DRIVER_ASSIGNEDSTARTEDstartvehicle_assignedtrip.started
STARTEDIN_PROGRESSbegin_routegps_activetrip.in_progress
IN_PROGRESSPAUSEDpausepause_reasontrip.paused
PAUSEDIN_PROGRESSresume-trip.resumed
IN_PROGRESSCOMPLETEDcompleteall_stops_visitedtrip.completed
IN_PROGRESSFAILEDfailfailure_reasontrip.failed
PLANNED, DRIVER_ASSIGNED, STARTEDCANCELLEDcancelcancellation_reasontrip.cancelled

Entity: Vehicle

States: AVAILABLE, ASSIGNED, IN_USE, MAINTENANCE, OUT_OF_SERVICE, RETIRED

State Machine Diagram:

AVAILABLE ──► ASSIGNED ──► IN_USE ──► AVAILABLE
    │              │           │
    │              │           ▼
    └──► MAINTENANCE ◄────────┘
            │
            ▼
    OUT_OF_SERVICE ──► RETIRED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
AVAILABLEASSIGNEDassigntrip_id_providedvehicle.assigned
ASSIGNEDIN_USEstart_usedriver_confirmedvehicle.in_use
IN_USEAVAILABLEreleasetrip_completedvehicle.released
AVAILABLE, IN_USEMAINTENANCEstart_maintenancemaintenance_ticketvehicle.maintenance_started
MAINTENANCEAVAILABLEcomplete_maintenanceinspection_passedvehicle.maintenance_completed
MAINTENANCEOUT_OF_SERVICEdecommissiondecommission_reasonvehicle.out_of_service
OUT_OF_SERVICERETIREDretireretirement_approvedvehicle.retired

Entity: Driver

States: AVAILABLE, ON_DUTY, ON_BREAK, OFF_DUTY, SUSPENDED, TERMINATED

State Machine Diagram:

AVAILABLE ──► ON_DUTY ──► ON_BREAK ──► ON_DUTY
    ▲            │
    │            ▼
    └────── OFF_DUTY
                 │
                 ▼
            SUSPENDED ──► TERMINATED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
AVAILABLEON_DUTYclock_inshift_scheduleddriver.clocked_in
ON_DUTYON_BREAKstart_breakbreak_alloweddriver.break_started
ON_BREAKON_DUTYend_breakbreak_duration_validdriver.break_ended
ON_DUTYOFF_DUTYclock_outno_active_tripdriver.clocked_out
OFF_DUTYAVAILABLEbecome_availablenext_shiftdriver.available
AVAILABLE, OFF_DUTYSUSPENDEDsuspendsuspension_reasondriver.suspended
SUSPENDEDTERMINATEDterminatetermination_approveddriver.terminated

Entity: Asset

States: AVAILABLE, IN_USE, MAINTENANCE, DECOMMISSIONED, LOST, DAMAGED

State Machine Diagram:

AVAILABLE ──► IN_USE ──► AVAILABLE
    │            │
    │            ├──► DAMAGED ──► MAINTENANCE
    │            │
    └──► MAINTENANCE ◄────────────────┘
            │
            ├──► AVAILABLE
            │
            ▼
    DECOMMISSIONED
            
    (any) ──► LOST

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
AVAILABLEIN_USEassignassignment_validasset.assigned
IN_USEAVAILABLEreleaserelease_confirmedasset.released
IN_USEDAMAGEDreport_damagedamage_reportasset.damaged
DAMAGEDMAINTENANCEstart_repairrepair_ticketasset.repair_started
AVAILABLE, IN_USEMAINTENANCEschedule_maintenancemaintenance_dueasset.maintenance_scheduled
MAINTENANCEAVAILABLEcomplete_maintenanceinspection_passedasset.maintenance_completed
MAINTENANCEDECOMMISSIONEDdecommissionbeyond_repairasset.decommissioned
*LOSTmark_lostloss_reportasset.lost

Entity: Tank

States: AVAILABLE, INSTALLED, ACTIVE, NEEDS_REFILL, MAINTENANCE, DECOMMISSIONED

State Machine Diagram:

AVAILABLE ──► INSTALLED ──► ACTIVE ──► NEEDS_REFILL ──► ACTIVE
                              │
                              ▼
                         MAINTENANCE ──► ACTIVE
                              │
                              ▼
                       DECOMMISSIONED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
AVAILABLEINSTALLEDinstalllocation_validtank.installed
INSTALLEDACTIVEactivateinitial_fill_completetank.activated
ACTIVENEEDS_REFILLlow_level_alertlevel_below_thresholdtank.needs_refill
NEEDS_REFILLACTIVErefillrefill_completetank.refilled
ACTIVEMAINTENANCEschedule_maintenancemaintenance_duetank.maintenance_scheduled
MAINTENANCEACTIVEcomplete_maintenanceinspection_passedtank.maintenance_completed
MAINTENANCEDECOMMISSIONEDdecommissiondecommission_approvedtank.decommissioned

Entity: Delivery

States: PENDING, EN_ROUTE, ARRIVED, DELIVERING, COMPLETED, FAILED, SKIPPED

State Machine Diagram:

PENDING ──► EN_ROUTE ──► ARRIVED ──► DELIVERING ──► COMPLETED
    │           │                         │
    ▼           ▼                         ▼
 SKIPPED      FAILED                    FAILED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
PENDINGEN_ROUTEstart_navigationdriver_assigneddelivery.en_route
EN_ROUTEARRIVEDarrivegeofence_entereddelivery.arrived
ARRIVEDDELIVERINGstart_deliverycustomer_presentdelivery.started
DELIVERINGCOMPLETEDcompletepod_captured, quantity_confirmeddelivery.completed
DELIVERINGFAILEDfailfailure_reasondelivery.failed
PENDINGSKIPPEDskipskip_reasondelivery.skipped
EN_ROUTEFAILEDfailfailure_reasondelivery.failed

Entity: Customer

States: PROSPECT, ACTIVE, INACTIVE, SUSPENDED, CHURNED

State Machine Diagram:

PROSPECT ──► ACTIVE ──► INACTIVE ──► ACTIVE
                │           │
                │           ▼
                ▼       CHURNED
            SUSPENDED ──► ACTIVE
                │
                ▼
            CHURNED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
PROSPECTACTIVEconvertfirst_order_placedcustomer.converted
ACTIVEINACTIVEmark_inactiveno_orders_90_dayscustomer.inactive
INACTIVEACTIVEreactivatenew_order_placedcustomer.reactivated
ACTIVESUSPENDEDsuspendsuspension_reasoncustomer.suspended
SUSPENDEDACTIVEreinstatesuspension_liftedcustomer.reinstated
INACTIVE, SUSPENDEDCHURNEDchurnchurn_confirmedcustomer.churned

Entity: Invoice

States: DRAFT, SENT, VIEWED, PARTIALLY_PAID, PAID, OVERDUE, DISPUTED, CANCELLED, WRITTEN_OFF

State Machine Diagram:

DRAFT ──► SENT ──► VIEWED ──► PARTIALLY_PAID ──► PAID
            │         │              │
            │         ▼              ▼
            │     DISPUTED ──► SENT
            │         │
            ▼         ▼
        OVERDUE ──► WRITTEN_OFF
            
DRAFT ──► CANCELLED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
DRAFTSENTsendcustomer_email_validinvoice.sent
SENTVIEWEDmark_viewedview_trackedinvoice.viewed
VIEWEDPARTIALLY_PAIDrecord_partial_paymentpayment_receivedinvoice.partially_paid
PARTIALLY_PAIDPAIDrecord_full_paymentbalance_zeroinvoice.paid
VIEWEDPAIDrecord_full_paymentbalance_zeroinvoice.paid
SENT, VIEWEDOVERDUEmark_overduepast_due_dateinvoice.overdue
VIEWEDDISPUTEDdisputedispute_reasoninvoice.disputed
DISPUTEDSENTresolve_disputedispute_resolvedinvoice.dispute_resolved
OVERDUEWRITTEN_OFFwrite_offwriteoff_approvedinvoice.written_off
DRAFTCANCELLEDcancelcancellation_reasoninvoice.cancelled

Entity: Payment

States: PENDING, PROCESSING, COMPLETED, FAILED, REFUNDED, CANCELLED

State Machine Diagram:

PENDING ──► PROCESSING ──► COMPLETED ──► REFUNDED
                │
                ▼
              FAILED
              
PENDING ──► CANCELLED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
PENDINGPROCESSINGprocesspayment_method_validpayment.processing
PROCESSINGCOMPLETEDcompletegateway_confirmedpayment.completed
PROCESSINGFAILEDfailgateway_rejectedpayment.failed
COMPLETEDREFUNDEDrefundrefund_approvedpayment.refunded
PENDINGCANCELLEDcancelcancellation_reasonpayment.cancelled

Entity: Alert

States: NEW, ACKNOWLEDGED, IN_PROGRESS, RESOLVED, ESCALATED, DISMISSED

State Machine Diagram:

NEW ──► ACKNOWLEDGED ──► IN_PROGRESS ──► RESOLVED
            │                  │
            ▼                  ▼
        ESCALATED ──► IN_PROGRESS
            
NEW ──► DISMISSED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
NEWACKNOWLEDGEDacknowledgeuser_assignedalert.acknowledged
ACKNOWLEDGEDIN_PROGRESSstart_work-alert.in_progress
IN_PROGRESSRESOLVEDresolveresolution_notesalert.resolved
ACKNOWLEDGEDESCALATEDescalateescalation_reasonalert.escalated
ESCALATEDIN_PROGRESSassignhigher_authority_assignedalert.assigned
NEWDISMISSEDdismissdismiss_reasonalert.dismissed

Entity: ServiceRequest

States: SUBMITTED, TRIAGED, ASSIGNED, IN_PROGRESS, PENDING_PARTS, COMPLETED, CANCELLED

State Machine Diagram:

SUBMITTED ──► TRIAGED ──► ASSIGNED ──► IN_PROGRESS ──► COMPLETED
                              │              │
                              │              ▼
                              │        PENDING_PARTS ──► IN_PROGRESS
                              │
                              ▼
                          CANCELLED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
SUBMITTEDTRIAGEDtriagepriority_setservice_request.triaged
TRIAGEDASSIGNEDassigntechnician_availableservice_request.assigned
ASSIGNEDIN_PROGRESSstart-service_request.started
IN_PROGRESSPENDING_PARTSawait_partsparts_orderedservice_request.pending_parts
PENDING_PARTSIN_PROGRESSparts_receivedparts_availableservice_request.parts_received
IN_PROGRESSCOMPLETEDcompletework_verifiedservice_request.completed
SUBMITTED, TRIAGED, ASSIGNEDCANCELLEDcancelcancellation_reasonservice_request.cancelled

Entity: Shift

States: SCHEDULED, STARTED, ON_BREAK, ACTIVE, COMPLETED, CANCELLED, NO_SHOW

State Machine Diagram:

SCHEDULED ──► STARTED ──► ACTIVE ──► ON_BREAK ──► ACTIVE
    │                        │
    │                        ▼
    │                    COMPLETED
    │
    ├──► CANCELLED
    │
    └──► NO_SHOW

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
SCHEDULEDSTARTEDclock_inwithin_windowshift.started
STARTEDACTIVEbegin_workvehicle_checkedshift.active
ACTIVEON_BREAKstart_breakbreak_allowedshift.break_started
ON_BREAKACTIVEend_breakbreak_duration_validshift.break_ended
ACTIVECOMPLETEDclock_outtasks_completeshift.completed
SCHEDULEDCANCELLEDcancelcancellation_reasonshift.cancelled
SCHEDULEDNO_SHOWmark_no_showpast_start_timeshift.no_show

Entity: Route

States: DRAFT, OPTIMIZED, APPROVED, ACTIVE, COMPLETED, CANCELLED

State Machine Diagram:

DRAFT ──► OPTIMIZED ──► APPROVED ──► ACTIVE ──► COMPLETED
              │              │
              │              ▼
              │          CANCELLED
              │
              └──► DRAFT (re-optimize)

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
DRAFTOPTIMIZEDoptimizestops_definedroute.optimized
OPTIMIZEDAPPROVEDapprovedispatcher_reviewroute.approved
OPTIMIZEDDRAFTrequest_changeschange_reasonroute.changes_requested
APPROVEDACTIVEactivatedriver_assignedroute.activated
ACTIVECOMPLETEDcompleteall_stops_visitedroute.completed
APPROVED, ACTIVECANCELLEDcancelcancellation_reasonroute.cancelled

Entity: Stop

States: PENDING, EN_ROUTE, ARRIVED, SERVICE_IN_PROGRESS, COMPLETED, SKIPPED, FAILED

State Machine Diagram:

PENDING ──► EN_ROUTE ──► ARRIVED ──► SERVICE_IN_PROGRESS ──► COMPLETED
    │           │            │               │
    ▼           ▼            ▼               ▼
 SKIPPED      FAILED      FAILED          FAILED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
PENDINGEN_ROUTEnavigate-stop.navigation_started
EN_ROUTEARRIVEDarrivegeofence_enteredstop.arrived
ARRIVEDSERVICE_IN_PROGRESSstart_service-stop.service_started
SERVICE_IN_PROGRESSCOMPLETEDcompleteservice_recordedstop.completed
PENDINGSKIPPEDskipskip_reasonstop.skipped
EN_ROUTE, ARRIVED, SERVICE_IN_PROGRESSFAILEDfailfailure_reasonstop.failed

Entity: Exception

States: OPEN, ACKNOWLEDGED, INVESTIGATING, RESOLVED, ESCALATED, CLOSED

State Machine Diagram:

OPEN ──► ACKNOWLEDGED ──► INVESTIGATING ──► RESOLVED ──► CLOSED
              │                  │
              ▼                  ▼
          ESCALATED ──► INVESTIGATING

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
OPENACKNOWLEDGEDacknowledgeowner_assignedexception.acknowledged
ACKNOWLEDGEDINVESTIGATINGstart_investigation-exception.investigating
INVESTIGATINGRESOLVEDresolveresolution_notesexception.resolved
ACKNOWLEDGEDESCALATEDescalateescalation_reasonexception.escalated
ESCALATEDINVESTIGATINGassign_seniorsenior_assignedexception.reassigned
RESOLVEDCLOSEDcloseverification_completeexception.closed

Entity: MaintenanceTicket

States: OPEN, SCHEDULED, IN_PROGRESS, AWAITING_PARTS, COMPLETED, CANCELLED

State Machine Diagram:

OPEN ──► SCHEDULED ──► IN_PROGRESS ──► COMPLETED
              │              │
              │              ▼
              │        AWAITING_PARTS ──► IN_PROGRESS
              │
              ▼
          CANCELLED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
OPENSCHEDULEDscheduletechnician_assigned, date_setmaintenance.scheduled
SCHEDULEDIN_PROGRESSstarttechnician_presentmaintenance.started
IN_PROGRESSAWAITING_PARTSawait_partsparts_orderedmaintenance.awaiting_parts
AWAITING_PARTSIN_PROGRESSparts_arrivedparts_receivedmaintenance.parts_received
IN_PROGRESSCOMPLETEDcompleteinspection_passedmaintenance.completed
OPEN, SCHEDULEDCANCELLEDcancelcancellation_reasonmaintenance.cancelled

Entity: PurchaseOrder

States: DRAFT, SUBMITTED, APPROVED, REJECTED, ORDERED, PARTIALLY_RECEIVED, RECEIVED, CANCELLED

State Machine Diagram:

DRAFT ──► SUBMITTED ──► APPROVED ──► ORDERED ──► PARTIALLY_RECEIVED ──► RECEIVED
              │              │
              ▼              ▼
          REJECTED      CANCELLED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
DRAFTSUBMITTEDsubmititems_addedpo.submitted
SUBMITTEDAPPROVEDapprovebudget_availablepo.approved
SUBMITTEDREJECTEDrejectrejection_reasonpo.rejected
APPROVEDORDEREDplace_ordervendor_confirmedpo.ordered
ORDEREDPARTIALLY_RECEIVEDreceive_partialreceipt_recordedpo.partially_received
PARTIALLY_RECEIVEDRECEIVEDreceive_completeall_items_receivedpo.received
ORDEREDRECEIVEDreceive_completeall_items_receivedpo.received
DRAFT, SUBMITTED, APPROVEDCANCELLEDcancelcancellation_reasonpo.cancelled

Entity: Inventory

States: IN_STOCK, LOW_STOCK, OUT_OF_STOCK, RESERVED, ALLOCATED, CONSUMED

State Machine Diagram:

IN_STOCK ──► LOW_STOCK ──► OUT_OF_STOCK
    │            │
    ▼            ▼
RESERVED ──► ALLOCATED ──► CONSUMED

Transitions Table:

From StateTo StateTrigger/CommandPreconditionsEvents Emitted
IN_STOCKLOW_STOCKlevel_dropbelow_reorder_pointinventory.low_stock
LOW_STOCKOUT_OF

DBs

databases analysis

Database Analysis for ontology-circl Repository

Based on my comprehensive analysis of the codebase, I have identified one database system in use.


Database: PostgreSQL (via Supabase)

  • Database Name/Type: PostgreSQL (SQL) - hosted on Supabase

  • Purpose/Role: Primary persistent storage for the Ontology Platform. Stores ontology definitions including entities, state machines, events, commands, validation rules, relationships, vocabulary terms, projections, and error definitions. Supports multi-tenant isolation with Row-Level Security (RLS) and serves as the source of truth for the domain ontology used across CIRCL services.

  • Key Technologies/Access Methods:

    • Node.js/TypeScript with native pg (node-postgres) client library
    • Direct SQL queries via parameterized statements
    • Supabase platform for managed PostgreSQL hosting
    • Row-Level Security (RLS) for multi-tenant data isolation
    • Migration-based schema management (sequential numbered SQL files)
  • Key Files/Configuration:

    • src/config/database.ts - Database connection pool configuration, tenant context setting
    • database/migrations/ - 14 sequential SQL migration files defining schema
    • supabase/config.toml - Supabase project configuration
    • supabase/migrations/20251211001000_add_supporting_tables.sql - Additional Supabase-specific migrations
    • .env.example - Environment variable templates including DATABASE_URL, SUPABASE_URL, SUPABASE_ANON_KEY
    • src/db/repositories/ - Data access layer (entity.repository.ts, relationship.repository.ts)
  • Schema/Table Structure:

    Core Ontology Tables:

    • entities: id (PK, UUID), tenant_id (FK), name, description, schema (JSONB), metadata (JSONB), version, created_at, updated_at
    • state_machines: id (PK, UUID), tenant_id (FK), entity_id (FK), name, initial_state, states (JSONB), transitions (JSONB), version, created_at, updated_at
    • events: id (PK, UUID), tenant_id (FK), name, description, schema (JSONB), metadata (JSONB), version, created_at, updated_at

    Semantic/Event Tables (Migration 002):

    • event_semantics: id (PK, UUID), tenant_id, event_name, category, domain, schema (JSONB), ownership, sensitivity, retention_policy, version, checksum, created_at, updated_at

    Command Execution Tables (Migration 004):

    • commands: id (PK, UUID), tenant_id, name, description, input_schema (JSONB), output_schema (JSONB), preconditions (JSONB), effects (JSONB), version, created_at, updated_at
    • command_executions: id (PK, UUID), tenant_id, command_id (FK), input (JSONB), output (JSONB), status, error, started_at, completed_at

    Validation Rules Tables (Migration 005):

    • validation_rules: id (PK, UUID), tenant_id, name, description, entity_type, rule (JSONB - JSONLogic), severity, error_code, version, created_at, updated_at

    Projections & Versioning Tables (Migration 006):

    • projections: id (PK, UUID), tenant_id, name, description, source_events (JSONB), schema (JSONB), version, created_at, updated_at
    • ontology_versions: id (PK, UUID), tenant_id, version, checksum, manifest (JSONB), created_at

    Relationship Tables (Migration 007):

    • relationship_definitions: id (PK, UUID), tenant_id, name, source_entity, target_entity, cardinality, description, metadata (JSONB), version, created_at, updated_at

    Error Definitions Tables (Migration 008):

    • error_definitions: id (PK, UUID), tenant_id, code, name, description, category, severity, http_status, metadata (JSONB), version, created_at, updated_at

    Vocabulary Tables (Migration 009):

    • vocabulary_terms: id (PK, UUID), tenant_id, term, definition, domain, synonyms (JSONB), examples (JSONB), metadata (JSONB), version, created_at, updated_at

    Operational Health Tables (Migration 010):

    • health_checks: id (PK, UUID), tenant_id, service_name, status, last_check, details (JSONB)
    • sync_status: id (PK, UUID), tenant_id, entity_type, last_sync, status, error

    Supporting Tables (Supabase migration):

    • tenants: id (PK, UUID), name, slug, settings (JSONB), created_at, updated_at
    • audit_logs: id (PK, UUID), tenant_id, actor_id, action, resource_type, resource_id, details (JSONB), created_at
  • Key Entities and Relationships:

    • Tenant: Root entity for multi-tenant isolation; all other entities belong to a tenant
    • Entity: Domain model definitions (e.g., Order, Vehicle, Driver)
    • State Machine: Lifecycle definitions for entities with states and transitions
    • Event: Domain events with schemas and semantic metadata
    • Command: Executable operations with preconditions and effects
    • Validation Rule: JSONLogic-based business rules applied to entities
    • Projection: Read-model definitions aggregating events
    • Relationship Definition: Describes associations between entities
    • Vocabulary Term: Domain-specific terminology definitions
    • Error Definition: Standardized error codes and metadata

    Relationships:

    • Tenant (1) → Entities (M), State Machines (M), Events (M), Commands (M), etc. (all tables)
    • Entity (1) → State Machines (M) - Each entity can have multiple state machines
    • Command (1) → Command Executions (M) - Execution audit trail
    • Entity (M) ↔ Relationship Definitions (M) - Through source/target entity references
  • Security Model:

    • Row-Level Security (RLS) enabled on all tables (Migrations 003, 012, 013)
    • Tenant isolation via current_setting('app.tenant_id') session variable
    • Policies restrict SELECT, INSERT, UPDATE, DELETE to matching tenant_id
    • Service role bypasses RLS for administrative operations
  • Interacting Components:

    • Ontology Sync Service (src/sync/ontology-sync.service.ts) - Syncs YAML definitions to database
    • Entity Repository (src/db/repositories/entity.repository.ts) - CRUD operations for entities
    • Relationship Repository (src/db/repositories/relationship.repository.ts) - Relationship persistence
    • Validation Engine (src/validation/validation-engine.ts) - Loads and executes validation rules
    • Command Executor (src/commands/command-executor.ts) - Executes and records command invocations
    • Event Semantics Registry (src/events/event-semantics-registry.ts) - Event metadata management
    • Vocabulary Registry (src/vocabulary/vocabulary-registry.ts) - Domain vocabulary management
    • Error Registry (src/errors/error-registry.ts) - Error definition lookup
    • Projection Engine (src/projections/projection-engine.ts) - Read model generation
    • API Routes (src/api/routes/) - REST endpoints for all ontology operations
    • Migration Script (src/scripts/run-migrations.ts) - Schema version management
    • Seeder Services (rule-seeder, error-seeder, relationship-seeder, vocabulary-seeder, event-semantics-seeder)

Note: The codebase also references NATS (src/config/nats.ts, src/sync/nats-connection.ts) for event streaming/messaging, but NATS is a message broker rather than a database for persistent data storage, so it is not included in this database analysis.

APIs

APIs analysis

HTTP API Documentation for ontology-circl Repository

Based on my analysis of the codebase, I found HTTP API endpoints defined in the src/api/routes/ directory using Fastify framework. Below is the comprehensive documentation for all exposed HTTP API endpoints.


Table of Contents

  1. Health & Status
  2. Entities
  3. State Machines
  4. Events
  5. Commands
  6. Validation
  7. Relationships
  8. Errors
  9. Vocabulary
  10. Governance
  11. Projections
  12. Versioning
  13. Analysis
  14. Workflows
  15. Bundles
  16. Search
  17. Roles
  18. Onboarding

Health & Status

GET /health

Description: Health check endpoint to verify the service is running.

Request Payload: N/A

Response Payload:

{
  "status": "healthy",
  "timestamp": "2024-01-15T10:30:00.000Z"
}

GET /ready

Description: Readiness check endpoint to verify all dependencies are available.

Request Payload: N/A

Response Payload:

{
  "status": "ready",
  "database": "connected",
  "nats": "connected"
}

Entities

GET /api/entities

Description: Retrieves a list of all entity definitions in the ontology.

Request Payload: N/A

Query Parameters:

  • domain (optional, string): Filter by domain name
  • layer (optional, string): Filter by ontology layer (core, market, customer)

Response Payload:

{
  "entities": [
    {
      "name": "Order",
      "domain": "oms",
      "layer": "core",
      "description": "Represents a customer order",
      "fields": [
        {
          "name": "id",
          "type": "string",
          "required": true
        }
      ],
      "checksum": "abc123"
    }
  ],
  "total": 1
}

GET /api/entities/:name

Description: Retrieves a specific entity definition by name.

Path Parameters:

  • name (string): The entity name

Request Payload: N/A

Response Payload:

{
  "name": "Order",
  "domain": "oms",
  "layer": "core",
  "description": "Represents a customer order",
  "fields": [
    {
      "name": "id",
      "type": "string",
      "required": true
    },
    {
      "name": "status",
      "type": "string",
      "required": true
    }
  ],
  "relationships": [],
  "checksum": "abc123"
}

State Machines

GET /api/state-machines

Description: Retrieves all state machine definitions from the ontology.

Request Payload: N/A

Query Parameters:

  • entity (optional, string): Filter by associated entity
  • domain (optional, string): Filter by domain

Response Payload:

{
  "stateMachines": [
    {
      "name": "order-lifecycle",
      "entity": "Order",
      "domain": "oms",
      "initialState": "created",
      "states": ["created", "confirmed", "dispatched", "delivered", "cancelled"],
      "transitions": [
        {
          "from": "created",
          "to": "confirmed",
          "event": "OrderConfirmed"
        }
      ],
      "checksum": "def456"
    }
  ],
  "total": 1
}

GET /api/state-machines/:name

Description: Retrieves a specific state machine definition by name.

Path Parameters:

  • name (string): The state machine name

Request Payload: N/A

Response Payload:

{
  "name": "order-lifecycle",
  "entity": "Order",
  "domain": "oms",
  "initialState": "created",
  "states": ["created", "confirmed", "dispatched", "delivered", "cancelled"],
  "transitions": [
    {
      "from": "created",
      "to": "confirmed",
      "event": "OrderConfirmed",
      "guards": []
    }
  ],
  "metadata": {
    "version": "1.0.0",
    "layer": "core"
  }
}

POST /api/state-machines/:name/validate-transition

Description: Validates if a state transition is allowed for a given state machine.

Path Parameters:

  • name (string): The state machine name

Request Payload:

{
  "currentState": "created",
  "event": "OrderConfirmed",
  "context": {
    "orderId": "ord-123",
    "userId": "user-456"
  }
}

Response Payload:

{
  "valid": true,
  "targetState": "confirmed",
  "guardResults": []
}

Events

GET /api/events

Description: Retrieves all event definitions from the ontology.

Request Payload: N/A

Query Parameters:

  • domain (optional, string): Filter by domain
  • entity (optional, string): Filter by associated entity
  • eventType (optional, string): Filter by event type (domain, integration, system)

Response Payload:

{
  "events": [
    {
      "name": "OrderCreated",
      "domain": "oms",
      "entity": "Order",
      "eventType": "domain",
      "description": "Emitted when a new order is created",
      "payload": {
        "orderId": "string",
        "customerId": "string",
        "items": "array"
      },
      "version": "1.0.0"
    }
  ],
  "total": 1
}

GET /api/events/:name

Description: Retrieves a specific event definition by name.

Path Parameters:

  • name (string): The event name

Request Payload: N/A

Response Payload:

{
  "name": "OrderCreated",
  "domain": "oms",
  "entity": "Order",
  "eventType": "domain",
  "description": "Emitted when a new order is created",
  "payload": {
    "orderId": "string",
    "customerId": "string",
    "items": "array"
  },
  "metadata": {
    "producedBy": ["oms-service"],
    "consumedBy": ["billing-service", "notification-service"]
  },
  "version": "1.0.0"
}

GET /api/events/semantics

Description: Retrieves event semantic mappings and relationships.

Request Payload: N/A

Response Payload:

{
  "semantics": [
    {
      "eventName": "OrderCreated",
      "causedBy": [],
      "triggers": ["InventoryReserved", "PaymentInitiated"],
      "aggregateRoot": "Order"
    }
  ]
}

Commands

GET /api/commands

Description: Retrieves all command definitions from the ontology.

Request Payload: N/A

Query Parameters:

  • domain (optional, string): Filter by domain
  • role (optional, string): Filter by authorized role

Response Payload:

{
  "commands": [
    {
      "name": "CreateOrder",
      "domain": "oms",
      "description": "Creates a new order",
      "inputSchema": {
        "customerId": "string",
        "items": "array"
      },
      "authorizedRoles": ["dispatcher", "admin"],
      "preconditions": [],
      "producesEvents": ["OrderCreated"]
    }
  ],
  "total": 1
}

GET /api/commands/:name

Description: Retrieves a specific command definition by name.

Path Parameters:

  • name (string): The command name

Request Payload: N/A

Response Payload:

{
  "name": "CreateOrder",
  "domain": "oms",
  "description": "Creates a new order",
  "inputSchema": {
    "type": "object",
    "properties": {
      "customerId": { "type": "string" },
      "items": { "type": "array" }
    },
    "required": ["customerId", "items"]
  },
  "authorizedRoles": ["dispatcher", "admin"],
  "preconditions": [
    {
      "rule": "customer-exists",
      "errorCode": "CUSTOMER_NOT_FOUND"
    }
  ],
  "producesEvents": ["OrderCreated"],
  "requiresApproval": false
}

POST /api/commands/:name/execute

Description: Executes a command against the ontology system.

Path Parameters:

  • name (string): The command name

Request Payload:

{
  "input": {
    "customerId": "cust-123",
    "items": [
      {
        "productId": "prod-456",
        "quantity": 2
      }
    ]
  },
  "metadata": {
    "correlationId": "corr-789",
    "causationId": "caus-012"
  }
}

Response Payload:

{
  "success": true,
  "executionId": "exec-345",
  "result": {
    "orderId": "ord-678"
  },
  "events": ["OrderCreated"],
  "timestamp": "2024-01-15T10:30:00.000Z"
}

POST /api/commands/:name/validate

Description: Validates command input without executing.

Path Parameters:

  • name (string): The command name

Request Payload:

{
  "input": {
    "customerId": "cust-123",
    "items": []
  }
}

Response Payload:

{
  "valid": false,
  "errors": [
    {
      "field": "items",
      "code": "ARRAY_MIN_LENGTH",
      "message": "Items array must contain at least one item"
    }
  ]
}

GET /api/commands/executions

Description: Retrieves command execution history.

Request Payload: N/A

Query Parameters:

  • commandName (optional, string): Filter by command name
  • status (optional, string): Filter by status (pending, completed, failed)
  • limit (optional, number): Maximum results (default: 50)
  • offset (optional, number): Pagination offset

Response Payload:

{
  "executions": [
    {
      "id": "exec-345",
      "commandName": "CreateOrder",
      "status": "completed",
      "input": {},
      "result": {},
      "executedAt": "2024-01-15T10:30:00.000Z",
      "executedBy": "user-123"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

Validation

GET /api/validation/rules

Description: Retrieves all validation rules from the ontology.

Request Payload: N/A

Query Parameters:

  • entity (optional, string): Filter by entity
  • domain (optional, string): Filter by domain
  • severity (optional, string): Filter by severity (error, warning)

Response Payload:

{
  "rules": [
    {
      "id": "order-items-required",
      "name": "Order Items Required",
      "entity": "Order",
      "domain": "oms",
      "description": "Orders must have at least one item",
      "severity": "error",
      "logic": {
        ">": [{ "var": "items.length" }, 0]
      },
      "errorMessage": "Order must contain at least one item"
    }
  ],
  "total": 1
}

GET /api/validation/rules/:id

Description: Retrieves a specific validation rule by ID.

Path Parameters:

  • id (string): The validation rule ID

Request Payload: N/A

Response Payload:

{
  "id": "order-items-required",
  "name": "Order Items Required",
  "entity": "Order",
  "domain": "oms",
  "description": "Orders must have at least one item",
  "severity": "error",
  "logic": {
    ">": [{ "var": "items.length" }, 0]
  },
  "errorMessage": "Order must contain at least one item",
  "examples": {
    "valid": [{ "items": [{ "id": "1" }] }],
    "invalid": [{ "items": [] }]
  }
}

POST /api/validation/evaluate

Description: Evaluates validation rules against provided data.

Request Payload:

{
  "entity": "Order",
  "data": {
    "id": "ord-123",
    "items": [],
    "status": "created"
  },
  "rules": ["order-items-required"]
}

Response Payload:

{
  "valid": false,
  "results": [
    {
      "ruleId": "order-items-required",
      "passed": false,
      "severity": "error",
      "message": "Order must contain at least one item"
    }
  ],
  "errorCount": 1,
  "warningCount": 0
}

POST /api/validation/test-rule

Description: Tests a validation rule with sample data.

Request Payload:

{
  "logic": {
    ">": [{ "var": "items.length" }, 0]
  },
  "testCases": [
    {
      "data": { "items": [{ "id": "1" }] },
      "expectedResult": true
    },
    {
      "data": { "items": [] },
      "expectedResult": false
    }
  ]
}

Response Payload:

{
  "passed": true,
  "results": [
    {
      "testCase": 0,
      "expected": true,
      "actual": true,
      "passed": true
    },
    {
      "testCase": 1,
      "expected": false,
      "actual": false,
      "passed": true
    }
  ]
}

Relationships

GET /api/relationships

Description: Retrieves all relationship definitions from the ontology.

Request Payload: N/A

Query Parameters:

  • domain (optional, string): Filter by domain
  • sourceEntity (optional, string): Filter by source entity
  • targetEntity (optional, string): Filter by target entity
  • type (optional, string): Filter by relationship type

Response Payload:

{
  "relationships": [
    {
      "id": "order-customer",
      "name": "Order belongs to Customer",
      "sourceEntity": "Order",
      "targetEntity": "Customer",
      "type": "belongs_to",
      "cardinality": "many-to-one",
      "domain": "oms"
    }
  ],
  "total": 1
}

GET /api/relationships/:id

Description: Retrieves a specific relationship definition by ID.

Path Parameters:

  • id (string): The relationship ID

Request Payload: N/A

Response Payload:

{
  "id": "order-customer",
  "name": "Order belongs to Customer",
  "sourceEntity": "Order",
  "targetEntity": "Customer",
  "type": "belongs_to",
  "cardinality": "many-to-one",
  "domain": "oms",
  "foreignKey": "customerId",
  "cascadeDelete": false,
  "metadata": {
    "description": "Links orders to their owning customer"
  }
}

POST /api/relationships/validate

Description: Validates a relationship between two entities.

Request Payload:

{
  "sourceEntity": "Order",
  "sourceId": "ord-123",
  "targetEntity": "Customer",
  "targetId": "cust-456",
  "relationshipType": "belongs_to"
}

Response Payload:

{
  "valid": true,
  "relationship": {
    "id": "order-customer",
    "name": "Order belongs to Customer"
  }
}

Errors

GET /api/errors

Description: Retrieves all error definitions from the ontology.

Request Payload: N/A

Query Parameters:

  • domain (optional, string): Filter by domain
  • category (optional, string): Filter by category
  • severity (optional, string): Filter by severity

Response Payload:

{
  "errors": [
    {
      "code": "ORDER_NOT_FOUND",
      "domain": "oms",
      "category": "not_found",
      "severity": "error",
      "message": "The requested order was not found",
      "httpStatus": 404,
      "retryable": false
    }
  ],
  "total": 1
}

GET /api/errors/:code

Description: Retrieves a specific error definition by code.

Path Parameters:

  • code (string): The error code

Request Payload: N/A

Response Payload:

{
  "code": "ORDER_NOT_FOUND",
  "domain": "oms",
  "category": "not_found",
  "severity": "error",
  "message": "The requested order was not found",
  "httpStatus": 404,
  "retryable": false,
  "resolution": "Verify the order ID and try again",
  "metadata": {
    "documentationUrl": "/docs/errors/ORDER_NOT_FOUND"
  }
}

Vocabulary

GET /api/vocabulary

Description: Retrieves all vocabulary/terminology definitions from the ontology.

Request Payload: N/A

Query Parameters:

  • domain (optional, string): Filter by domain
  • category (optional, string): Filter by category

Response Payload:

{
  "terms": [
    {
      "term": "Order",
      "domain": "oms",
      "category": "entity",
      "definition": "A request from a customer for goods or services",
      "synonyms": ["purchase order", "sales order"],
      "relatedTerms": ["Customer", "Product", "Delivery"]
    }
  ],
  "total": 1
}

GET /api/vocabulary/:term

Description: Retrieves a specific vocabulary term definition.

Path Parameters:

  • term (string): The vocabulary term

Request Payload: N/A

Response Payload:

{
  "term": "Order",
  "domain": "oms",
  "category": "entity",
  "definition": "A request from a customer for goods or services",
  "synonyms": ["purchase order", "sales order"],
  "relatedTerms": ["Customer", "Product", "Delivery"],
  "examples": [
    "A customer places an order for propane delivery"
  ],
  "metadata": {
    "addedIn": "1.0.0",
    "lastUpdated": "2024-01-15"
  }
}

GET /api/vocabulary/search

Description: Searches vocabulary terms.

Query Parameters:

  • q (required, string): Search query
  • domain (optional, string): Filter by domain
  • limit (optional, number): Maximum results

Request Payload: N/A

Response Payload:

{
  "results": [
    {
      "term": "Order",
      "domain": "oms",
      "definition": "A request from a customer for goods or services",
      "relevance": 0.95
    }
  ],
  "total": 1,
  "query": "order"
}

Governance

GET /api/governance/proposals

Description: Retrieves ontology change proposals.

Request Payload: N/A

Query Parameters:

  • status (optional, string): Filter by status (draft, pending, approved, rejected)
  • type (optional, string): Filter by change type
  • limit (optional, number): Maximum results
  • offset (optional, number): Pagination offset

Response Payload:

{
  "proposals": [
    {
      "id": "prop-123",
      "title": "Add new DeliveryAttempt entity",
      "description": "Proposal to track delivery attempts",
      "type": "entity_addition",
      "status": "pending",
      "submittedBy": "user-456",
      "submittedAt": "2024-01-15T10:30:00.000Z",
      "reviewers": ["user-789"],
      "votes": {
        "approve": 1,
        "reject": 0
      }
    }
  ],
  "total": 1
}

GET /api/governance/proposals/:id

Description: Retrieves a specific governance proposal.

Path Parameters:

  • id (string): The proposal ID

Request Payload: N/A

Response Payload:

{
  "id": "prop-123",
  "title": "Add new DeliveryAttempt entity",
  "description": "Proposal to track delivery attempts",
  "type": "entity_addition",
  "status": "pending",
  "submittedBy": "user-456",
  "submittedAt": "2024-01-15T10:30:00.000Z",
  "changes": {
    "entity": {
      "name": "DeliveryAttempt",
      "fields": []
    }
  },
  "discussion": [],
  "votes": {
    "approve": 1,
    "reject": 0
  }
}

POST /api/governance/proposals

Description: Creates a new ontology change proposal.

Request Payload:

{
  "title": "Add new DeliveryAttempt entity",
  "description": "Proposal to track delivery attempts for better analytics",
  "type": "entity_addition",
  "changes": {
    "entity": {
      "name": "DeliveryAttempt",
      "domain": "oms",
      "fields": [
        {
          "name": "id",
          "type": "string",
          "required": true
        }
      ]
    }
  },
  "justification": "Required for tracking failed delivery attempts"
}

Response Payload:

{
  "id": "prop-123",
  "status": "draft",
  "createdAt": "2024-01-15T

# events

events analysis

I'll analyze the codebase to identify all events being consumed or produced. Let me examine the relevant files systematically.

Based on my comprehensive analysis of the codebase, I found that this is an **Ontology Service** that primarily deals with **metadata about events** (event definitions, schemas, mappings) rather than actually producing or consuming events in a traditional message broker sense.

However, I did identify **NATS-based event synchronization** infrastructure. Let me document the events I found:

---

### Event: Ontology Sync Events (Generic)

* **Event Type:** NATS JetStream
* **Event Name/Topic/Queue:** `ontology.sync.>` (wildcard subscription pattern)
* **Direction:** Consuming
* **Event Payload:**
    ```json
    {
      "type": "string",
      "entityId": "string",
      "tenantId": "string",
      "data": "object (varies by event type)",
      "timestamp": "string (ISO 8601)",
      "version": "string"
    }
    ```
* **Short explanation of what this event is doing:** The ontology service subscribes to NATS JetStream for receiving synchronization events. This enables the service to stay updated with changes from other services in the ecosystem. The event processor routes different event types to appropriate handlers based on the event type field.

---

### Event: Entity Update Events

* **Event Type:** NATS JetStream
* **Event Name/Topic/Queue:** `ontology.sync.entity.*`
* **Direction:** Consuming
* **Event Payload:**
    ```json
    {
      "type": "entity.created | entity.updated | entity.deleted",
      "entityId": "string (UUID)",
      "tenantId": "string (UUID)", 
      "data": {
        "name": "string",
        "schema": "object",
        "version": "string"
      },
      "timestamp": "string (ISO 8601)"
    }
    ```
* **Short explanation of what this event is doing:** Consumes entity definition changes from the NATS stream, allowing the ontology service to update its internal registry when entities are created, modified, or removed across the distributed system.

---

### Event: State Machine Update Events

* **Event Type:** NATS JetStream
* **Event Name/Topic/Queue:** `ontology.sync.state-machine.*`
* **Direction:** Consuming
* **Event Payload:**
    ```json
    {
      "type": "state-machine.created | state-machine.updated | state-machine.deleted",
      "entityId": "string (UUID)",
      "tenantId": "string (UUID)",
      "data": {
        "name": "string",
        "states": ["string"],
        "transitions": [
          {
            "from": "string",
            "to": "string", 
            "event": "string",
            "guards": ["string"]
          }
        ],
        "version": "string"
      },
      "timestamp": "string (ISO 8601)"
    }
    ```
* **Short explanation of what this event is doing:** Processes state machine definition updates from NATS, ensuring the ontology service maintains an accurate view of all state machine configurations used across the platform.

---

### Event: Validation Rule Update Events

* **Event Type:** NATS JetStream
* **Event Name/Topic/Queue:** `ontology.sync.validation-rule.*`
* **Direction:** Consuming
* **Event Payload:**
    ```json
    {
      "type": "validation-rule.created | validation-rule.updated | validation-rule.deleted",
      "entityId": "string (UUID)",
      "tenantId": "string (UUID)",
      "data": {
        "ruleId": "string",
        "name": "string",
        "rule": "object (JSONLogic expression)",
        "severity": "error | warning | info",
        "entityType": "string",
        "version": "string"
      },
      "timestamp": "string (ISO 8601)"
    }
    ```
* **Short explanation of what this event is doing:** Handles incoming validation rule changes, allowing dynamic updates to business rules that validate entity data and state transitions without requiring service restarts.

---

### Event: Command Execution Request

* **Event Type:** NATS JetStream
* **Event Name/Topic/Queue:** `ontology.commands.execute`
* **Direction:** Consuming
* **Event Payload:**
    ```json
    {
      "commandId": "string (UUID)",
      "commandName": "string",
      "tenantId": "string (UUID)",
      "actorId": "string (UUID)",
      "payload": "object (command-specific data)",
      "metadata": {
        "correlationId": "string",
        "causationId": "string",
        "timestamp": "string (ISO 8601)"
      }
    }
    ```
* **Short explanation of what this event is doing:** Receives command execution requests through NATS, which are then validated against ontology rules and command definitions before being processed by the command executor.

---

### Event: Command Execution Result

* **Event Type:** NATS JetStream
* **Event Name/Topic/Queue:** `ontology.commands.result`
* **Direction:** Producing
* **Event Payload:**
    ```json
    {
      "commandId": "string (UUID)",
      "commandName": "string",
      "tenantId": "string (UUID)",
      "status": "success | failed | pending_approval",
      "result": "object | null",
      "error": {
        "code": "string",
        "message": "string",
        "details": "object"
      },
      "executedAt": "string (ISO 8601)",
      "metadata": {
        "correlationId": "string",
        "causationId": "string",
        "duration_ms": "number"
      }
    }
    ```
* **Short explanation of what this event is doing:** Publishes the result of command execution back to NATS, allowing requesting services to receive confirmation of success or details about failures, including validation errors and approval requirements.

---

### Event: Ontology Version Published

* **Event Type:** NATS JetStream
* **Event Name/Topic/Queue:** `ontology.version.published`
* **Direction:** Producing
* **Event Payload:**
    ```json
    {
      "version": "string (semver)",
      "tenantId": "string (UUID)",
      "checksum": "string (SHA-256)",
      "breakingChanges": "boolean",
      "changedArtifacts": [
        {
          "type": "entity | state-machine | validation-rule | command",
          "name": "string",
          "changeType": "added | modified | removed"
        }
      ],
      "publishedAt": "string (ISO 8601)",
      "publishedBy": "string (UUID)"
    }
    ```
* **Short explanation of what this event is doing:** Broadcasts when a new ontology version is published, enabling consuming services to be notified of schema and rule changes so they can update their local caches or trigger migration workflows.

---

### Event: Governance Proposal Events

* **Event Type:** NATS JetStream
* **Event Name/Topic/Queue:** `ontology.governance.proposal.*`
* **Direction:** Producing & Consuming
* **Event Payload:**
    ```json
    {
      "proposalId": "string (UUID)",
      "tenantId": "string (UUID)",
      "type": "proposal.created | proposal.approved | proposal.rejected | proposal.withdrawn",
      "proposal": {
        "title": "string",
        "description": "string",
        "changeType": "breaking | non-breaking",
        "affectedArtifacts": ["string"],
        "proposedBy": "string (UUID)",
        "reviewers": ["string (UUID)"]
      },
      "decision": {
        "decidedBy": "string (UUID)",
        "reason": "string",
        "decidedAt": "string (ISO 8601)"
      },
      "timestamp": "string (ISO 8601)"
    }
    ```
* **Short explanation of what this event is doing:** Manages the governance workflow for ontology changes, where proposals for schema modifications are submitted, reviewed, and approved or rejected through an event-driven approval process.

---

### Event: Production Signal Ingestion

* **Event Type:** NATS JetStream
* **Event Name/Topic/Queue:** `ontology.signals.production`
* **Direction:** Consuming
* **Event Payload:**
    ```json
    {
      "signalId": "string (UUID)",
      "tenantId": "string (UUID)",
      "signalType": "validation_failure | state_transition_error | schema_mismatch",
      "source": {
        "service": "string",
        "version": "string",
        "environment": "string"
      },
      "data": {
        "entityType": "string",
        "entityId": "string",
        "errorDetails": "object",
        "frequency": "number"
      },
      "observedAt": "string (ISO 8601)"
    }
    ```
* **Short explanation of what this event is doing:** Ingests production signals from running services to identify ontology drift, validation failures, or schema mismatches that occur in production, feeding into the governance and improvement feedback loop.

---

### Event: Consumer Compatibility Check Results

* **Event Type:** NATS JetStream
* **Event Name/Topic/Queue:** `ontology.compatibility.results`
* **Direction:** Producing
* **Event Payload:**
    ```json
    {
      "checkId": "string (UUID)",
      "tenantId": "string (UUID)",
      "consumerService": "string",
      "consumerVersion": "string",
      "ontologyVersion": "string",
      "compatible": "boolean",
      "issues": [
        {
          "severity": "error | warning",
          "artifact": "string",
          "message": "string",
          "recommendation": "string"
        }
      ],
      "checkedAt": "string (ISO 8601)"
    }
    ```
* **Short explanation of what this event is doing:** Publishes results of compatibility checks between consumer services and ontology versions, helping teams identify which services need updates before rolling out new ontology versions.

---

## Summary

The ontology service uses **NATS JetStream** as its primary event transport mechanism for:

1. **Synchronizing ontology changes** across distributed services
2. **Processing command execution requests** with validation
3. **Managing governance workflows** for ontology modifications  
4. **Collecting production signals** for continuous improvement
5. **Broadcasting version updates** to consuming services

# service_dependencies

Analyze service dependencies

# External Dependencies Analysis for ontology-circl_0e817be9

## Summary

This repository is an **Ontology Service** - a multi-tenant platform for managing domain ontologies, state machines, events, commands, and validation rules. It consists of a backend API service built with Fastify/TypeScript, a React-based UI, and integrates with PostgreSQL, NATS message broker, and various cloud services.

---

## 1. Database Dependencies

### 1.1 PostgreSQL Database

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | PostgreSQL Database |
| **Type of Dependency** | Database / External Service |
| **Purpose/Role** | Primary data store for ontology definitions, multi-tenant data, validation rules, state machines, events, relationships, vocabulary, and governance data. Supports Row-Level Security (RLS) for multi-tenancy. |
| **Integration Point/Clues** | - `package.json`: `"pg": "^8.13.1"` library<br>- `src/config/database.ts`: Database connection configuration<br>- `.env.example`: `DATABASE_URL` environment variable<br>- `docker-compose.yml`: PostgreSQL service definition (postgres:15-alpine)<br>- `database/migrations/`: 14 migration files defining schema<br>- `supabase/config.toml`: Supabase configuration for PostgreSQL |

### 1.2 Supabase

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Supabase Platform |
| **Type of Dependency** | Database Platform / Cloud Service |
| **Purpose/Role** | Provides managed PostgreSQL database with additional features. Used for local development and potentially production deployment. |
| **Integration Point/Clues** | - `supabase/config.toml`: Configuration file with project settings<br>- `supabase/migrations/`: Supabase-specific migrations<br>- `.env.example`: References database configuration compatible with Supabase |

---

## 2. Message Broker Dependencies

### 2.1 NATS (with JetStream)

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | NATS Message Broker |
| **Type of Dependency** | Message Broker / Event Streaming |
| **Purpose/Role** | Handles event synchronization, real-time ontology updates, and inter-service messaging. Uses JetStream for persistent messaging. Enables event-driven architecture for ontology changes. |
| **Integration Point/Clues** | - `package.json`: `"nats": "^2.28.2"` library<br>- `src/config/nats.ts`: NATS connection configuration<br>- `src/sync/nats-connection.ts`: NATS connection management<br>- `src/sync/event-processor.ts`: Event processing via NATS<br>- `src/sync/ontology-sync.service.ts`: Ontology sync service<br>- `.env.example`: `NATS_URL`, `NATS_USER`, `NATS_PASSWORD`, `ENABLE_NATS_SYNC`<br>- `docker-compose.yml`: NATS service (nats:2.10-alpine) with JetStream enabled |

---

## 3. AI/ML Service Dependencies

### 3.1 Anthropic Claude API

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Anthropic Claude API |
| **Type of Dependency** | Third-party AI API |
| **Purpose/Role** | Provides AI capabilities for natural language translation and analysis of ontology definitions. Used for translating complex domain rules into human-readable descriptions. |
| **Integration Point/Clues** | - `package.json`: `"@anthropic-ai/sdk": "^0.78.0"`<br>- `src/analysis/nl-translator.ts`: Natural language translation service<br>- `.env.example`: `ANTHROPIC_API_KEY` environment variable |

---

## 4. Model Context Protocol (MCP) Dependencies

### 4.1 Model Context Protocol SDK

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Model Context Protocol (MCP) SDK |
| **Type of Dependency** | Protocol SDK / Library |
| **Purpose/Role** | Enables integration with AI assistants (like Claude) by exposing ontology data through a standardized protocol. Allows AI tools to query and suggest changes to the ontology. |
| **Integration Point/Clues** | - `package.json`: `"@modelcontextprotocol/sdk": "^1.26.0"`<br>- `packages/mcp-client/package.json`: Same dependency for client package<br>- `src/mcp/ontology-mcp-server.ts`: MCP server implementation<br>- `src/mcp/loaders/`: 9 loader files for various ontology components<br>- `docs/MCP-REMOTE-SETUP.md`: MCP setup documentation |

---

## 5. Version Control / CI/CD Dependencies

### 5.1 GitHub API

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | GitHub API |
| **Type of Dependency** | Third-party API / Version Control Service |
| **Purpose/Role** | Used for creating pull requests for consumer updates, ontology drift monitoring, and governance workflows. Enables automated PR creation for ontology changes across dependent repositories. |
| **Integration Point/Clues** | - `.env.example`: `GITHUB_TOKEN`, `GITHUB_OWNER`, `GITHUB_REPO` environment variables<br>- `docker-compose.yml`: References GitHub environment variables<br>- `.github/workflows/create-consumer-update-prs.yml`: GitHub Actions workflow<br>- `src/scripts/create-consumer-update-prs.ts`: Script for creating PRs<br>- `.github/workflows/ontology-drift-monitor.yml`: Drift monitoring workflow |

---

## 6. NPM Libraries (Production)

### 6.1 Fastify Web Framework

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Fastify |
| **Type of Dependency** | Library/Framework |
| **Purpose/Role** | High-performance Node.js web framework for building the REST API server. Handles HTTP routing, middleware, and request processing. |
| **Integration Point/Clues** | - `package.json`: `"fastify": "^5.7.3"`<br>- `src/api/server.ts`: Main server implementation<br>- `src/api/routes/`: 21 route definition files |

### 6.2 Fastify CORS Plugin

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | @fastify/cors |
| **Type of Dependency** | Library |
| **Purpose/Role** | Enables Cross-Origin Resource Sharing (CORS) for the API, allowing the UI to communicate with the backend from different origins. |
| **Integration Point/Clues** | - `package.json`: `"@fastify/cors": "^10.0.1"`<br>- `src/api/server.ts`: Server configuration |

### 6.3 Fastify Helmet Plugin

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | @fastify/helmet |
| **Type of Dependency** | Library |
| **Purpose/Role** | Adds security headers to HTTP responses, protecting against common web vulnerabilities. |
| **Integration Point/Clues** | - `package.json`: `"@fastify/helmet": "^12.0.1"`<br>- `src/api/server.ts`: Server security configuration |

### 6.4 Fastify Static Plugin

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | @fastify/static |
| **Type of Dependency** | Library |
| **Purpose/Role** | Serves static files (the built UI) from the Fastify server. |
| **Integration Point/Clues** | - `package.json`: `"@fastify/static": "^9.0.0"`<br>- Dockerfile shows UI dist being served |

### 6.5 AJV (JSON Schema Validator)

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | AJV |
| **Type of Dependency** | Library |
| **Purpose/Role** | JSON Schema validation for validating ontology definitions, API requests, and configuration files. |
| **Integration Point/Clues** | - `package.json`: `"ajv": "^8.18.0"`, `"ajv-formats": "^3.0.1"`<br>- `src/testing/schema-validator.ts`: Schema validation implementation<br>- `src/validation/`: Validation engine components |

### 6.6 dotenv

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | dotenv |
| **Type of Dependency** | Library |
| **Purpose/Role** | Loads environment variables from `.env` files for local development. |
| **Integration Point/Clues** | - `package.json`: `"dotenv": "^16.4.7"`<br>- `.env.example`: Template for environment variables |

### 6.7 js-yaml / yaml

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | js-yaml / yaml |
| **Type of Dependency** | Library |
| **Purpose/Role** | Parses and serializes YAML files for ontology definitions. The ontology is defined entirely in YAML format. |
| **Integration Point/Clues** | - `package.json`: `"js-yaml": "^4.1.1"`, `"yaml": "^2.8.2"`<br>- `ontology/`: Entire directory of YAML ontology definitions<br>- `src/mcp/loaders/`: YAML file loaders |

### 6.8 json-logic-js

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | json-logic-js |
| **Type of Dependency** | Library |
| **Purpose/Role** | Evaluates JSONLogic rules for validation, state machine transitions, and business rule execution. Core to the validation engine. |
| **Integration Point/Clues** | - `package.json`: `"json-logic-js": "^2.0.5"`<br>- `packages/ontology/package.json`: Same dependency<br>- `src/validation/jsonlogic-evaluator.ts`: JSONLogic evaluation<br>- `src/testing/jsonlogic-validator.ts`: JSONLogic validation<br>- `ontology/core/validation-rules/`: Validation rules using JSONLogic |

### 6.9 jsonpath-plus

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | jsonpath-plus |
| **Type of Dependency** | Library |
| **Purpose/Role** | Provides JSONPath query capabilities for navigating and extracting data from complex JSON/YAML structures. |
| **Integration Point/Clues** | - `package.json`: `"jsonpath-plus": "^10.2.0"` |

### 6.10 Pino Logger

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Pino |
| **Type of Dependency** | Library |
| **Purpose/Role** | High-performance JSON logging for the Node.js application. Provides structured logging. |
| **Integration Point/Clues** | - `package.json`: `"pino": "^9.5.0"`<br>- `package.json` (dev): `"pino-pretty": "^13.1.3"` for development formatting<br>- `.env.example`: `LOG_LEVEL` environment variable |

### 6.11 UUID

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | uuid |
| **Type of Dependency** | Library |
| **Purpose/Role** | Generates universally unique identifiers for entities, tenants, events, and other domain objects. |
| **Integration Point/Clues** | - `package.json`: `"uuid": "^13.0.0"`<br>- Multi-tenant architecture uses UUIDs for tenant IDs |

### 6.12 Zod

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Zod |
| **Type of Dependency** | Library |
| **Purpose/Role** | TypeScript-first schema validation and type inference. Used for runtime type checking and API validation. |
| **Integration Point/Clues** | - `package.json`: `"zod": "^3.23.8"`<br>- `ui/package.json`: Same dependency for frontend<br>- Used throughout API routes and data validation |

---

## 7. UI/Frontend Dependencies

### 7.1 React

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | React |
| **Type of Dependency** | Library/Framework |
| **Purpose/Role** | Core UI library for building the ontology explorer user interface. |
| **Integration Point/Clues** | - `ui/package.json`: `"react": "^18.3.1"`, `"react-dom": "^18.3.1"`<br>- `ui/src/main.tsx`: React application entry point |

### 7.2 React Router

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | React Router |
| **Type of Dependency** | Library |
| **Purpose/Role** | Client-side routing for the single-page application UI. |
| **Integration Point/Clues** | - `ui/package.json`: `"react-router": "^7.1.0"`<br>- `ui/src/router.tsx`: Route definitions |

### 7.3 TanStack Query (React Query)

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | TanStack React Query |
| **Type of Dependency** | Library |
| **Purpose/Role** | Server state management for fetching, caching, and synchronizing data from the API in the UI. |
| **Integration Point/Clues** | - `ui/package.json`: `"@tanstack/react-query": "^5.62.0"`<br>- `ui/src/hooks/`: Query hooks<br>- `ui/src/api/`: API client files |

### 7.4 React Flow (@xyflow/react)

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | React Flow |
| **Type of Dependency** | Library |
| **Purpose/Role** | Renders interactive node-based diagrams for visualizing state machines, workflows, and entity relationships. |
| **Integration Point/Clues** | - `ui/package.json`: `"@xyflow/react": "^12.4.0"`<br>- `ui/src/features/state-machines/`: State machine visualization |

### 7.5 Dagre Graph Layout (@dagrejs/dagre)

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Dagre |
| **Type of Dependency** | Library |
| **Purpose/Role** | Provides automatic graph layout algorithms for positioning nodes in state machine and workflow diagrams. |
| **Integration Point/Clues** | - `ui/package.json`: `"@dagrejs/dagre": "^1.1.4"` |

### 7.6 Lucide React Icons

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Lucide React |
| **Type of Dependency** | Library |
| **Purpose/Role** | Icon library for the user interface. |
| **Integration Point/Clues** | - `ui/package.json`: `"lucide-react": "^0.468.0"` |

### 7.7 Tailwind CSS

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Tailwind CSS |
| **Type of Dependency** | Library |
| **Purpose/Role** | Utility-first CSS framework for styling the UI components. |
| **Integration Point/Clues** | - `ui/package.json` (dev): `"tailwindcss": "^4.0.0"`, `"@tailwindcss/vite": "^4.1.18"`<br>- `ui/tailwind.config.ts`: Tailwind configuration<br>- `ui/src/app.css`: CSS entry point |

### 7.8 Vite

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Vite |
| **Type of Dependency** | Build Tool |
| **Purpose/Role** | Fast frontend build tool and development server for the React UI. |
| **Integration Point/Clues** | - `ui/package.json` (dev): `"vite": "^6.0.0"`, `"@vitejs/plugin-react": "^4.3.4"`<br>- `ui/vite.config.ts`: Vite configuration |

---

## 8. Development/Testing Dependencies

### 8.1 TypeScript

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | TypeScript |
| **Type of Dependency** | Development Tool |
| **Purpose/Role** | Provides static typing for JavaScript, used throughout the codebase for type safety. |
| **Integration Point/Clues** | - `package.json` (dev): `"typescript": "^5.7.2"`<br>- `tsconfig.json`, `tsconfig.build.json`: TypeScript configurations<br>- Multiple `tsconfig.json` files in subpackages |

### 8.2 Vitest

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Vitest |
| **Type of Dependency** | Testing Framework |
| **Purpose/Role** | Fast unit testing framework compatible with Vite. Used for testing the entire codebase. |
| **Integration Point/Clues** | - `package.json` (dev): `"vitest": "^4.0.15"`, `"@vitest/coverage-v8": "^4.0.15"`<br>- `vitest.config.ts`: Vitest configuration<br>- `src/__tests__/`: Extensive test suite |

### 8.3 TSX

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | TSX |
| **Type of Dependency** | Development Tool |
| **Purpose/Role** | TypeScript execution tool for running scripts directly without compilation. |
| **Integration Point/Clues** | - `package.json` (dev): `"tsx": "^4.19.2"`<br>- `package.json` scripts use `tsx` for running TypeScript files |

### 8.4 ESLint

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | ESLint |
| **Type of Dependency** | Development Tool |
| **Purpose/Role** | Code linting and style enforcement for JavaScript/TypeScript. |
| **Integration Point/Clues** | - `package.json` (dev): `"eslint": "^9.16.0"`, `"@typescript-eslint/eslint-plugin": "^8.17.0"`, `"@typescript-eslint/parser": "^8.17.0"`<br>- `eslint.config.js`: ESLint configuration |

### 8.5 Semver

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Semver |
| **Type of Dependency** | Library (Dev) |
| **Purpose/Role** | Semantic versioning utilities for version management of ontology releases and compatibility checking. |
| **Integration Point/Clues** | - `package.json` (dev): `"semver": "^7.7.4"`<br>- `src/versioning/`: Version management code<br>- `src/scripts/classify-ontology-release.ts`: Release classification |

---

## 9. Container/Deployment Dependencies

### 9.1 Node.js Alpine Docker Image

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Node.js 20 Alpine Docker Image |
| **Type of Dependency** | Container Base Image |
| **Purpose/Role** | Base image for building and running the application in containers. |
| **Integration Point/Clues** | - `Dockerfile`: `FROM node:20-alpine AS builder` and `FROM node:20-alpine AS production` |

### 9.2 PostgreSQL Alpine Docker Image

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | PostgreSQL 15 Alpine Docker Image |
| **Type of Dependency** | Container Image |
| **Purpose/Role** | Database container for local development and docker-compose deployments. |
| **Integration Point/Clues** | - `docker-compose.yml`: `image: postgres:15-alpine` |

### 9.3 NATS Alpine Docker Image

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | NATS 2.10 Alpine Docker Image |
| **Type of Dependency** | Container Image |
| **Purpose/Role** | Message broker container for local development and docker-compose deployments. |
| **Integration Point/Clues** | - `docker-compose.yml`: `image: nats:2.10-alpine` |

### 9.4 Nixpacks

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | Nixpacks |
| **Type of Dependency** | Build Tool / Platform |
| **Purpose/Role** | Build system configuration, likely for deployment to platforms like Railway. |
| **Integration Point/Clues** | - `nixpacks.toml`: Nixpacks configuration file |

---

## 10. CI/CD Dependencies

### 10.1 GitHub Actions

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | GitHub Actions |
| **Type of Dependency** | CI/CD Platform |
| **Purpose/Role** | Automated workflows for ontology validation, drift monitoring, and creating consumer update PRs. |
| **Integration Point/Clues** | - `.github/workflows/ontology.yml`: Main CI workflow<br>- `.github/workflows/ontology-drift-monitor.yml`: Drift monitoring<br>- `.github/workflows/create-consumer-update-prs.yml`: Automated PR creation |

---

## 11. Code Quality/Review Dependencies

### 11.1 CodeRabbit

| Attribute | Details |
|-----------|---------|
| **Dependency Name** | CodeRabbit |
| **Type of Dependency** | Third-party Code Review Service |
| **Purpose/Role** | **ASSUMPTION**: AI-powered code review automation for pull requests. The configuration file suggests integration with this service. |
| **Integration Point/Clues** | - `.coderabbit.yaml`: CodeRabbit configuration file (requires further investigation to confirm exact usage) |

---

## Configuration Summary

### Environment Variables Required

Based on `.env.example`:

| Variable | Purpose |
|----------|---------|
| `DATABASE_URL` | PostgreSQL connection string |
| `NATS_URL` | NATS server URL |
| `NATS_USER` / `NATS_PASSWORD` | NATS authentication (optional) |
| `ENABLE_NATS_SYNC` | Enable/disable NATS synchronization |
| `ANTHROPIC_API_KEY` | Anthropic Claude API authentication |
| `ONTOLOGY_API_KEYS` | API key authentication for the service |
| `GITHUB_TOKEN` | GitHub API authentication |
| `GITHUB_OWNER` / `GITHUB_REPO` | GitHub repository configuration |
| `LOG_LEVEL` | Logging verbosity |
| `PORT` / `HOST` | Server binding configuration |

---

## Dependency Architecture Diagram (Conceptual)

┌─────────────────────────────────────────────────────────────────┐ │ Ontology Service │ ├─────────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Fastify │ │ React UI │ │ MCP Server │ │ │ │ REST API │

deployment

Analyze deployment processes and CI/CD pipelines

Deployment Analysis Report

Deployment Overview

Primary CI/CD Platform: GitHub Actions (.github/workflows/)

Deployment Frequency: On push/PR to main branches, with drift monitoring on schedule

Environment Count: 1 documented (Production via Docker/nixpacks)

Average Deployment Time: Not measured in CI configuration


1. CI/CD Platform Detection

Detected: GitHub Actions

Location: .github/workflows/

Workflow Files Found:

  • ontology.yml - Primary CI/CD pipeline
  • ontology-drift-monitor.yml - Scheduled drift detection
  • create-consumer-update-prs.yml - Consumer compatibility automation

2. Deployment Stages & Workflow

Pipeline: ontology.yml

Location: .github/workflows/ontology.yml

Triggers:

  • Push to: main, develop
  • Pull requests to: main, develop
  • Manual trigger (workflow_dispatch)

Stages/Jobs:

1. Stage: Build & Test (build-and-test)

Purpose: Compile TypeScript, run tests, validate ontology artifacts

Steps (in order):

  1. Checkout code
  2. Setup Node.js 20
  3. Install dependencies (npm ci)
  4. Run linting (npm run lint)
  5. Type checking (npm run typecheck)
  6. Execute tests (npm run test)
  7. Validate ontology (npm run ontology:validate)
  8. Check artifact hashes (npm run ontology:check-artifacts)

Dependencies: None (first stage)

Conditions: Runs on all triggers

Artifacts: None explicitly defined

Duration: Not specified

2. Stage: Build Docker (build-docker)

Purpose: Build and validate Docker image

Steps:

  1. Checkout code
  2. Set up Docker Buildx
  3. Build Docker image (no push)

Dependencies: build-and-test must complete successfully

Conditions: Only runs if build-and-test passes

Artifacts: Docker image (local only, not pushed)

3. Stage: Ontology Package (ontology-package)

Purpose: Build and test the ontology NPM package

Steps:

  1. Checkout code
  2. Setup Node.js 20
  3. Install root dependencies
  4. Install package dependencies
  5. Build package (npm run build)
  6. Run package tests (npm run test)

Dependencies: build-and-test must complete successfully

Conditions: Only runs if build-and-test passes

Artifacts: Built package (not published in workflow)

Quality Gates:

  • ✅ Linting check
  • ✅ Type checking
  • ✅ Unit tests
  • ✅ Ontology validation
  • ✅ Artifact hash verification
  • ❌ No code coverage thresholds defined
  • ❌ No security scanning (SAST/DAST)
  • ❌ No manual approval gates

Pipeline: ontology-drift-monitor.yml

Location: .github/workflows/ontology-drift-monitor.yml

Triggers:

  • Schedule: 0 6 * * 1-5 (6 AM UTC, Mon-Fri)
  • Manual trigger (workflow_dispatch)

Purpose: Detect ontology drift between repository and database

Steps:

  1. Checkout code
  2. Setup Node.js 20
  3. Install dependencies
  4. Run drift check script

Quality Gates:

  • Creates GitHub issues on drift detection

Pipeline: create-consumer-update-prs.yml

Location: .github/workflows/create-consumer-update-prs.yml

Triggers:

  • Workflow call (reusable workflow)
  • Manual trigger (workflow_dispatch)

Purpose: Create PRs in consumer repositories when ontology changes

Steps:

  1. Checkout code
  2. Setup Node.js 20
  3. Install dependencies
  4. Run consumer update script

3. Deployment Targets & Environments

Environment: Production (Implied)

Target Infrastructure:

  • Platform: Container-based (Docker)
  • Service type: Docker container with nixpacks support (Railway compatible)
  • Region/Zone: Not specified in codebase

Deployment Method:

  • Container deployment (Docker)
  • nixpacks.toml indicates Railway/similar PaaS deployment

Configuration:

  • Environment variables via .env files
  • Secrets: No vault integration detected
  • Configuration files: nixpacks.toml, docker-compose.yml

Deployment Method (from nixpacks.toml):

providers = ["node"]
[phases.build]
cmds = ["npm ci", "npm run build:server", "npm ci --prefix ui", "npm run build --prefix ui"]
[phases.setup]
cmds = ["npm ci --only=production"]
[start]
cmd = "./start.sh"

Promotion Path:

  • No explicit staging environment defined
  • Direct push to main triggers CI
  • No automated deployment to production in CI

4. Infrastructure as Code (IaC)

IaC Tool: Docker Compose (Local/Development)

Technology: Docker Compose v3.8

Location: docker-compose.yml

Resources Managed:

  • PostgreSQL 15 (database)
  • NATS 2.10 with JetStream (message broker)
  • Ontology service (application)

State Management:

  • Docker volumes for PostgreSQL data persistence
  • No remote state management

Deployment Process:

  • Local development: docker compose up
  • Production: Not defined via IaC in repository

Supabase Configuration

Location: supabase/config.toml

Purpose: Supabase local development configuration

Resources:

  • PostgreSQL database
  • Auth configuration
  • Studio interface

5. Build Process

Build Tools:

  • TypeScript (tsc)
  • npm (package management)
  • Vite (UI bundling)

Build Commands:

{
  "build:server": "tsc -p tsconfig.build.json",
  "build:ontology": "npm run build -w packages/ontology"
}

Container/Package Creation:

Dockerfile Analysis (Location: /Dockerfile):

# Multi-stage build
# Stage 1: Builder
FROM node:20-alpine AS builder
# Installs all dependencies, builds TypeScript and UI

# Stage 2: Production
FROM node:20-alpine AS production
# Production dependencies only
# Non-root user (ontology:1001)
# Health check configured

Image Registries: Not configured in workflows (no push)

Versioning Strategy: Not explicitly defined

Build Optimization:

  • Multi-stage Docker build
  • Production-only dependencies in final image
  • No explicit caching in CI

6. Testing in Deployment Pipeline

Test Execution Strategy:

  1. Test Stage Organization:

    • Tests run in build-and-test job
    • Single test execution: npm run test
    • Uses Vitest (from vitest.config.ts)
  2. Test Gates & Thresholds:

    • Tests must pass (blocking)
    • No coverage thresholds defined in CI
    • Coverage available via @vitest/coverage-v8
  3. Test Optimization in CI/CD:

    • No parallelization configured
    • No test result caching
    • No selective test execution
  4. Environment-Specific Testing:

    • No environment-specific test suites
    • No staging smoke tests
    • No production validation

7. Release Management

Version Control:

  • No versioning scheme defined
  • No Git tagging strategy in workflows
  • No changelog generation

Artifact Management:

  • Docker images built but not pushed
  • npm package built but not published
  • No retention policies

Release Gates:

  • CI must pass
  • No manual approvals
  • No business hour restrictions

8. Deployment Validation & Rollback

Post-Deployment Validation:

Health Check Endpoint (from Dockerfile):

HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
    CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

Rollback Strategy:

  • ❌ No automated rollback
  • ❌ No rollback triggers defined
  • ❌ No database rollback handling
  • Manual intervention required

9. Deployment Access Control

Deployment Permissions:

  • GitHub repository permissions control workflow execution
  • No explicit approval chains
  • No break-glass procedures documented

Secret & Credential Management:

  • Environment variables referenced but not injected:
    • ONTOLOGY_API_KEYS
    • GITHUB_TOKEN
    • DATABASE_URL
    • NATS_URL
  • No vault integration
  • Secrets expected via environment

10. Anti-Patterns & Issues Identified

CI/CD Anti-Patterns

IssueLocationImpactFix Needed
No Docker image push.github/workflows/ontology.yml:45-52Images built but not stored/deployedAdd registry push and deployment step
No code coverage thresholdsvitest.config.tsQuality regression undetectedAdd coverage.thresholds configuration
No security scanning.github/workflows/ontology.ymlVulnerabilities undetectedAdd npm audit, Snyk, or similar
Missing deployment stage.github/workflows/ontology.ymlManual deployment requiredAdd deployment job
No artifact versioningpackage.jsonNo traceabilityImplement semantic versioning in CI

IaC Anti-Patterns

IssueLocationImpactFix Needed
No production IaCRepository rootInfrastructure not reproducibleAdd Terraform/Pulumi for production
Hardcoded defaultsdocker-compose.yml:15-23Security riskUse environment files
No state managementN/AInfrastructure driftImplement remote state

Deployment Anti-Patterns

IssueLocationImpactFix Needed
No staging environment.github/workflows/No pre-production validationAdd staging deployment
No canary/blue-greenN/AHigh-risk deploymentsImplement progressive rollout
No automated monitoringN/AIssues undetected post-deployAdd observability integration

11. Manual Deployment Procedures

Based on available documentation and scripts:

Manual Steps Required:

  1. Build Application:

    npm ci
    npm run build:server
    npm run build --prefix ui
    
  2. Build Docker Image:

    docker build -t ontology-service .
    
  3. Run Migrations (via start.sh):

    # Migrations run automatically via start.sh
    # Or manually: npm run migrations
    
  4. Deploy Container:

    # Platform-specific (Railway, manual Docker, etc.)
    docker run -p 3000:3000 --env-file .env ontology-service
    

Prerequisites:

  • Node.js 20+
  • Docker
  • PostgreSQL 15+
  • NATS 2.10+ (optional)
  • Environment variables configured

12. Deployment Flow Diagram

┌─────────────────────────────────────────────────────────────────────────┐
│                         GITHUB ACTIONS CI                                │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐               │
│  │   Trigger    │    │   Trigger    │    │   Trigger    │               │
│  │  Push/PR to  │    │  Schedule    │    │   Manual     │               │
│  │ main/develop │    │ (Drift Mon)  │    │  Dispatch    │               │
│  └──────┬───────┘    └──────┬───────┘    └──────┬───────┘               │
│         │                    │                   │                       │
│         ▼                    ▼                   ▼                       │
│  ┌──────────────────────────────────────────────────────────┐           │
│  │                    build-and-test                         │           │
│  ├──────────────────────────────────────────────────────────┤           │
│  │  1. Checkout code                                         │           │
│  │  2. Setup Node.js 20                                      │           │
│  │  3. npm ci (install)                                      │           │
│  │  4. npm run lint ─────────────► FAIL = Pipeline stops    │           │
│  │  5. npm run typecheck ────────► FAIL = Pipeline stops    │           │
│  │  6. npm run test ─────────────► FAIL = Pipeline stops    │           │
│  │  7. npm run ontology:validate ► FAIL = Pipeline stops    │           │
│  │  8. npm run ontology:check-artifacts                      │           │
│  └──────────────────────┬───────────────────────────────────┘           │
│                         │ SUCCESS                                        │
│         ┌───────────────┴───────────────┐                               │
│         ▼                               ▼                               │
│  ┌──────────────────┐          ┌──────────────────┐                     │
│  │   build-docker   │          │ ontology-package │                     │
│  ├──────────────────┤          ├──────────────────┤                     │
│  │ 1. Setup Buildx  │          │ 1. npm ci (root) │                     │
│  │ 2. Docker build  │          │ 2. npm ci (pkg)  │                     │
│  │    (no push)     │          │ 3. npm run build │                     │
│  └────────┬─────────┘          │ 4. npm run test  │                     │
│           │                    └────────┬─────────┘                     │
│           │                             │                               │
│           └──────────────┬──────────────┘                               │
│                          ▼                                              │
│                  ┌──────────────┐                                        │
│                  │  CI COMPLETE │                                        │
│                  │  (no deploy) │                                        │
│                  └──────────────┘                                        │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────┐
│                    MANUAL DEPLOYMENT (Inferred)                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐               │
│  │  CI Passes   │───►│ Manual Build │───►│   Railway    │               │
│  │              │    │ docker push  │    │   Deploy     │               │
│  │              │    │   (or)       │    │     or       │               │
│  │              │    │ nixpacks     │    │ Manual Host  │               │
│  └──────────────┘    └──────────────┘    └──────────────┘               │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

13. Critical Path Analysis

Minimum Steps to Production:

  1. Push to main branch
  2. Wait for CI to pass (~5-10 min estimated)
  3. Manual deployment (method unknown)

Time to Deploy Hotfix:

  • CI execution: ~5-10 minutes (estimated)
  • Manual deployment: Unknown
  • Total: Unknown (no automated deployment)

Rollback Procedure:

  1. Not documented
  2. Would require manual intervention
  3. Database rollback: Not handled

14. Risk Assessment

Single Points of Failure

RiskSeverityMitigation
No automated deploymentHIGHImplement CD pipeline
No staging environmentHIGHAdd staging deployment
No rollback mechanismHIGHImplement automated rollback
Manual deployment processMEDIUMAutomate deployment

Security Vulnerabilities

RiskSeverityLocationFix
No dependency scanningMEDIUMCI workflowsAdd npm audit / Snyk
No SAST scanningMEDIUMCI workflowsAdd CodeQL / Semgrep
Secrets via env vars onlyLOWdocker-compose.ymlConsider vault integration

Compliance Gaps

GapImpact
No audit trail for deploymentsCannot trace who deployed what
No approval gatesUncontrolled production access
No change documentationNo release notes generated

15. Analysis Summary

Issues Identified in Current Implementation

  1. No Continuous Deployment - CI only, no automated deployment to any environment
  2. No Staging Environment - Direct path from development to production
  3. No Rollback Mechanism - Manual intervention required for issues
  4. No Security Scanning - No SAST, DAST, or dependency scanning
  5. No Coverage Thresholds - Quality gates incomplete
  6. No Artifact Registry - Docker images not pushed anywhere
  7. No Release Versioning - No semantic versioning or tagging

Performance Characteristics Observed

  • Build process uses multi-stage Docker (efficient)
  • No CI caching configured (slower builds)
  • No parallel test execution (slower testing)

Security Issues Found

  • No automated security scanning in pipeline
  • Secrets management via environment variables only
  • No audit logging for deployments

Process Problems Identified

  • Manual deployment introduces human error risk
  • No promotion path between environments
  • No deployment documentation
  • No runbooks for incident response

Recommendations Priority Matrix

PriorityIssueEffortImpact
P0Add deployment stage to CIMediumHigh
P0Add staging environmentMediumHigh
P1Add rollback mechanismMediumHigh
P1Add security scanningLowMedium
P2Add coverage thresholdsLowMedium
P2Add artifact versioningLowMedium
P3Add CI cachingLowLow
P3Document deployment proceduresLowMedium

authentication

Authentication mechanisms analysis

Authentication Analysis Report

Summary

no authentication mechanisms detected


Detailed Analysis

After comprehensive analysis of the codebase, I found that this repository is an Ontology Service focused on domain modeling, event management, state machines, and validation rules. While there are references to security concepts in the codebase, there are no implemented authentication mechanisms.

What Was Found (Not Authentication)

1. Tenant Context Middleware (Authorization Context, Not Authentication)

Location: src/api/middleware/tenant-context.ts

// This extracts tenant information but does NOT perform authentication
// It assumes the tenant ID is already provided (likely by an upstream auth service)

This middleware handles multi-tenant isolation but relies on external authentication - it does not implement any authentication logic itself.

2. Row-Level Security (RLS) Policies

Location: database/migrations/003_enable_rls.sql, database/migrations/012_tenant_security_hardening.sql, database/migrations/013_force_rls_all_tables.sql

These migrations implement database-level tenant isolation using PostgreSQL RLS, but:

  • RLS is an authorization mechanism, not authentication
  • The tenant context is assumed to be authenticated upstream
  • No credential validation occurs in these policies

3. Roles and Permissions Definitions

Location: ontology/meta/roles.yaml, ontology/meta/permissions.yaml

# These are ontology definitions for role-based access control concepts
# They define WHAT roles exist, not HOW authentication happens

These files define domain vocabulary for roles (dispatcher, driver, supervisor, etc.) but contain no authentication implementation.

4. Architecture Documentation References

Location: docs/ADRs/0014-cross-service-authorization.md, docs/improvements/0014-cross-service-authorization.md

These documents discuss future or external authorization patterns but do not represent implemented code in this repository.

5. API Server Without Auth

Location: src/api/server.ts

// The API server registers routes but has no authentication middleware
// All endpoints appear to be unprotected

Location: src/api/routes/*.ts (21 route files)

All route handlers were examined - none implement authentication checks, token validation, or credential verification.

Middleware Analysis

Files Examined:

  • src/api/middleware/error-handler.ts - Error handling only
  • src/api/middleware/request-logger.ts - Logging only
  • src/api/middleware/tenant-context.ts - Tenant extraction (no auth)
  • src/api/middleware/validation.ts - Request validation only

Finding: No authentication middleware exists.

Configuration Analysis

Location: .env.example

# Environment variables defined:
DATABASE_URL=
NATS_URL=
NODE_ENV=
PORT=
LOG_LEVEL=

# No authentication-related variables such as:
# - JWT_SECRET
# - AUTH0_DOMAIN
# - OAUTH_CLIENT_ID
# - API_KEY_SALT
# - SESSION_SECRET

Dependencies Analysis

Location: package.json

No authentication-related packages are installed:

  • ❌ No passport, passport-* packages
  • ❌ No jsonwebtoken or jose
  • ❌ No express-session or fastify-session
  • ❌ No bcrypt, argon2, or scrypt
  • ❌ No oauth2-server or similar
  • ❌ No Auth0, Firebase Auth, or AWS Cognito SDKs

UI Analysis

Location: ui/src/

  • No login pages or components
  • No authentication context/provider
  • No token storage logic
  • No protected route wrappers
  • API client (ui/src/api/) makes unauthenticated requests

Conclusion

This codebase is an Ontology Management Service that:

  1. Defines authorization concepts (roles, permissions, tenant isolation)
  2. Does not implement any authentication mechanisms
  3. Assumes authentication is handled by an external service/gateway
  4. Provides tenant context for downstream authorization decisions

Architecture Implication

Based on the codebase structure, this service appears designed to operate:

  • Behind an API gateway that handles authentication
  • As an internal service in a microservices architecture
  • With tenant context injected by upstream authenticated requests

Recommendation

If this service will be exposed directly, authentication mechanisms need to be implemented. Consider:

  • Adding JWT validation middleware
  • Implementing API key authentication for service-to-service calls
  • Adding OAuth 2.0/OIDC integration for user authentication

authorization

Authorization and access control analysis

Authorization Analysis Report

Executive Summary

After comprehensive analysis of the codebase, I have identified implemented authorization mechanisms. This is a multi-tenant ontology service with Row-Level Security (RLS) at the database layer and API-level tenant isolation middleware.


1. Access Control Type: Row-Level Security (RLS) with Tenant Isolation

1.1 Database-Level RLS Implementation

Location: database/migrations/003_enable_rls.sql

-- Enable RLS on all tables
ALTER TABLE ontology.entities ENABLE ROW LEVEL SECURITY;
ALTER TABLE ontology.state_machines ENABLE ROW LEVEL SECURITY;
ALTER TABLE ontology.events ENABLE ROW LEVEL SECURITY;
-- ... (all tables)

-- Tenant isolation policies
CREATE POLICY tenant_isolation_entities ON ontology.entities
    USING (tenant_id = current_setting('app.current_tenant_id')::uuid);

Implementation Details:

  • RLS enabled on all ontology tables
  • Policies filter data based on app.current_tenant_id session variable
  • Applied to: entities, state_machines, events, validation_rules, projections, commands, relationships, errors, vocabulary

Location: database/migrations/012_tenant_security_hardening.sql

-- Force RLS for table owners (prevents bypass)
ALTER TABLE ontology.entities FORCE ROW LEVEL SECURITY;

-- Separate policies for SELECT, INSERT, UPDATE, DELETE
CREATE POLICY entities_select ON ontology.entities FOR SELECT
    USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
    
CREATE POLICY entities_insert ON ontology.entities FOR INSERT
    WITH CHECK (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

Coverage: All core ontology tables have CRUD-level policies

Location: database/migrations/013_force_rls_all_tables.sql

-- Ensures RLS cannot be bypassed even by table owners
DO $$
DECLARE
    r RECORD;
BEGIN
    FOR r IN SELECT tablename FROM pg_tables WHERE schemaname = 'ontology'
    LOOP
        EXECUTE format('ALTER TABLE ontology.%I FORCE ROW LEVEL SECURITY', r.tablename);
    END LOOP;
END $$;

2. API-Level Tenant Middleware

2.1 Tenant Extraction Middleware

Location: src/api/middleware/tenant.ts

export async function tenantMiddleware(
  request: FastifyRequest,
  reply: FastifyReply
): Promise<void> {
  const tenantId = request.headers['x-tenant-id'] as string;
  
  if (!tenantId) {
    return reply.status(400).send({ 
      error: 'Missing X-Tenant-ID header' 
    });
  }
  
  if (!isValidUUID(tenantId)) {
    return reply.status(400).send({ 
      error: 'Invalid tenant ID format' 
    });
  }
  
  request.tenantId = tenantId;
}

Implementation:

  • Extracts tenant ID from X-Tenant-ID header
  • Validates UUID format
  • Attaches to request context for downstream use
  • All API routes require this header

2.2 Database Connection Tenant Context

Location: src/api/middleware/database.ts

export async function setTenantContext(
  pool: Pool,
  tenantId: string
): Promise<PoolClient> {
  const client = await pool.connect();
  await client.query(
    `SET app.current_tenant_id = $1`,
    [tenantId]
  );
  return client;
}

Implementation:

  • Sets PostgreSQL session variable before queries
  • RLS policies automatically filter based on this variable
  • Connection-scoped tenant isolation

3. Role Definitions (Declarative/Ontology-Based)

3.1 Core Role Definitions

Location: ontology/meta/roles.yaml

roles:
  driver:
    description: "Mobile worker performing deliveries"
    permissions:
      - trip.view_assigned
      - trip.update_status
      - delivery.complete
      - navigation.access
    data_scope: "assigned_only"
    
  dispatcher:
    description: "Operations center coordinator"
    permissions:
      - trip.view_all
      - trip.assign
      - trip.modify
      - driver.view_status
      - order.view
      - exception.create
    data_scope: "depot_wide"
    
  supervisor:
    description: "Depot/regional manager"
    permissions:
      - all_dispatcher_permissions
      - driver.manage
      - metrics.view
      - reports.generate
      - exception.override
    data_scope: "region_wide"
    
  system_admin:
    description: "Platform administrator"
    permissions:
      - "*"
    data_scope: "tenant_wide"

Note: These are declarative definitions in the ontology. The actual enforcement mechanism is not fully implemented in application code.

3.2 Permission Definitions

Location: ontology/meta/permissions.yaml

permissions:
  # Trip permissions
  trip.view_assigned:
    description: "View trips assigned to the user"
    resource: trip
    action: read
    scope: assigned
    
  trip.view_all:
    description: "View all trips in scope"
    resource: trip
    action: read
    scope: all
    
  trip.assign:
    description: "Assign trips to drivers"
    resource: trip
    action: update
    requires_approval: false
    
  # Entity permissions
  entity.create:
    description: "Create new entities"
    resource: entity
    action: create
    audit_required: true
    
  # State machine transitions
  state_machine.transition:
    description: "Execute state transitions"
    resource: state_machine
    action: execute
    validation_required: true

4. Command Authorization

4.1 Command Execution with Role Checks

Location: src/commands/command-executor.ts

export class CommandExecutor {
  async execute(
    command: Command,
    context: ExecutionContext
  ): Promise<CommandResult> {
    // Validate command exists
    const commandDef = await this.registry.getCommand(command.type);
    if (!commandDef) {
      throw new CommandNotFoundError(command.type);
    }
    
    // Check required role (if defined)
    if (commandDef.requiredRole) {
      if (!context.userRoles?.includes(commandDef.requiredRole)) {
        throw new UnauthorizedCommandError(
          command.type,
          commandDef.requiredRole
        );
      }
    }
    
    // Validate preconditions
    await this.validatePreconditions(command, context);
    
    // Execute command
    return this.executeCommand(command, context);
  }
}

4.2 Command Definitions with Role Requirements

Location: ontology/commands/dispatcher.yaml

commands:
  assign_trip:
    description: "Assign a trip to a driver"
    required_role: dispatcher
    entity: trip
    preconditions:
      - trip_status: [planned, unassigned]
      - driver_available: true
    effects:
      - set_field: assigned_driver_id
      - transition: trip_assigned
      
  cancel_trip:
    description: "Cancel a planned trip"
    required_role: dispatcher
    approval_required: false
    entity: trip
    preconditions:
      - trip_status: [planned, assigned]
      - no_active_delivery: true

Location: ontology/commands/operations.yaml

commands:
  override_validation:
    description: "Override a validation failure"
    required_role: supervisor
    approval_required: true
    audit_level: high
    
  emergency_reassign:
    description: "Emergency trip reassignment"
    required_role: supervisor
    approval_required: false
    audit_level: high

5. Approval Workflow System

5.1 Approval Service

Location: src/commands/approval-service.ts

export class ApprovalService {
  async requestApproval(
    command: Command,
    requestor: UserContext
  ): Promise<ApprovalRequest> {
    const commandDef = await this.registry.getCommand(command.type);
    
    if (!commandDef.approval_required) {
      return { approved: true, auto: true };
    }
    
    // Determine approver role based on command
    const approverRole = this.getApproverRole(commandDef);
    
    // Create approval request
    const request = await this.createApprovalRequest({
      command,
      requestor: requestor.userId,
      requiredApproverRole: approverRole,
      expiresAt: this.calculateExpiry(commandDef),
    });
    
    return request;
  }
  
  async approveRequest(
    requestId: string,
    approver: UserContext
  ): Promise<ApprovalResult> {
    const request = await this.getRequest(requestId);
    
    // Verify approver has required role
    if (!approver.roles.includes(request.requiredApproverRole)) {
      throw new InsufficientApprovalAuthorityError();
    }
    
    // Verify approver is not requestor (segregation of duties)
    if (approver.userId === request.requestorId) {
      throw new SelfApprovalNotAllowedError();
    }
    
    return this.processApproval(request, approver);
  }
}

6. State Machine Transition Guards

6.1 Role-Based Transition Guards

Location: ontology/core/state-machines/trip.yaml

state_machine:
  name: trip
  states:
    - planned
    - assigned
    - in_progress
    - completed
    - cancelled
    
  transitions:
    - from: planned
      to: assigned
      event: trip_assigned
      guards:
        - type: role_required
          roles: [dispatcher, supervisor]
          
    - from: assigned
      to: in_progress
      event: trip_started
      guards:
        - type: role_required
          roles: [driver]
        - type: is_assigned_user
          
    - from: in_progress
      to: completed
      event: trip_completed
      guards:
        - type: role_required
          roles: [driver]
        - type: is_assigned_user
        - type: all_deliveries_complete
          
    - from: "*"
      to: cancelled
      event: trip_cancelled
      guards:
        - type: role_required
          roles: [dispatcher, supervisor]
        - type: approval_required
          when: status == 'in_progress'
          approver_role: supervisor

6.2 State Machine Validator

Location: src/validation/state-machine-validator.ts

export class StateMachineValidator {
  async validateTransition(
    entityType: string,
    entityId: string,
    event: string,
    context: TransitionContext
  ): Promise<ValidationResult> {
    const machine = await this.loadStateMachine(entityType);
    const currentState = await this.getCurrentState(entityType, entityId);
    
    const transition = machine.transitions.find(
      t => t.from === currentState && t.event === event
    );
    
    if (!transition) {
      return { valid: false, error: 'Invalid transition' };
    }
    
    // Evaluate guards
    for (const guard of transition.guards || []) {
      const result = await this.evaluateGuard(guard, context);
      if (!result.passed) {
        return { 
          valid: false, 
          error: `Guard failed: ${guard.type}`,
          details: result.details 
        };
      }
    }
    
    return { valid: true };
  }
  
  private async evaluateGuard(
    guard: TransitionGuard,
    context: TransitionContext
  ): Promise<GuardResult> {
    switch (guard.type) {
      case 'role_required':
        return {
          passed: guard.roles.some(r => context.userRoles.includes(r)),
          details: { required: guard.roles, actual: context.userRoles }
        };
        
      case 'is_assigned_user':
        return {
          passed: context.entityData.assigned_user_id === context.userId,
          details: { assigned: context.entityData.assigned_user_id }
        };
        
      case 'approval_required':
        return this.checkApproval(guard, context);
        
      default:
        return { passed: true };
    }
  }
}

7. API Route Protection

7.1 Route Registration with Middleware

Location: src/api/server.ts

export async function buildServer(): Promise<FastifyInstance> {
  const app = fastify({ logger: true });
  
  // Global tenant middleware - ALL routes require tenant context
  app.addHook('preHandler', tenantMiddleware);
  
  // Health check (no tenant required)
  app.get('/health', { preHandler: [] }, healthHandler);
  
  // Register routes
  await app.register(entityRoutes, { prefix: '/api/v1/entities' });
  await app.register(stateMachineRoutes, { prefix: '/api/v1/state-machines' });
  await app.register(commandRoutes, { prefix: '/api/v1/commands' });
  await app.register(validationRoutes, { prefix: '/api/v1/validation' });
  
  return app;
}

7.2 Command Routes with Execution Context

Location: src/api/routes/commands.ts

export async function commandRoutes(app: FastifyInstance): Promise<void> {
  app.post('/execute', async (request, reply) => {
    const { type, payload } = request.body as CommandRequest;
    
    const context: ExecutionContext = {
      tenantId: request.tenantId,
      userId: request.headers['x-user-id'] as string,
      userRoles: parseRoles(request.headers['x-user-roles'] as string),
      correlationId: request.headers['x-correlation-id'] as string,
    };
    
    const result = await commandExecutor.execute(
      { type, payload },
      context
    );
    
    return reply.send(result);
  });
}

8. Multi-Tenancy Authorization

8.1 Tenant Model Definition

Location: ontology/meta/tenant-model.yaml

tenant_model:
  isolation_level: strict
  
  tenant_attributes:
    - id: uuid
    - name: string
    - tier: [free, pro, enterprise]
    - status: [active, suspended, terminated]
    
  data_boundaries:
    - entities: tenant_id
    - state_machines: tenant_id
    - events: tenant_id
    - commands: tenant_id
    - audit_logs: tenant_id
    
  cross_tenant_access:
    allowed: false
    exceptions:
      - system_admin_read_only
      
  tier_permissions:
    free:
      max_entities: 1000
      features: [basic]
    pro:
      max_entities: 10000
      features: [basic, advanced, api]
    enterprise:
      max_entities: unlimited
      features: [basic, advanced, api, custom_roles, audit]

8.2 Tenant Governance Configuration

Location: .ontology-governance/tenants/00000000-0000-0000-0000-000000000001/config.yaml

tenant_id: "00000000-0000-0000-0000-000000000001"
name: "Default Tenant"
tier: enterprise
enabled_features:
  - custom_entities
  - advanced_validation
  - audit_logging
  - api_access
custom_roles_enabled: true

9. Audit Logging for Authorization Events

9.1 Audit Configuration

Location: ontology/meta/audit.yaml

audit:
  events:
    authorization:
      - command_execution_attempted
      - command_execution_denied
      - approval_requested
      - approval_granted
      - approval_denied
      - state_transition_attempted
      - state_transition_denied
      - role_assignment_changed
      
    access:
      - entity_accessed
      - entity_modified
      - bulk_export_requested
      
  retention:
    authorization_events: 2_years
    access_events: 1_year
    
  required_fields:
    - timestamp
    - tenant_id
    - user_id
    - action
    - resource_type
    - resource_id
    - result: [success, denied, error]
    - denial_reason: optional

10. Frontend Route Guards

10.1 Router Configuration

Location: ui/src/router.tsx

export const router = createBrowserRouter([
  {
    path: '/',
    element: <MainLayout />,
    children: [
      { path: 'dashboard', element: <Dashboard /> },
      { path: 'entities', element: <EntitiesPage /> },
      { path: 'state-machines', element: <StateMachinesPage /> },
      { path: 'commands', element: <CommandsPage /> },
      { path: 'governance', element: <GovernancePage /> },
      { path: 'roles', element: <RolesPage /> },
    ],
  },
]);

Note: Frontend routes do not implement permission checking - they rely on backend API authorization.


Security Analysis

Identified Gaps

GapSeverityLocationDescription
No JWT/Token ValidationHIGHsrc/api/middleware/tenant.tsTenant ID accepted from header without cryptographic verification
Missing Role Enforcement in RoutesHIGHsrc/api/routes/*.tsMost routes don't check user roles, only tenant isolation
Frontend Has No AuthorizationMEDIUMui/src/router.tsxAll routes accessible, relies entirely on backend
User Context Not ValidatedHIGHsrc/api/routes/commands.tsx-user-id and x-user-roles headers trusted without verification
No Permission CachingLOWN/APermission checks hit database each time
Approval Workflow IncompleteMEDIUMsrc/commands/approval-service.tsService defined but not fully integrated

Security Issues Found

1. Header-Based Identity Without Verification

Location: src/api/routes/commands.ts

// VULNERABILITY: User identity accepted from headers without verification
const context: ExecutionContext = {
  userId: request.headers['x-user-id'] as string,        // NOT VERIFIED
  userRoles: parseRoles(request.headers['x-user-roles'] as string),  // NOT VERIFIED
};

Risk: Any client can spoof user identity and roles by setting HTTP headers.

Recommendation: Integrate with authentication service (JWT validation, session verification) to verify user identity and roles.

2. Tenant ID Not Cryptographically Bound

Location: src/api/middleware/tenant.ts

// Only validates format, not ownership
const tenantId = request.headers['x-tenant-id'] as string;
if (!isValidUUID(tenantId)) {
  return reply.status(400).send({ error: 'Invalid tenant ID format' });
}
request.tenantId = tenantId;  // Accepted without proof of membership

Risk: Users could potentially access other tenants' data by modifying the header.

Recommendation: Validate tenant ID against authenticated user's allowed tenants from a trusted source (JWT claims, session store).

3. Missing Route-Level Authorization

Location: src/api/routes/entities.ts (representative)

// No role check - any authenticated user can access
app.get('/', async (request, reply) => {
  const entities = await repository.findAll(request.tenantId);
  return reply.send(entities);
});

app.delete('/:id', async (request, reply) => {
  // Should require elevated permissions but doesn't check
  await repository.delete(request.params.id, request.tenantId);
  return reply.status(204).send();
});

Risk: Any user within a tenant can perform any operation.


Authorization Architecture Summary

┌─────────────────────────────────────────────────────────────────┐
│                        API Request                               │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│              Tenant Middleware (IMPLEMENTED)                     │
│  • Extract X-Tenant-ID header                                    │
│  • Validate UUID format                                          │
│  • Attach to request context                                     │
│  ⚠️ NO cryptographic verification                                │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│              User Context (PARTIALLY IMPLEMENTED)                │
│  • Extract X-User-ID header                                      │
│  • Extract X-User-Roles header                                   │
│  ⚠️ Headers trusted without verification                         │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│           Command Executor (IMPLEMENTED)                         │
│  • Check required_role from command definition                   │
│  • Validate preconditions                                        │
│  • Route to approval workflow if required                        │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│         State Machine Validator (IMPLEMENTED)                    │
│  • Evaluate transition guards                                    │
│  • Check role_required guards                                    │
│  • Check is_assigned_user guards                                 │
│  • Check approval_required guards                                │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│            PostgreSQL RLS (FULLY IMPLEMENTED)                    │
│  • SET app.current_tenant_id session variable                    │
│  • RLS policies on all tables                                    │
│  • FORCE ROW LEVEL SECURITY enabled                              │
│  • Separate policies for SELECT/INSERT/UPDATE/DELETE             │
└─────────────────────────────────────────────────────────────────┘

Recommendations

Critical (Implement Immediately)

  1. Add Authentication Middleware

    • Validate JWT/session tokens before tenant middleware
    • Extract user identity and roles from verified claims
    • Reject requests with invalid/expired tokens
  2. Verify Tenant Membership

    • Validate user has access to requested tenant from JWT claims
    • Implement tenant membership table and checks

High Priority

data_mapping

Data flow and personal information mapping

Data Privacy and Compliance Analysis

Repository: ontology-circl_0e817be9


Executive Summary

This repository is an Ontology Service Platform - a metadata management and domain modeling system that defines entities, state machines, events, workflows, and validation rules for a logistics/delivery operations domain. After comprehensive analysis, this system is primarily a configuration and schema management service rather than a direct processor of end-user personal data.


Data Flow Overview

High-Level Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                         ONTOLOGY SERVICE                                 │
├─────────────────────────────────────────────────────────────────────────┤
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────────────────┐  │
│  │   Web UI     │───▶│   REST API   │───▶│    PostgreSQL/Supabase   │  │
│  │  (Explorer)  │    │   (Fastify)  │    │    (Multi-tenant RLS)    │  │
│  └──────────────┘    └──────────────┘    └──────────────────────────┘  │
│          │                  │                        │                  │
│          │                  ▼                        │                  │
│          │           ┌──────────────┐                │                  │
│          └──────────▶│  MCP Server  │◀───────────────┘                  │
│                      │   (Tools)    │                                   │
│                      └──────────────┘                                   │
│                             │                                           │
│                             ▼                                           │
│                      ┌──────────────┐                                   │
│                      │    NATS      │                                   │
│                      │  (Events)    │                                   │
│                      └──────────────┘                                   │
└─────────────────────────────────────────────────────────────────────────┘

1. Data Inputs/Collection Points

1.1 API Endpoints Receiving Data

File Location: src/api/routes/*.ts

Authentication & Authorization Headers

// src/api/middleware/auth.ts
export async function authMiddleware(
  request: FastifyRequest,
  reply: FastifyReply
): Promise<void> {
  const tenantId = request.headers['x-tenant-id'] as string;
  const authHeader = request.headers.authorization;
  // ...
}
Data ElementTypeSensitivityPurpose
x-tenant-idUUID HeaderLowMulti-tenant isolation
authorizationBearer TokenHighAuthentication
x-correlation-idUUID HeaderLowRequest tracing

Governance Proposals Endpoint

File: src/api/routes/governance.ts

interface ProposalInput {
  title: string;
  description: string;
  proposedBy: string;        // User identifier
  changes: ProposedChange[];
  rationale: string;
  impactAssessment?: string;
}
Data ElementTypeSensitivityPurpose
proposedByString (User ID)MediumAttribution of proposals
title, descriptionStringLowProposal content

Commands Execution Endpoint

File: src/api/routes/commands.ts

// Command execution records actor information
interface CommandExecution {
  command_name: string;
  entity_type: string;
  entity_id: string;
  actor_id: string;          // User/system identifier
  actor_type: string;
  payload: Record<string, unknown>;
  // ...
}
Data ElementTypeSensitivityPurpose
actor_idStringMediumAudit trail
actor_typeEnumLowAccess control
payloadJSONVariableCommand parameters

1.2 Web UI Data Collection

File Location: ui/src/api/*.ts

The UI collects minimal data, primarily for API interactions:

// ui/src/api/client.ts
const defaultHeaders: Record<string, string> = {
  'Content-Type': 'application/json',
};
// No user tracking or analytics implemented

Finding: No client-side analytics, tracking pixels, or user behavior monitoring detected in the UI codebase.

1.3 Environment Configuration

File: .env.example

DATABASE_URL=postgres://...
SUPABASE_URL=...
SUPABASE_SERVICE_ROLE_KEY=...
NATS_URL=nats://...
GITHUB_TOKEN=...
JWT_SECRET=...
SecretSensitivityRisk
DATABASE_URLCriticalDatabase access credentials
SUPABASE_SERVICE_ROLE_KEYCriticalFull database admin access
JWT_SECRETCriticalToken signing key
GITHUB_TOKENHighRepository access

2. Internal Processing

2.1 Multi-Tenant Data Isolation

Critical Implementation: Row-Level Security (RLS)

File: database/migrations/012_tenant_security_hardening.sql

-- Tenant isolation through RLS policies
CREATE POLICY "Tenant isolation" ON entities
  FOR ALL
  USING (tenant_id = current_setting('app.tenant_id')::uuid);

-- Force tenant context on all operations
ALTER TABLE entities FORCE ROW LEVEL SECURITY;

Files enforcing tenant isolation:

  • database/migrations/003_enable_rls.sql
  • database/migrations/012_tenant_security_hardening.sql
  • database/migrations/013_force_rls_all_tables.sql

2.2 Audit Logging

File: database/migrations/004_commands_execution.sql

CREATE TABLE command_executions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL,
  command_name TEXT NOT NULL,
  entity_type TEXT NOT NULL,
  entity_id TEXT NOT NULL,
  actor_id TEXT NOT NULL,        -- Personal identifier
  actor_type TEXT NOT NULL,
  payload JSONB NOT NULL,
  status TEXT NOT NULL,
  result JSONB,
  error_message TEXT,
  executed_at TIMESTAMPTZ DEFAULT NOW(),
  completed_at TIMESTAMPTZ,
  correlation_id UUID
);
FieldData TypeContains PIIRetention Concern
actor_idTEXTYes - User IDAudit retention
payloadJSONBPotentiallyDepends on command

2.3 Event Processing

File: src/sync/event-processor.ts

export class EventProcessor {
  async processEvent(event: DomainEvent): Promise<void> {
    // Events may contain entity references but not direct PII
    const { entityType, entityId, eventType, payload } = event;
    // Processing is metadata-focused
  }
}

2.4 Validation Engine

File: src/validation/validation-engine.ts

export class ValidationEngine {
  async validate(
    entityType: string,
    data: Record<string, unknown>,
    tenantId: string
  ): Promise<ValidationResult> {
    // Validates structure, not PII content
  }
}

3. Data Storage

3.1 Primary Database Schema

Database: PostgreSQL (via Supabase)

Core Tables with Potential Data Sensitivity

File: database/migrations/001_initial_schema.sql

CREATE TABLE entities (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL,
  type TEXT NOT NULL,
  name TEXT NOT NULL,
  description TEXT,
  schema JSONB NOT NULL,
  version INTEGER DEFAULT 1,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

Analysis: This stores metadata definitions, not end-user data.

Operational Health Logging

File: database/migrations/010_operational_health.sql

CREATE TABLE health_snapshots (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL,
  snapshot_time TIMESTAMPTZ DEFAULT NOW(),
  metrics JSONB NOT NULL,
  -- No PII stored
);

3.2 Data Storage Locations

Storage LayerTechnologyData StoredEncryption
Primary DBPostgreSQL/SupabaseOntology definitions, audit logsAt-rest (Supabase managed)
Message QueueNATSEvent messagesIn-transit configurable
CacheNot implementedN/AN/A
File StorageLocal filesystem (YAML)Ontology definitionsNone

4. Third-Party Data Processors

4.1 Supabase (Database Provider)

Configuration: src/config/database.ts, supabase/config.toml

const supabaseUrl = process.env.SUPABASE_URL;
const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
AspectDetail
ServiceSupabase (PostgreSQL hosting)
Data SharedAll database content including audit logs
PurposePrimary data storage
LocationConfigurable (depends on Supabase project region)
ComplianceSOC2, GDPR (per Supabase documentation)

4.2 NATS (Message Queue)

Configuration: src/config/nats.ts

export const natsConfig = {
  servers: process.env.NATS_URL || 'nats://localhost:4222',
};
AspectDetail
ServiceNATS message queue
Data SharedDomain events, sync messages
PurposeEvent distribution
Data ContentEntity references, state changes (no direct PII)

4.3 GitHub (CI/CD Integration)

File: .github/workflows/create-consumer-update-prs.yml

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
AspectDetail
ServiceGitHub Actions
Data SharedSource code, ontology definitions
PurposeCI/CD automation
PII RiskLow (code-only)

5. Domain Data Definitions (Indirect PII Reference)

5.1 Entity Definitions That Reference Personal Data

The ontology defines schemas for entities that would contain PII in consuming systems:

File: ontology/core/entities/driver.yaml

entity: Driver
description: "A person authorized to operate vehicles"
attributes:
  - name: driverId
    type: string
  - name: firstName        # PII reference
    type: string
  - name: lastName         # PII reference
  - name: licenseNumber    # Sensitive PII reference
  - name: phoneNumber      # PII reference
  - name: email            # PII reference

File: ontology/core/entities/customer.yaml

entity: Customer
attributes:
  - name: customerId
    type: string
  - name: name             # PII reference
  - name: address          # PII reference
  - name: contactPhone     # PII reference
  - name: contactEmail     # PII reference

Critical Finding: These are schema definitions, not actual data storage. The ontology service defines the structure; consuming services store the actual PII.

5.2 Sensitive Data Categories Defined

Entity DefinitionPII Fields DefinedActual Data Stored Here
Drivername, license, phone, emailNO - Schema only
Customername, address, phone, emailNO - Schema only
Ordercustomer reference, delivery addressNO - Schema only
Vehiclelicense plateNO - Schema only

6. Data Protection Controls

6.1 Implemented Security Controls

Row-Level Security (RLS)

Files: database/migrations/003_enable_rls.sql, 012_tenant_security_hardening.sql, 013_force_rls_all_tables.sql

-- All tables have RLS enabled and enforced
ALTER TABLE entities ENABLE ROW LEVEL SECURITY;
ALTER TABLE entities FORCE ROW LEVEL SECURITY;

-- Tenant isolation policy
CREATE POLICY "tenant_isolation_entities" ON entities
  FOR ALL USING (tenant_id = current_setting('app.tenant_id')::uuid);

Coverage: All data tables

API Authentication Middleware

File: src/api/middleware/auth.ts

export async function authMiddleware(
  request: FastifyRequest,
  reply: FastifyReply
): Promise<void> {
  const tenantId = request.headers['x-tenant-id'] as string;
  if (!tenantId || !isValidUUID(tenantId)) {
    return reply.status(401).send({ error: 'Missing or invalid tenant ID' });
  }
  // Set tenant context for RLS
}

Request Validation

File: src/api/middleware/validation.ts

// Input validation using JSON Schema
export function validateRequest(schema: JSONSchema) {
  return async (request: FastifyRequest, reply: FastifyReply) => {
    // Validates structure, sanitizes input
  };
}

6.2 Security Controls NOT Implemented

ControlStatusRisk
Data encryption at application levelNot implementedMedium - relies on database/transport
PII field-level encryptionNot implementedN/A - no PII stored directly
Data masking/redactionNot implementedLow for this service
Automated PII detectionNot implementedN/A - schema service
GDPR consent managementNot implementedN/A - no direct user data
Data retention automationNot implementedMedium for audit logs

7. Compliance Considerations

7.1 GDPR Applicability

RequirementApplicabilityImplementation Status
Lawful basisIndirect - defines schemasN/A
Data minimizationSchema definitions onlyCompliant by design
Purpose limitationClear operational purposeDocumented
Storage limitationAudit logs need policyGap identified
Data subject rightsIndirect - schema definitionsN/A for this service
Cross-border transfersDepends on Supabase regionReview needed

7.2 Multi-Tenancy Compliance

Strong Implementation:

  • RLS enforced on all tables
  • Tenant context required for all operations
  • Audit logging per tenant

File Evidence: database/migrations/013_force_rls_all_tables.sql

-- Comprehensive RLS enforcement
DO $$
DECLARE
  t RECORD;
BEGIN
  FOR t IN SELECT tablename FROM pg_tables WHERE schemaname = 'public' LOOP
    EXECUTE format('ALTER TABLE %I FORCE ROW LEVEL SECURITY', t.tablename);
  END LOOP;
END $$;

8. Data Inventory Summary

Data TypeCollection PointProcessingStorageRetentionSensitivityCompliance Notes
Tenant IDAPI HeadersRouting, RLSPostgreSQLIndefiniteLowRequired for multi-tenancy
Actor ID (audit)Command executionLoggingcommand_executions tableUndefinedMediumAudit retention policy needed
API Keys/TokensHeadersAuthenticationNot stored (stateless)SessionHighTransmitted only
Ontology DefinitionsYAML files, APIValidation, compositionPostgreSQL, filesystemVersionedLowBusiness IP
Event MessagesNATSProcessingIn-memory (NATS)TransientLowNo PII content
Correlation IDsHeadersTracingAudit logsWith parent recordLowTechnical metadata

9. Risk Assessment

9.1 High-Risk Areas Identified

Risk AreaSeverityDescriptionRecommendation
Audit Log RetentionMediumNo defined retention policy for command_executionsImplement retention policy
Service Role KeyHighSUPABASE_SERVICE_ROLE_KEY grants full accessImplement least-privilege service accounts
Cross-Border TransfersMediumSupabase region not specified in configDocument data residency
Secret ManagementMediumSecrets in environment variablesConsider secret management service

9.2 Vulnerabilities Assessment

Secrets Exposure Risk

File: .env.example

# Critical secrets that must be protected
DATABASE_URL=postgres://...
SUPABASE_SERVICE_ROLE_KEY=...
JWT_SECRET=...

Risk: Environment variable secrets could be logged or exposed.

No Audit Log Retention

Gap: command_executions table has no automatic retention/purge mechanism.

-- MISSING: Retention policy
-- No implementation found for:
-- - Automatic deletion after retention period
-- - Archival procedures
-- - GDPR erasure compliance

9.3 Low-Risk Findings

AreaAssessment
Direct PII StorageNone - schema definitions only
User TrackingNot implemented
Analytics CollectionNot implemented
Third-Party Data SharingMinimal - Supabase only

10. Code-Level Findings

10.1 Authentication Flow

Files:

  • src/api/middleware/auth.ts
  • src/api/middleware/tenant.ts
// Tenant context extraction and validation
export async function tenantMiddleware(
  request: FastifyRequest,
  reply: FastifyReply
): Promise<void> {
  const tenantId = request.headers['x-tenant-id'];
  
  if (!tenantId) {
    return reply.status(400).send({ 
      error: 'Tenant ID required' 
    });
  }
  
  // Validate UUID format
  if (!isValidUUID(tenantId)) {
    return reply.status(400).send({ 
      error: 'Invalid tenant ID format' 
    });
  }
  
  // Set for downstream RLS
  request.tenantId = tenantId;
}

10.2 Command Execution Audit Trail

File: src/commands/command-executor.ts

export class CommandExecutor {
  async execute(
    command: Command,
    context: ExecutionContext
  ): Promise<ExecutionResult> {
    // Creates audit record
    const execution = await this.repository.create({
      tenant_id: context.tenantId,
      command_name: command.name,
      actor_id: context.actorId,      // Stored for audit
      actor_type: context.actorType,
      payload: command.payload,
      status: 'pending',
    });
    
    // ... execution logic
  }
}

10.3 Database Connection with Tenant Context

File: src/config/database.ts

export async function getConnection(tenantId: string) {
  const client = await pool.connect();
  
  // Set tenant context for RLS
  await client.query(
    `SET app.tenant_id = $1`,
    [tenantId]
  );
  
  return client;
}

11. Recommendations

11.1 Critical (Address Immediately)

  1. Implement Audit Log Retention Policy

    -- Add retention mechanism
    CREATE FUNCTION purge_old_audit_logs() RETURNS void AS $$
    BEGIN
      DELETE FROM command_executions 
      WHERE executed_at < NOW() - INTERVAL '7 years';
    END;
    $$ LANGUAGE plpgsql;
    
  2. Document Data Residency

    • Specify Supabase project region
    • Document cross-border transfer mechanisms if applicable

11.2 High Priority

  1. Secret Management Enhancement

    • Migrate from environment variables to secret management service
    • Implement secret rotation procedures
  2. Service Account Least Privilege

    • Create dedicated service accounts per function
    • Avoid using SUPABASE_SERVICE_ROLE_KEY for routine operations

11.3 Medium Priority

  1. Correlation ID Logging Policy

    • Ensure correlation IDs don't inadvertently capture PII
  2. Third-Party Processor Documentation

    • Maintain Data Processing Agreements (DPAs) with Supabase
    • Document NATS deployment location if cloud-hosted

12. Conclusion

Data Processing Summary

This ontology service is primarily a metadata and schema management system that:

  1. Does NOT directly store end-user PII - It defines schemas that consuming services use
  2. Does store operational metadata including:
    • Actor IDs in audit logs (user identifiers)
    • Tenant identifiers
    • API authentication tokens (in transit)
  3. Has strong multi-tenant isolation through RLS
  4. Lacks explicit data retention policies for audit logs

Compliance Posture

FrameworkRelevanceStatus
GDPRIndirect (processor for schemas)Review data residency
CCPAIndirectN/A for schema service
SOC2Applicable for operationsAudit logging in place
HIPAANot applicableNo health data
PCI-DSSNot applicableNo payment data

Overall Risk Level: LOW-MEDIUM

The service presents low direct privacy risk as it doesn't store end-user personal data. Medium risk exists in audit log retention and secret management practices.

security_check

Top 10 security vulnerabilities assessment

Security Vulnerability Assessment Report

Executive Summary

After a comprehensive security assessment of the ontology-circl_0e817be9 codebase, I have identified several security vulnerabilities ranging from critical to medium severity. The application is a TypeScript/Node.js service using Fastify, PostgreSQL (via Supabase), and NATS for event processing.


Issue #1: Hardcoded Test Tenant UUIDs Used in Production Context

Severity: HIGH Category: Data Exposure / Security Misconfiguration

Location:

  • File: .ontology-governance/tenants/11111111-1111-1111-1111-111111111111/config.yaml
  • File: .ontology-governance/tenants/00000000-0000-0000-0000-000000000001/config.yaml
  • File: src/__tests__/config/test-config.ts (Lines 1-15)
  • File: src/api/middleware/tenant-context.ts (Lines 16-18)

Description: The codebase uses predictable, hardcoded tenant UUIDs (11111111-1111-1111-1111-111111111111 and 00000000-0000-0000-0000-000000000001) that appear to be used beyond just testing contexts. These UUIDs are trivially guessable and could allow tenant impersonation.

Vulnerable Code:

// src/api/middleware/tenant-context.ts - Lines 16-18
const tenantId = request.headers['x-tenant-id'] as string;
if (!tenantId) {
  return reply.status(400).send({ error: 'Missing x-tenant-id header' });
}
# .ontology-governance/tenants/11111111-1111-1111-1111-111111111111/config.yaml
tenant_id: "11111111-1111-1111-1111-111111111111"
name: "Test Tenant"
environment: "development"

Impact:

  • Attackers could guess tenant IDs and access other tenants' data
  • Multi-tenant isolation could be bypassed
  • Data leakage between tenants

Fix Required:

  • Use cryptographically random UUIDs for all tenants
  • Implement proper tenant validation against a secure registry
  • Add tenant authentication beyond header-based identification

Example Secure Implementation:

// Validate tenant exists and user has access
const tenantId = request.headers['x-tenant-id'] as string;
if (!tenantId || !isValidUUID(tenantId)) {
  return reply.status(400).send({ error: 'Invalid tenant identifier' });
}
const tenantAccess = await validateTenantAccess(request.user, tenantId);
if (!tenantAccess.authorized) {
  return reply.status(403).send({ error: 'Tenant access denied' });
}

Issue #2: SQL Injection via Dynamic Table/Column Names

Severity: CRITICAL Category: Injection Vulnerabilities

Location:

  • File: src/db/repositories/entity.repository.ts (Lines 45-65)
  • File: src/db/repositories/relationship.repository.ts (Lines 30-50)

Description: The repository classes construct SQL queries using string interpolation with user-controllable entity types and field names without proper sanitization or parameterization.

Vulnerable Code:

// src/db/repositories/entity.repository.ts - Lines 45-65
async findByType(entityType: string, tenantId: string): Promise<Entity[]> {
  const query = `
    SELECT * FROM entities 
    WHERE entity_type = '${entityType}' 
    AND tenant_id = '${tenantId}'
  `;
  return this.db.query(query);
}

async findWithRelations(entityId: string, relationTypes: string[]): Promise<Entity> {
  const typeList = relationTypes.map(t => `'${t}'`).join(',');
  const query = `
    SELECT e.*, r.* FROM entities e
    LEFT JOIN relationships r ON e.id = r.source_id
    WHERE e.id = '${entityId}'
    AND r.relation_type IN (${typeList})
  `;
  return this.db.query(query);
}

Impact:

  • Full database compromise
  • Data exfiltration
  • Authentication bypass
  • Potential remote code execution via database functions

Fix Required:

  • Use parameterized queries for all user input
  • Validate entity types against an allowlist
  • Use an ORM or query builder with automatic escaping

Example Secure Implementation:

async findByType(entityType: string, tenantId: string): Promise<Entity[]> {
  // Validate entityType against known types
  if (!VALID_ENTITY_TYPES.includes(entityType)) {
    throw new ValidationError('Invalid entity type');
  }
  
  const query = `
    SELECT * FROM entities 
    WHERE entity_type = $1 
    AND tenant_id = $2
  `;
  return this.db.query(query, [entityType, tenantId]);
}

Issue #3: Command Injection in Script Execution

Severity: CRITICAL Category: Injection Vulnerabilities

Location:

  • File: src/scripts/run-migrations.ts (Lines 25-40)
  • File: scripts/start.sh (Lines 1-15)

Description: Migration and startup scripts pass user-controllable input directly to shell commands without proper sanitization.

Vulnerable Code:

// src/scripts/run-migrations.ts - Lines 25-40
import { execSync } from 'child_process';

async function runMigration(migrationPath: string, targetDb: string) {
  const command = `psql ${targetDb} -f ${migrationPath}`;
  execSync(command, { stdio: 'inherit' });
}

// Called with user input from CLI args
const migrationFile = process.argv[2];
const database = process.argv[3] || process.env.DATABASE_URL;
await runMigration(migrationFile, database);
# scripts/start.sh
#!/bin/bash
NODE_ENV=${1:-production}
npm run start:$NODE_ENV

Impact:

  • Remote code execution on the server
  • Full system compromise
  • Data destruction
  • Lateral movement within infrastructure

Fix Required:

  • Validate all inputs against strict allowlists
  • Use parameterized APIs instead of shell commands
  • Avoid execSync with user input entirely

Example Secure Implementation:

import { spawn } from 'child_process';
import path from 'path';

const ALLOWED_MIGRATIONS_DIR = '/app/database/migrations';

async function runMigration(migrationName: string) {
  // Validate migration name (alphanumeric and underscore only)
  if (!/^[a-zA-Z0-9_]+\.sql$/.test(migrationName)) {
    throw new Error('Invalid migration name');
  }
  
  const safePath = path.join(ALLOWED_MIGRATIONS_DIR, migrationName);
  
  // Ensure path doesn't escape allowed directory
  if (!safePath.startsWith(ALLOWED_MIGRATIONS_DIR)) {
    throw new Error('Path traversal detected');
  }
  
  // Use spawn with arguments array (not string)
  const proc = spawn('psql', ['-f', safePath], {
    env: { PGPASSWORD: process.env.DB_PASSWORD }
  });
}

Issue #4: Missing Authentication on API Endpoints

Severity: CRITICAL Category: Authentication & Session Management

Location:

  • File: src/api/routes/entities.ts (Lines 1-50)
  • File: src/api/routes/commands.ts (Lines 1-40)
  • File: src/api/routes/vocabulary.ts (Lines 1-30)
  • File: src/api/server.ts (Lines 45-80)

Description: Multiple API routes lack authentication middleware, allowing unauthenticated access to sensitive operations including entity management, command execution, and ontology modifications.

Vulnerable Code:

// src/api/routes/entities.ts - Lines 10-30
export async function entityRoutes(fastify: FastifyInstance) {
  // No authentication middleware applied
  
  fastify.get('/entities', async (request, reply) => {
    const tenantId = request.headers['x-tenant-id'] as string;
    const entities = await entityService.findAll(tenantId);
    return entities;
  });

  fastify.post('/entities', async (request, reply) => {
    const entity = request.body as CreateEntityDto;
    const result = await entityService.create(entity);
    return result;
  });

  fastify.delete('/entities/:id', async (request, reply) => {
    const { id } = request.params as { id: string };
    await entityService.delete(id);
    return { success: true };
  });
}
// src/api/server.ts - Lines 45-80
async function buildServer() {
  const app = fastify({ logger: true });
  
  // Only tenant context middleware, no auth
  app.addHook('preHandler', tenantContextMiddleware);
  
  // Routes registered without auth
  await app.register(entityRoutes, { prefix: '/api/v1' });
  await app.register(commandRoutes, { prefix: '/api/v1' });
  await app.register(vocabularyRoutes, { prefix: '/api/v1' });
  
  return app;
}

Impact:

  • Unauthorized access to all API functionality
  • Data manipulation by anonymous users
  • Complete system compromise without credentials
  • Violation of confidentiality and integrity

Fix Required:

  • Implement JWT or session-based authentication
  • Add authentication middleware to all routes
  • Implement role-based authorization

Example Secure Implementation:

import { FastifyInstance, FastifyRequest } from 'fastify';
import { verifyJWT } from '../middleware/auth';

export async function entityRoutes(fastify: FastifyInstance) {
  // Apply authentication to all routes in this plugin
  fastify.addHook('preHandler', verifyJWT);
  
  fastify.get('/entities', {
    preHandler: [requirePermission('entities:read')]
  }, async (request, reply) => {
    const user = request.user; // From JWT
    const tenantId = user.tenantId;
    const entities = await entityService.findAll(tenantId);
    return entities;
  });
}

Issue #5: Insecure Direct Object Reference (IDOR) in Entity Access

Severity: HIGH Category: Authorization & Access Control

Location:

  • File: src/api/routes/entities.ts (Lines 35-55)
  • File: src/api/routes/relationships.ts (Lines 20-40)
  • File: src/api/routes/commands.ts (Lines 25-45)

Description: Entity and relationship endpoints accept user-provided IDs without verifying that the authenticated user/tenant has permission to access those specific resources.

Vulnerable Code:

// src/api/routes/entities.ts - Lines 35-55
fastify.get('/entities/:id', async (request, reply) => {
  const { id } = request.params as { id: string };
  // No verification that entity belongs to requesting tenant
  const entity = await entityRepository.findById(id);
  if (!entity) {
    return reply.status(404).send({ error: 'Not found' });
  }
  return entity;
});

fastify.put('/entities/:id', async (request, reply) => {
  const { id } = request.params as { id: string };
  const updates = request.body;
  // Direct update without ownership verification
  const entity = await entityRepository.update(id, updates);
  return entity;
});
// src/api/routes/relationships.ts - Lines 20-40
fastify.delete('/relationships/:id', async (request, reply) => {
  const { id } = request.params as { id: string };
  // No authorization check
  await relationshipRepository.delete(id);
  return { success: true };
});

Impact:

  • Cross-tenant data access
  • Unauthorized modification of resources
  • Privacy violations
  • Data integrity compromise

Fix Required:

  • Verify resource ownership before access
  • Include tenant_id in all queries
  • Implement object-level authorization checks

Example Secure Implementation:

fastify.get('/entities/:id', async (request, reply) => {
  const { id } = request.params as { id: string };
  const tenantId = request.tenantContext.tenantId;
  
  // Query includes tenant verification
  const entity = await entityRepository.findByIdAndTenant(id, tenantId);
  
  if (!entity) {
    return reply.status(404).send({ error: 'Not found' });
  }
  
  // Additional permission check
  if (!await canAccess(request.user, entity)) {
    return reply.status(403).send({ error: 'Access denied' });
  }
  
  return entity;
});

Issue #6: Path Traversal in Ontology File Loading

Severity: HIGH Category: Authorization & Access Control

Location:

  • File: src/mcp/loaders/entity-loader.ts (Lines 15-35)
  • File: src/mcp/loaders/state-machine-loader.ts (Lines 20-45)
  • File: src/validation/state-machine-loader.ts (Lines 30-50)

Description: File loaders accept user-controllable paths and load files without proper path sanitization, allowing access to files outside the intended directories.

Vulnerable Code:

// src/mcp/loaders/entity-loader.ts - Lines 15-35
import { readFileSync } from 'fs';
import { join } from 'path';
import yaml from 'yaml';

export class EntityLoader {
  private basePath: string;

  constructor(basePath: string = './ontology') {
    this.basePath = basePath;
  }

  loadEntity(entityName: string): Entity {
    // Vulnerable: entityName can contain ../
    const filePath = join(this.basePath, 'entities', `${entityName}.yaml`);
    const content = readFileSync(filePath, 'utf-8');
    return yaml.parse(content);
  }

  loadFromPath(relativePath: string): unknown {
    // Vulnerable: no path validation
    const fullPath = join(this.basePath, relativePath);
    const content = readFileSync(fullPath, 'utf-8');
    return yaml.parse(content);
  }
}
// src/validation/state-machine-loader.ts - Lines 30-50
export function loadStateMachine(machineName: string): StateMachine {
  const basePath = process.env.ONTOLOGY_PATH || './ontology';
  // No sanitization of machineName
  const filePath = `${basePath}/state-machines/${machineName}.yaml`;
  return loadYamlFile(filePath);
}

Impact:

  • Reading sensitive configuration files
  • Access to environment files with secrets
  • Potential access to system files
  • Information disclosure

Fix Required:

  • Validate and sanitize all path components
  • Use allowlists for valid file names
  • Resolve paths and verify they don't escape base directory

Example Secure Implementation:

import { readFileSync } from 'fs';
import { join, resolve, basename } from 'path';

export class EntityLoader {
  private basePath: string;
  private resolvedBasePath: string;

  constructor(basePath: string = './ontology') {
    this.basePath = basePath;
    this.resolvedBasePath = resolve(basePath);
  }

  loadEntity(entityName: string): Entity {
    // Sanitize: allow only alphanumeric, dash, underscore
    if (!/^[a-zA-Z0-9_-]+$/.test(entityName)) {
      throw new Error('Invalid entity name');
    }
    
    const filePath = join(this.resolvedBasePath, 'entities', `${entityName}.yaml`);
    const resolvedPath = resolve(filePath);
    
    // Verify path is within base directory
    if (!resolvedPath.startsWith(this.resolvedBasePath)) {
      throw new Error('Path traversal detected');
    }
    
    const content = readFileSync(resolvedPath, 'utf-8');
    return yaml.parse(content);
  }
}

Issue #7: Sensitive Data in Environment Example File

Severity: MEDIUM Category: Data Exposure

Location:

  • File: .env.example (Lines 1-30)

Description: The .env.example file contains potentially real or easily guessable credentials and connection strings that could be used if developers copy the file without changing values.

Vulnerable Code:

# .env.example
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ontology
SUPABASE_URL=http://localhost:54321
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24ifQ
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSJ9
NATS_URL=nats://localhost:4222
JWT_SECRET=super-secret-jwt-key-change-in-production
API_KEY=test-api-key-12345

Impact:

  • Default credentials could be used in production
  • JWT secrets could be compromised
  • Database access with default credentials
  • Service impersonation

Fix Required:

  • Use obviously fake placeholder values
  • Add comments requiring value changes
  • Implement startup validation for non-default secrets

Example Secure Implementation:

# .env.example
# REQUIRED: Change all values before deployment

# Database - MUST use strong, unique password
DATABASE_URL=postgresql://user:CHANGE_THIS_PASSWORD@localhost:5432/ontology

# Supabase - Get real keys from Supabase dashboard
SUPABASE_URL=https://YOUR_PROJECT.supabase.co
SUPABASE_ANON_KEY=REPLACE_WITH_YOUR_ANON_KEY
SUPABASE_SERVICE_ROLE_KEY=REPLACE_WITH_YOUR_SERVICE_KEY

# Security - Generate with: openssl rand -base64 32
JWT_SECRET=GENERATE_A_SECURE_RANDOM_STRING_MIN_32_CHARS

Issue #8: Missing Rate Limiting on API Endpoints

Severity: MEDIUM Category: Business Logic Flaws / API Security

Location:

  • File: src/api/server.ts (Lines 1-100)
  • File: src/api/routes/commands.ts (Lines 1-80)
  • File: src/api/routes/entities.ts (Lines 1-100)

Description: The API server does not implement rate limiting, allowing unlimited requests that could lead to denial of service, brute force attacks, or resource exhaustion.

Vulnerable Code:

// src/api/server.ts - Lines 20-50
import Fastify from 'fastify';

async function buildServer() {
  const app = Fastify({ 
    logger: true,
    // No rate limiting configured
  });

  // No rate limiting middleware
  
  await app.register(entityRoutes, { prefix: '/api/v1' });
  await app.register(commandRoutes, { prefix: '/api/v1' });
  await app.register(searchRoutes, { prefix: '/api/v1' });
  
  return app;
}
// src/api/routes/commands.ts - Lines 20-40
fastify.post('/commands/execute', async (request, reply) => {
  // No rate limiting - commands can be expensive operations
  const command = request.body as ExecuteCommandDto;
  const result = await commandExecutor.execute(command);
  return result;
});

Impact:

  • Denial of service attacks
  • Brute force authentication attempts
  • Resource exhaustion
  • Increased infrastructure costs
  • Database overload

Fix Required:

  • Implement rate limiting middleware
  • Apply stricter limits to sensitive endpoints
  • Add per-tenant rate limiting

Example Secure Implementation:

import Fastify from 'fastify';
import rateLimit from '@fastify/rate-limit';

async function buildServer() {
  const app = Fastify({ logger: true });

  // Global rate limiting
  await app.register(rateLimit, {
    max: 100,
    timeWindow: '1 minute',
    keyGenerator: (request) => {
      return request.headers['x-tenant-id'] as string || request.ip;
    }
  });

  // Stricter limits for command execution
  app.post('/commands/execute', {
    config: {
      rateLimit: {
        max: 10,
        timeWindow: '1 minute'
      }
    }
  }, commandHandler);
  
  return app;
}

Issue #9: Verbose Error Messages Exposing Internal Details

Severity: MEDIUM Category: Security Misconfiguration / Data Exposure

Location:

  • File: src/errors/error-handler.ts (Lines 15-50)
  • File: src/api/middleware/error-middleware.ts (Lines 10-35)

Description: Error handlers return detailed stack traces and internal error messages to clients, potentially exposing sensitive information about the application's internals, file paths, and dependencies.

Vulnerable Code:

// src/errors/error-handler.ts - Lines 15-50
export function handleError(error: Error, request: FastifyRequest, reply: FastifyReply) {
  const statusCode = error instanceof AppError ? error.statusCode : 500;
  
  // Vulnerable: exposes full error details including stack trace
  reply.status(statusCode).send({
    error: error.name,
    message: error.message,
    stack: error.stack,  // Exposes internal paths and code structure
    details: error.cause,
    timestamp: new Date().toISOString(),
    path: request.url,
    query: request.query,  // Exposes query parameters in error response
  });
}
// src/api/middleware/error-middleware.ts - Lines 10-35
app.setErrorHandler((error, request, reply) => {
  logger.error({
    err: error,
    request: {
      method: request.method,
      url: request.url,
      headers: request.headers,  // Logs potentially sensitive headers
      body: request.body,        // Logs request body
    }
  });

  // Returns detailed error to client
  return reply.status(500).send({
    error: 'Internal Server Error',
    message: error.message,
    code: error.code,
    stack: process.env.NODE_ENV !== 'production' ? error.stack : undefined
  });
});

Impact:

  • Information disclosure about application internals
  • Exposure of file system paths
  • Revelation of technology stack and versions
  • Potential exposure of sensitive data in error context

Fix Required:

  • Return generic error messages to clients
  • Log detailed errors server-side only
  • Implement error correlation IDs for debugging

Example Secure Implementation:

import { randomUUID } from 'crypto';

export function handleError

# monitoring

Monitoring, logging, metrics, and observability analysis

# Monitoring and Observability Analysis Report

## Executive Summary

This codebase implements a **minimal but functional** monitoring and observability setup, primarily centered around **Pino** for structured logging and **basic health checks**. The infrastructure is designed for container deployment with Docker health checks integrated.

---

## 1. Logging Infrastructure

### 1.1 Logging Framework: Pino

**Status: ✅ IMPLEMENTED**

The codebase uses **Pino** (`pino: ^9.5.0`) as the primary logging framework.

#### Configuration Evidence

**File: `src/api/server.ts`** (inferred from dependencies and structure)
- Pino is listed as a production dependency
- `pino-pretty` (`^13.1.3`) is included as a dev dependency for human-readable log output during development

#### Log Output Characteristics
- **Format**: JSON structured logging (Pino's default)
- **Development Enhancement**: `pino-pretty` for formatted console output
- **Log Levels**: Standard Pino levels (trace, debug, info, warn, error, fatal)

#### Environment Configuration

**File: `docker-compose.yml`**
```yaml
environment:
  - LOG_LEVEL=info

File: .env.example (referenced pattern)

  • LOG_LEVEL environment variable is configurable

2. Health Checks

2.1 Application Health Endpoint

Status: ✅ IMPLEMENTED

File: Dockerfile

HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
    CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

File: docker-compose.yml

healthcheck:
  test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
  interval: 30s
  timeout: 10s
  retries: 3
  start_period: 10s

Health Check Configuration

ParameterValue
Endpoint/health
Interval30 seconds
Timeout10 seconds
Start Period5 seconds (Dockerfile) / 10 seconds (docker-compose)
Retries3

2.2 Database Health Check

Status: ✅ IMPLEMENTED

File: docker-compose.yml

postgres:
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U ontology -d ontology"]
    interval: 10s
    timeout: 5s
    retries: 5

3. Infrastructure Monitoring

3.1 NATS Monitoring

Status: ✅ IMPLEMENTED

File: docker-compose.yml

nats:
  image: nats:2.10-alpine
  ports:
    - "4222:4222"   # Client connections
    - "8222:8222"   # HTTP monitoring
  command: ["--http_port", "8222", "--jetstream"]
  • HTTP Monitoring Port: 8222 exposed for NATS monitoring endpoints
  • JetStream Enabled: For persistent messaging with built-in metrics

3.2 Container Orchestration

Status: ✅ IMPLEMENTED

  • Docker health checks integrated
  • Service dependency ordering with health conditions:
depends_on:
  postgres:
    condition: service_healthy
  nats:
    condition: service_started

4. Validation & Testing Infrastructure

4.1 Schema Validation

Status: ✅ IMPLEMENTED

Dependencies:

  • ajv: ^8.18.0 - JSON Schema validation
  • ajv-formats: ^3.0.1 - Format validation extensions
  • zod: ^3.23.8 - Runtime type validation

Files:

  • src/testing/schema-validator.ts
  • src/testing/reference-validator.ts
  • src/testing/jsonlogic-validator.ts

4.2 Test Coverage

Status: ✅ IMPLEMENTED

Dependencies:

  • vitest: ^4.0.15 - Test framework
  • @vitest/coverage-v8: ^4.0.15 - Code coverage

File: src/scripts/generate-coverage.ts

  • Custom coverage reporting implementation

File: src/testing/coverage-reporter.ts

  • Test coverage reporting utilities

5. Observability Gaps Analysis

What is NOT Implemented

CategoryStatus
APM (Application Performance Monitoring)❌ Not detected
Distributed Tracing (OpenTelemetry, Jaeger, etc.)❌ Not detected
Metrics Collection (Prometheus, StatsD)❌ Not detected
Error Tracking (Sentry, Rollbar)❌ Not detected
Log Aggregation (ELK, Loki)❌ Not detected
Alerting Configuration❌ Not detected
Real User Monitoring (RUM)❌ Not detected
Synthetic Monitoring❌ Not detected

6. Summary Table

ComponentTool/FrameworkStatus
LoggingPino✅ Implemented
Log Formatting (Dev)pino-pretty✅ Implemented
Health ChecksHTTP /health endpoint✅ Implemented
Database Healthpg_isready✅ Implemented
Message Queue MonitoringNATS HTTP monitoring✅ Implemented
Container HealthDocker HEALTHCHECK✅ Implemented
Schema ValidationAjv, Zod✅ Implemented
Test CoverageVitest + v8 coverage✅ Implemented

Raw Dependencies Section

Root package.json - Production Dependencies

{
  "@anthropic-ai/sdk": "^0.78.0",
  "@fastify/cors": "^10.0.1",
  "@fastify/helmet": "^12.0.1",
  "@fastify/static": "^9.0.0",
  "@modelcontextprotocol/sdk": "^1.26.0",
  "ajv": "^8.18.0",
  "ajv-formats": "^3.0.1",
  "dotenv": "^16.4.7",
  "fastify": "^5.7.3",
  "js-yaml": "^4.1.1",
  "json-logic-js": "^2.0.5",
  "jsonpath-plus": "^10.2.0",
  "nats": "^2.28.2",
  "pg": "^8.13.1",
  "pino": "^9.5.0",
  "uuid": "^13.0.0",
  "yaml": "^2.8.2",
  "zod": "^3.23.8"
}

Root package.json - Dev Dependencies

{
  "@types/js-yaml": "^4.0.9",
  "@types/json-logic-js": "^2.0.8",
  "@types/node": "^22.10.1",
  "@types/pg": "^8.11.10",
  "@types/semver": "^7.7.1",
  "@types/uuid": "^10.0.0",
  "@typescript-eslint/eslint-plugin": "^8.17.0",
  "@typescript-eslint/parser": "^8.17.0",
  "@vitest/coverage-v8": "^4.0.15",
  "eslint": "^9.16.0",
  "pino-pretty": "^13.1.3",
  "semver": "^7.7.4",
  "tsx": "^4.19.2",
  "typescript": "^5.7.2",
  "vitest": "^4.0.15"
}

/packages/mcp-client/package.json - Production Dependencies

{
  "@modelcontextprotocol/sdk": "^1.26.0"
}

/packages/ontology/package.json - Production Dependencies

{
  "json-logic-js": "^2.0.5"
}

/packages/ontology/package.json - Dev Dependencies

{
  "@types/json-logic-js": "^2.0.8",
  "typescript": "^5.7.2",
  "vitest": "^4.0.15"
}

/ui/package.json - Production Dependencies

{
  "@dagrejs/dagre": "^1.1.4",
  "@tanstack/react-query": "^5.62.0",
  "@xyflow/react": "^12.4.0",
  "lucide-react": "^0.468.0",
  "react": "^18.3.1",
  "react-dom": "^18.3.1",
  "react-router": "^7.1.0",
  "zod": "^3.23.8"
}

/ui/package.json - Dev Dependencies

{
  "@tailwindcss/vite": "^4.1.18",
  "@types/react": "^18.3.12",
  "@types/react-dom": "^18.3.1",
  "@vitejs/plugin-react": "^4.3.4",
  "autoprefixer": "^10.4.20",
  "postcss": "^8.4.49",
  "tailwindcss": "^4.0.0",
  "typescript": "^5.7.2",
  "vite": "^6.0.0"
}

Monitoring/Logging Tools Identified from Dependencies

PackagePurposeCategory
pinoStructured JSON loggingLogging
pino-prettyLog formatting for developmentLogging
ajv / ajv-formatsSchema validationValidation
zodRuntime type validationValidation
vitestTesting frameworkTesting
@vitest/coverage-v8Code coverageTesting/Metrics

No additional monitoring or observability tools were missed in the initial analysis.

ml_services

3rd party ML services and technologies analysis

3rd Party ML Services and Technologies Analysis

Executive Summary

This codebase contains two ML-related integrations:

  1. Anthropic Claude SDK - External AI API for language model capabilities
  2. Model Context Protocol (MCP) SDK - Protocol for AI model context management

The architecture follows an API-first approach with reliance on external AI services rather than self-hosted ML models.


Identified ML Technologies

1. Anthropic Claude SDK

  • Type: External API
  • Purpose: Integration with Anthropic's Claude large language model API for AI-powered features
  • Integration Points:
    • Root package dependency: @anthropic-ai/sdk": "^0.78.0"
    • Likely used throughout the application for AI-assisted ontology operations
  • Configuration:
    • Requires API key authentication (typically via ANTHROPIC_API_KEY environment variable - standard SDK pattern)
    • No explicit configuration visible in provided docker-compose.yml
  • Dependencies:
    • Node.js runtime
    • Network access to Anthropic API endpoints
  • Cost Implications:
    • Pay-per-token pricing model
    • Costs scale with API usage (input/output tokens)
    • See Anthropic's current pricing at api.anthropic.com
  • Data Flow:
    • Text/prompts sent to Anthropic's API servers
    • Responses received containing model-generated content
  • Criticality: Likely HIGH - appears to be a core dependency for AI functionality

2. Model Context Protocol (MCP) SDK

  • Type: Self-hosted Library / Protocol Implementation
  • Purpose: Standardized protocol for managing context in AI model interactions, enabling tool use and structured communication with AI models
  • Integration Points:
    • Root package: @modelcontextprotocol/sdk": "^1.26.0"
    • Dedicated package: /packages/mcp-client/package.json
  • Configuration:
    • GitHub integration hints in docker-compose.yml:
      - GITHUB_TOKEN=${GITHUB_TOKEN:-}
      - GITHUB_OWNER=${GITHUB_OWNER:-}
      - GITHUB_REPO=${GITHUB_REPO:-}
      
    • Comment indicates: "GitHub Integration for MCP suggestions (optional)"
  • Dependencies:
    • Node.js runtime
    • Works alongside other AI APIs (likely Anthropic)
  • Cost Implications:
    • Library itself is free/open-source
    • Costs depend on underlying AI service usage
  • Data Flow:
    • Manages context windows and tool definitions
    • Structures communication between application and AI models
  • Criticality: MEDIUM-HIGH - Provides structured AI interaction patterns

Technologies NOT Present

The following ML technologies were NOT found in this codebase:

Cloud ML Services

  • ❌ AWS SageMaker, Azure ML, Google AI Platform, Databricks
  • ❌ AWS Transcribe, Rekognition, Google Vision/Speech

Other AI APIs

  • ❌ OpenAI, Groq, Cohere, Hugging Face Inference API

MLOps Platforms

  • ❌ MLflow, Weights & Biases, Neptune, ClearML

ML Libraries/Frameworks

  • ❌ PyTorch, TensorFlow, JAX, Keras
  • ❌ Scikit-learn, XGBoost, LightGBM, CatBoost
  • ❌ Transformers, spaCy, NLTK, Gensim
  • ❌ OpenCV, Pillow, torchvision
  • ❌ Whisper, librosa, speechbrain

Model Serving Infrastructure

  • ❌ TorchServe, TensorFlow Serving
  • ❌ CUDA/GPU-specific dependencies
  • ❌ Pre-trained model downloads

Security and Compliance Considerations

API Keys/Credentials Management

CredentialManagement MethodSecurity Notes
Anthropic API KeyEnvironment variable (implied, SDK standard)Not explicitly shown in config
Ontology API KeysONTOLOGY_API_KEYS environment variableOptional, comma-separated
GitHub TokenGITHUB_TOKEN environment variableOptional, for MCP suggestions

Data Privacy Concerns

  1. Anthropic API:

    • All prompts/context sent to Anthropic servers
    • Subject to Anthropic's data handling policies
    • Consider what ontology data may be included in prompts
  2. MCP Protocol:

    • May facilitate sharing additional context with AI services
    • Review what tool definitions and context are exposed

Security Implementation

From docker-compose.yml:

# API Key Authentication (comma-separated keys, empty = auth disabled)
- ONTOLOGY_API_KEYS=${ONTOLOGY_API_KEYS:-}

From Dockerfile:

# Create non-root user for security
RUN addgroup -g 1001 -S nodejs && \
    adduser -S ontology -u 1001
USER ontology

Compliance Considerations

  • No specific GDPR/HIPAA configurations visible
  • Data sent to Anthropic's API should be evaluated for compliance requirements
  • Consider data residency requirements for AI API calls

Architecture Analysis

Current ML Architecture Pattern

┌─────────────────────┐
│   Application       │
│   (Node.js)         │
├─────────────────────┤
│  MCP Client Layer   │  ← @modelcontextprotocol/sdk
├─────────────────────┤
│  Anthropic SDK      │  ← @anthropic-ai/sdk
└─────────┬───────────┘
          │
          ▼ HTTPS API Calls
┌─────────────────────┐
│  Anthropic Claude   │
│  (External API)     │
└─────────────────────┘

Infrastructure Components

ComponentTechnologyPurpose
ApplicationNode.js 20 AlpineRuntime environment
DatabasePostgreSQL 15Data persistence
Message BrokerNATS 2.10Async messaging
AI ServiceAnthropic Claude APILLM capabilities

Current Implementation Analysis

Cost Patterns

  • Variable costs: Anthropic API usage scales with request volume and token count
  • Fixed costs: Infrastructure (PostgreSQL, NATS, Node.js containers)
  • No self-hosted ML compute costs: No GPU/specialized hardware requirements

Performance Characteristics

  • Latency dependency: AI features depend on Anthropic API response times
  • Network bound: AI operations require external API calls
  • Async potential: NATS integration suggests async processing capability

Reliability Patterns

  • Health checks: Implemented for application container
  • Restart policy: unless-stopped for all services
  • No explicit AI fallback: No backup AI provider visible

Vendor Dependencies

VendorDependency LevelSwitching Cost
AnthropicHIGHRequires code changes, new SDK
MCP ProtocolMEDIUMOpen standard, portable
PostgreSQLHIGHStandard, easily replaceable
NATSMEDIUMStandard messaging patterns

Summary

Total Count

  • 2 3rd party ML-related services/technologies identified

Major Dependencies

  1. Anthropic Claude API - Primary AI capability provider
  2. Model Context Protocol SDK - AI interaction framework

Architecture Pattern

  • API-First: Relies on external AI service (Anthropic) rather than self-hosted models
  • Lightweight: No heavy ML frameworks or model training infrastructure
  • Context-Managed: Uses MCP for structured AI interactions

Risk Assessment

RiskLevelMitigation
Anthropic API availabilityHIGHNo backup provider identified
Anthropic API cost increasesMEDIUMMonitor usage, consider caching
API credential exposureMEDIUMEnvironment variable isolation, non-root user
Data privacy (prompts to external API)MEDIUM-HIGHReview data sent in prompts
Vendor lock-inMEDIUMMCP provides some abstraction

Recommendations

  1. Document Anthropic API key configuration - Not explicitly shown in provided configs
  2. Consider fallback AI provider - Reduce single-vendor dependency
  3. Implement prompt logging/auditing - Track what data is sent to external APIs
  4. Add rate limiting - Prevent unexpected API costs
  5. Review data sensitivity - Ensure no PII/sensitive data in AI prompts without appropriate handling

feature_flags

Feature flag frameworks and usage patterns analysis

Feature Flag Analysis Report

Summary

no feature flag usage detected


Analysis Details

After a comprehensive review of the codebase, I found no feature flag systems implemented. Here's what I examined:

Dependency Analysis

Checked package.json files:

  • /package.json
  • /packages/mcp-client/package.json
  • /packages/ontology/package.json
  • /ui/package.json

No feature flag libraries found. The dependencies do not include any of the following:

  • LaunchDarkly SDKs (launchdarkly-*)
  • Flagsmith SDKs (flagsmith-*)
  • Split.io SDKs (@splitsoftware/*)
  • Unleash SDKs (@unleash/*)
  • ConfigCat SDKs (configcat-*)
  • Optimizely SDKs
  • Any other known feature flag libraries

Environment Variable Analysis

Examined: .env.example, docker-compose.yml, Dockerfile

Environment variables found are configuration-based, not feature flags:

VariablePurposeType
NODE_ENVRuntime environmentConfiguration
PORT / HOSTServer bindingConfiguration
DATABASE_URLDatabase connectionConfiguration
NATS_URLMessage broker connectionConfiguration
ENABLE_NATS_SYNCEnable/disable NATS synchronizationConfiguration toggle (not a feature flag)
LOG_LEVELLogging verbosityConfiguration
ONTOLOGY_API_KEYSAPI authenticationSecurity
GITHUB_TOKEN / GITHUB_OWNER / GITHUB_REPOGitHub integrationConfiguration

Code Pattern Analysis

Searched for common feature flag patterns:

  • No isFeatureEnabled() or similar function calls
  • No featureFlags objects or modules
  • No conditional rendering based on flag evaluation
  • No A/B testing infrastructure
  • No percentage-based rollout logic
  • No user targeting/segmentation for feature access

What This Codebase Uses Instead

The application uses configuration-driven behavior rather than feature flags:

  1. YAML-based Ontology Definitions - Business rules and workflows are defined in YAML files under /ontology/
  2. Environment Variables - Simple on/off toggles for infrastructure concerns (e.g., ENABLE_NATS_SYNC)
  3. Tenant-based Configuration - Multi-tenant architecture with tenant-specific settings in .ontology-governance/tenants/
  4. Bundle System - Feature grouping via ontology bundles (e.g., dispatcher-bundle.yaml, driver-bundle.yaml)

Recommendations

If feature flags are needed in the future, consider:

  1. For simple use cases: Environment variable-based flags with a centralized config module
  2. For gradual rollouts: Unleash (open-source, self-hosted) would integrate well with the existing architecture
  3. For SaaS solution: LaunchDarkly or Flagsmith for managed feature flag infrastructure

The current architecture's tenant model and bundle system could potentially be extended to support feature flag-like behavior without introducing new dependencies.

prompt_security_check

LLM and prompt injection vulnerability assessment

LLM Security Assessment Report

Part 1: LLM Usage Detection and Documentation

1.1 LLM Infrastructure Identification

After comprehensive scanning of the repository using all detection strategies:

Detection Strategy 1: Library and Package Detection

Root package.json dependencies analyzed:

  • No OpenAI, Anthropic, Google AI, or other LLM SDK dependencies found
  • No LangChain, LlamaIndex, or agent framework dependencies
  • No vector database clients (Pinecone, Weaviate, Chroma, FAISS)
  • Dependencies are primarily: Fastify, Drizzle ORM, NATS, Zod, YAML parsing libraries

UI package.json dependencies analyzed:

  • React, TanStack Query, Tailwind CSS
  • No LLM-related packages

Detection Strategy 2: Import/Include Pattern Matching

Searched all source files for:

  • import anthropic, from anthropic - Not found
  • import openai, from openai - Not found
  • import google.generativeai - Not found
  • import transformers - Not found
  • @anthropic-ai/sdk - Not found
  • @google/generative-ai - Not found

Detection Strategy 3: API Client Instantiation Patterns

Searched for:

  • new OpenAI(, new Anthropic(, OpenAI(, Anthropic( - Not found
  • openai.NewClient, anthropic.NewClient - Not found

Detection Strategy 4: API Method Call Patterns

Searched for:

  • .messages.create( - Not found
  • .chat.completions.create( - Not found
  • .generateContent( - Not found
  • HTTP calls to api.openai.com, api.anthropic.com - Not found

Detection Strategy 5: Configuration and Environment Variables

.env.example analyzed:

DATABASE_URL=postgresql://...
NATS_URL=nats://localhost:4222
LOG_LEVEL=info
  • No LLM API keys (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.)

Detection Strategy 6: Prompt-Related Patterns

Potential false positive investigated:

File: src/analysis/nl-translator.ts

export interface NLTranslatorConfig {
  // Configuration for natural language translation
}

export class NLTranslator {
  // Translates ontology concepts to natural language descriptions
  // Uses template-based string interpolation, NOT LLM calls
}

Finding: This is a template-based translator that converts ontology YAML definitions into human-readable text using string interpolation. No LLM API calls.

Detection Strategy 7: Custom Implementation Patterns

MCP Server Investigation:

File: src/mcp/ontology-mcp-server.ts

This implements a Model Context Protocol (MCP) server that:

  • Exposes ontology data (entities, state machines, events) as tools
  • Is designed to be consumed by external LLM applications
  • Does NOT make LLM API calls itself
  • Acts as a data provider, not an LLM consumer
// The MCP server provides tools like:
// - get_entities
// - get_state_machine
// - get_events
// These return ontology YAML data, not LLM-generated content

.claude/settings.json analyzed:

{
  // Claude Code/Desktop configuration for development assistance
  // This is IDE tooling configuration, not application LLM usage
}

CLAUDE.md analyzed:

  • This is documentation for developers using Claude as a coding assistant
  • Contains project context and conventions
  • Not application code that calls LLM APIs

1.2 MCP Server Analysis (Critical Finding)

While this repository does not consume LLM APIs, it provides data to LLMs via MCP:

File: src/mcp/ontology-mcp-server.ts

Purpose: Exposes ontology metadata for LLM tools to query

Tools Exposed:

  1. get_entities - Returns entity definitions
  2. get_state_machines - Returns state machine configurations
  3. get_events - Returns event schemas
  4. get_validation_rules - Returns validation rules
  5. get_relationships - Returns entity relationships
  6. get_vocabulary - Returns domain vocabulary

Security Relevance: This MCP server could be part of a "lethal trifecta" if:

  • An external LLM application connects to it
  • That LLM also has access to sensitive data
  • The LLM processes untrusted input

However, the security responsibility lies with the consuming LLM application, not this repository.

1.3 LLM Usage Summary

No LLM usage detected - prompt injection review not relevant for this repository.

This repository is an Ontology Service that:

  1. Manages domain ontology definitions (entities, state machines, events, validation rules)
  2. Provides a REST API for ontology data
  3. Exposes an MCP server for LLM tools to query ontology data
  4. Syncs ontology data with PostgreSQL and NATS

The repository does NOT:

  • Make calls to OpenAI, Anthropic, Google, or any LLM APIs
  • Process prompts or generate AI responses
  • Include any LLM SDK dependencies
  • Store or manage LLM API keys

Part 2: Security Assessment (Non-LLM Scope)

While LLM-specific vulnerabilities are not applicable, the following security observations are relevant:

2.1 MCP Server Security Considerations

Since this repository provides an MCP server that LLMs can connect to:

Tool Authorization

Location: src/mcp/ontology-mcp-server.ts

The MCP server should ensure:

  • Tool access is authenticated
  • Tenant isolation is enforced
  • Rate limiting prevents abuse

Data Exposure Risk

The MCP server exposes:

  • Entity schemas
  • State machine definitions
  • Validation rules
  • Business vocabulary

Recommendation: Ensure sensitive business logic in ontology definitions is appropriately classified and access-controlled.

2.2 General Security Observations

Multi-Tenant Security

Location: database/migrations/012_tenant_security_hardening.sql, 013_force_rls_all_tables.sql

Row-Level Security (RLS) is implemented for tenant isolation - this is a positive security control.

API Authentication

Location: src/api/middleware/

Authentication middleware exists for the REST API.


Conclusion

No LLM usage detected - prompt injection review not relevant for this repository.

This is an ontology management service that:

  • Provides structured data about domain entities, events, and business rules
  • Exposes this data via REST API and MCP protocol
  • Does not consume or call any LLM APIs

The MCP server implementation means this repository could be part of an LLM system's data layer, but the prompt injection attack surface would exist in the consuming LLM application, not here.

data_layer

Data persistence and access patterns

Data Layer Architecture Analysis

Executive Summary

This backend service is an Ontology Management Service that uses PostgreSQL as its primary database with a file-based YAML ontology definition layer. The architecture implements multi-tenant data isolation through Row-Level Security (RLS), with NATS for event-driven synchronization.


Database Architecture

1. Primary Database

Type: PostgreSQL (SQL - Relational)

Purpose: Stores runtime ontology metadata, command executions, validation rules, projections, relationships, vocabulary, and operational health data for a multi-tenant ontology platform.

Connection Configuration:

// src/config/database.ts
import pg from 'pg';

const pool = new pg.Pool({
  connectionString: process.env.DATABASE_URL,
  max: 20,                    // Connection pool max size
  idleTimeoutMillis: 30000,   // 30 seconds idle timeout
  connectionTimeoutMillis: 2000, // 2 seconds connection timeout
});

Connection Details:

  • Driver: pg (node-postgres) v8.13.1
  • Connection String: Environment variable DATABASE_URL
  • Pool Size: Maximum 20 connections
  • Idle Timeout: 30,000ms
  • Connection Timeout: 2,000ms

2. Data Models/Entities

The database schema is defined through sequential SQL migrations. Below are the core domain entities:

Core Tables (from migrations)

tenants - Multi-tenant isolation

-- database/migrations/001_initial_schema.sql
CREATE TABLE tenants (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    slug TEXT NOT NULL UNIQUE,
    name TEXT NOT NULL,
    config JSONB DEFAULT '{}',
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

entities - Ontology entity definitions

CREATE TABLE entities (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    schema JSONB NOT NULL,
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(tenant_id, name)
);

state_machines - State machine definitions

CREATE TABLE state_machines (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    entity_name TEXT NOT NULL,
    definition JSONB NOT NULL,
    version INTEGER DEFAULT 1,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(tenant_id, entity_name, version)
);

event_semantic_mappings - Event to entity mappings

-- database/migrations/002_semantic_tables.sql
CREATE TABLE event_semantic_mappings (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    event_type TEXT NOT NULL,
    entity_name TEXT NOT NULL,
    mapping_rules JSONB NOT NULL,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(tenant_id, event_type)
);

commands - Command definitions

-- database/migrations/004_commands_execution.sql
CREATE TABLE commands (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    entity_name TEXT,
    schema JSONB NOT NULL,
    emits_events TEXT[] DEFAULT '{}',
    requires_approval BOOLEAN DEFAULT false,
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(tenant_id, name)
);

command_executions - Command execution audit trail

CREATE TABLE command_executions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    command_name TEXT NOT NULL,
    entity_id UUID,
    payload JSONB NOT NULL,
    status TEXT NOT NULL DEFAULT 'pending',
    result JSONB,
    executed_by TEXT,
    executed_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    CONSTRAINT valid_status CHECK (status IN ('pending', 'approved', 'rejected', 'executed', 'failed'))
);

validation_rules - Business rule definitions

-- database/migrations/005_validation_rules.sql
CREATE TABLE validation_rules (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    entity_name TEXT,
    rule_type TEXT NOT NULL,
    rule_definition JSONB NOT NULL,
    error_message TEXT,
    severity TEXT DEFAULT 'error',
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(tenant_id, name),
    CONSTRAINT valid_rule_type CHECK (rule_type IN ('jsonlogic', 'schema', 'custom')),
    CONSTRAINT valid_severity CHECK (severity IN ('error', 'warning', 'info'))
);

projections - Read model definitions

-- database/migrations/006_projections_versioning.sql
CREATE TABLE projections (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    definition JSONB NOT NULL,
    version INTEGER DEFAULT 1,
    is_current BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(tenant_id, name, version)
);

ontology_versions - Version tracking

CREATE TABLE ontology_versions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    version TEXT NOT NULL,
    description TEXT,
    schema_hash TEXT NOT NULL,
    breaking_changes BOOLEAN DEFAULT false,
    migration_notes JSONB,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(tenant_id, version)
);

relationship_definitions - Entity relationships

-- database/migrations/007_relationship_definitions.sql
CREATE TABLE relationship_definitions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    source_entity TEXT NOT NULL,
    target_entity TEXT NOT NULL,
    relationship_type TEXT NOT NULL,
    cardinality TEXT NOT NULL,
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(tenant_id, name),
    CONSTRAINT valid_relationship_type CHECK (relationship_type IN ('association', 'composition', 'aggregation', 'dependency')),
    CONSTRAINT valid_cardinality CHECK (cardinality IN ('one-to-one', 'one-to-many', 'many-to-one', 'many-to-many'))
);

error_definitions - Error catalog

-- database/migrations/008_error_definitions.sql
CREATE TABLE error_definitions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    code TEXT NOT NULL,
    domain TEXT NOT NULL,
    message_template TEXT NOT NULL,
    severity TEXT NOT NULL,
    retry_strategy JSONB,
    resolution_hints TEXT[],
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(tenant_id, code),
    CONSTRAINT valid_severity CHECK (severity IN ('critical', 'error', 'warning', 'info'))
);

vocabulary_terms - Domain vocabulary

-- database/migrations/009_vocabulary.sql
CREATE TABLE vocabulary_terms (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    term TEXT NOT NULL,
    canonical_name TEXT NOT NULL,
    domain TEXT NOT NULL,
    definition TEXT,
    aliases TEXT[] DEFAULT '{}',
    related_entities TEXT[] DEFAULT '{}',
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(tenant_id, term)
);

ontology_health_metrics - Operational monitoring

-- database/migrations/010_operational_health.sql
CREATE TABLE ontology_health_metrics (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    metric_type TEXT NOT NULL,
    metric_value JSONB NOT NULL,
    recorded_at TIMESTAMPTZ DEFAULT NOW(),
    CONSTRAINT valid_metric_type CHECK (metric_type IN (
        'entity_usage', 'state_machine_transitions', 'validation_failures',
        'command_execution', 'projection_refresh', 'relationship_violations'
    ))
);

Entity Relationships

RelationshipTypeDescription
tenantsentities1:NTenant owns multiple entities
tenantsstate_machines1:NTenant owns multiple state machines
tenantscommands1:NTenant owns multiple commands
tenantscommand_executions1:NTenant owns execution history
tenantsvalidation_rules1:NTenant owns validation rules
tenantsprojections1:NTenant owns projections
tenantsrelationship_definitions1:NTenant owns relationships
tenantserror_definitions1:NTenant owns error catalog
tenantsvocabulary_terms1:NTenant owns vocabulary
commandscommand_executions1:NCommand has many executions

Indexes

-- database/migrations/001_initial_schema.sql
CREATE INDEX idx_entities_tenant ON entities(tenant_id);
CREATE INDEX idx_state_machines_tenant ON state_machines(tenant_id);
CREATE INDEX idx_state_machines_entity ON state_machines(tenant_id, entity_name);

-- database/migrations/004_commands_execution.sql
CREATE INDEX idx_commands_tenant ON commands(tenant_id);
CREATE INDEX idx_command_executions_tenant ON command_executions(tenant_id);
CREATE INDEX idx_command_executions_status ON command_executions(tenant_id, status);

-- database/migrations/006_projections_versioning.sql
CREATE INDEX idx_projections_tenant ON projections(tenant_id);
CREATE INDEX idx_projections_current ON projections(tenant_id, is_current) WHERE is_current = true;
CREATE INDEX idx_ontology_versions_tenant ON ontology_versions(tenant_id);

-- database/migrations/010_operational_health.sql
CREATE INDEX idx_health_metrics_tenant ON ontology_health_metrics(tenant_id);
CREATE INDEX idx_health_metrics_type ON ontology_health_metrics(metric_type);
CREATE INDEX idx_health_metrics_time ON ontology_health_metrics(recorded_at);

-- database/migrations/014_add_execution_tenant_index.sql
CREATE INDEX IF NOT EXISTS idx_command_executions_tenant_id ON command_executions(tenant_id);

3. Data Access Layer

Direct SQL with pg Client (No ORM)

The codebase uses raw SQL queries with the pg (node-postgres) driver. There is no ORM (like Sequelize, TypeORM, or Prisma) present.

Repository Pattern Implementation:

// src/db/repositories/entity.repository.ts
import pool from '../../config/database.js';

export class EntityRepository {
  async findByTenant(tenantId: string) {
    const result = await pool.query(
      'SELECT * FROM entities WHERE tenant_id = $1',
      [tenantId]
    );
    return result.rows;
  }

  async findByName(tenantId: string, name: string) {
    const result = await pool.query(
      'SELECT * FROM entities WHERE tenant_id = $1 AND name = $2',
      [tenantId, name]
    );
    return result.rows[0];
  }

  async create(tenantId: string, name: string, schema: object, metadata?: object) {
    const result = await pool.query(
      `INSERT INTO entities (tenant_id, name, schema, metadata) 
       VALUES ($1, $2, $3, $4) 
       RETURNING *`,
      [tenantId, name, JSON.stringify(schema), JSON.stringify(metadata || {})]
    );
    return result.rows[0];
  }
}
// src/db/repositories/relationship.repository.ts
import pool from '../../config/database.js';

export class RelationshipRepository {
  async findAll(tenantId: string) {
    const result = await pool.query(
      'SELECT * FROM relationship_definitions WHERE tenant_id = $1',
      [tenantId]
    );
    return result.rows;
  }

  async upsert(tenantId: string, relationship: RelationshipDefinition) {
    const result = await pool.query(
      `INSERT INTO relationship_definitions 
         (tenant_id, name, source_entity, target_entity, relationship_type, cardinality, metadata)
       VALUES ($1, $2, $3, $4, $5, $6, $7)
       ON CONFLICT (tenant_id, name) 
       DO UPDATE SET 
         source_entity = EXCLUDED.source_entity,
         target_entity = EXCLUDED.target_entity,
         relationship_type = EXCLUDED.relationship_type,
         cardinality = EXCLUDED.cardinality,
         metadata = EXCLUDED.metadata,
         updated_at = NOW()
       RETURNING *`,
      [tenantId, relationship.name, relationship.sourceEntity, 
       relationship.targetEntity, relationship.relationshipType, 
       relationship.cardinality, JSON.stringify(relationship.metadata || {})]
    );
    return result.rows[0];
  }
}

Query Pattern Summary

PatternImplementation
Database Driverpg (node-postgres)
ORM/ODMNone - Raw SQL
Repository PatternYes - src/db/repositories/
Query BuilderNone
Parameterized QueriesYes - $1, $2, $3 placeholders
Connection PoolingYes - pg.Pool

4. Caching Layer

In-Memory Caching (Application-Level)

No external cache (Redis/Memcached) is configured. The codebase implements in-memory caching:

// src/validation/rule-cache.ts
export class RuleCache {
  private cache: Map<string, CacheEntry> = new Map();
  private ttl: number;

  constructor(ttlMs: number = 60000) { // Default 60 second TTL
    this.ttl = ttlMs;
  }

  get(key: string): ValidationRule[] | null {
    const entry = this.cache.get(key);
    if (!entry) return null;
    
    if (Date.now() > entry.expiresAt) {
      this.cache.delete(key);
      return null;
    }
    
    return entry.rules;
  }

  set(key: string, rules: ValidationRule[]): void {
    this.cache.set(key, {
      rules,
      expiresAt: Date.now() + this.ttl
    });
  }

  invalidate(pattern?: string): void {
    if (!pattern) {
      this.cache.clear();
      return;
    }
    for (const key of this.cache.keys()) {
      if (key.includes(pattern)) {
        this.cache.delete(key);
      }
    }
  }
}
// src/projections/projection-cache.ts
export class ProjectionCache {
  private cache: Map<string, CachedProjection> = new Map();
  private defaultTtl: number;

  constructor(ttlMs: number = 300000) { // Default 5 minute TTL
    this.defaultTtl = ttlMs;
  }

  get(tenantId: string, projectionName: string): ProjectionResult | null {
    const key = `${tenantId}:${projectionName}`;
    const entry = this.cache.get(key);
    
    if (!entry || Date.now() > entry.expiresAt) {
      this.cache.delete(key);
      return null;
    }
    
    return entry.result;
  }

  set(tenantId: string, projectionName: string, result: ProjectionResult, ttl?: number): void {
    const key = `${tenantId}:${projectionName}`;
    this.cache.set(key, {
      result,
      expiresAt: Date.now() + (ttl || this.defaultTtl)
    });
  }
}

Caching Summary

AspectImplementation
Cache ProviderIn-memory Map
StrategyCache-aside (manual get/set)
TTL - Rules60 seconds
TTL - Projections300 seconds (5 minutes)
InvalidationPattern-based or full clear

Data Operations

1. CRUD Operations

Standard CRUD

CRUD operations are implemented via direct SQL in repository classes and seeder services:

// Example from src/errors/error-seeder.ts
export class ErrorSeeder {
  async seedErrors(tenantId: string, errors: ErrorDefinition[]): Promise<void> {
    for (const error of errors) {
      await pool.query(
        `INSERT INTO error_definitions 
          (tenant_id, code, domain, message_template, severity, retry_strategy, resolution_hints, metadata)
         VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
         ON CONFLICT (tenant_id, code) 
         DO UPDATE SET
           domain = EXCLUDED.domain,
           message_template = EXCLUDED.message_template,
           severity = EXCLUDED.severity,
           retry_strategy = EXCLUDED.retry_strategy,
           resolution_hints = EXCLUDED.resolution_hints,
           metadata = EXCLUDED.metadata,
           updated_at = NOW()`,
        [tenantId, error.code, error.domain, error.messageTemplate,
         error.severity, JSON.stringify(error.retryStrategy || null),
         error.resolutionHints || [], JSON.stringify(error.metadata || {})]
      );
    }
  }
}

Bulk Operations (Upsert Pattern)

// src/vocabulary/vocabulary-seeder.ts
async seedVocabulary(tenantId: string, terms: VocabularyTerm[]): Promise<void> {
  for (const term of terms) {
    await pool.query(
      `INSERT INTO vocabulary_terms 
        (tenant_id, term, canonical_name, domain, definition, aliases, related_entities, metadata)
       VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
       ON CONFLICT (tenant_id, term) 
       DO UPDATE SET
         canonical_name = EXCLUDED.canonical_name,
         domain = EXCLUDED.domain,
         definition = EXCLUDED.definition,
         aliases = EXCLUDED.aliases,
         related_entities = EXCLUDED.related_entities,
         metadata = EXCLUDED.metadata,
         updated_at = NOW()`,
      [tenantId, term.term, term.canonicalName, term.domain,
       term.definition, term.aliases || [], term.relatedEntities || [],
       JSON.stringify(term.metadata || {})]
    );
  }
}

Audit Trails

Command executions include built-in audit tracking:

// src/commands/command-executor.ts
async execute(tenantId: string, commandName: string, payload: object, executedBy?: string) {
  // Create execution record
  const execution = await pool.query(
    `INSERT INTO command_executions 
      (tenant_id, command_name, payload, status, executed_by)
     VALUES ($1, $2, $3, 'pending', $4)
     RETURNING *`,
    [tenantId, commandName, JSON.stringify(payload), executedBy]
  );

  // ... execution logic ...

  // Update with result
  await pool.query(
    `UPDATE command_executions 
     SET status = $1, result = $2, executed_at = NOW()
     WHERE id = $3`,
    [status, JSON.stringify(result), executionId]
  );
}

Soft Deletes: Not implemented. Deletes use ON DELETE CASCADE.


2. Transactions

Transaction boundaries are NOT explicitly implemented in the current codebase. Queries execute as individual statements. The architecture relies on:

  • Upsert patterns (ON CONFLICT DO UPDATE) for atomicity
  • Foreign key cascades for referential integrity
  • Individual statement atomicity
// No transaction wrapper found - example of current pattern:
async function seedMultipleItems(tenantId: string, items: Item[]) {
  for (const item of items) {
    // Each insert is a separate transaction
    await pool.query('INSERT INTO ...', [tenantId, item.name]);
  }
}

Distributed Transactions/Sagas: Not implemented at runtime. ADR documentation (docs/ADRs/0015-saga-pattern.md) indicates this is a planned enhancement.


3. Data Validation

Schema Validation (Zod & AJV)

// Uses Zod for TypeScript-first validation
// package.json: "zod": "^3.23.8", "ajv": "^8.18.0"

// Example from src/validation/validation-engine.ts
import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv({ allErrors: true });
addFormats(ajv);

export class ValidationEngine {
  validateSchema(data: unknown, schema: object): ValidationResult {
    const validate = ajv.compile(schema);
    const valid = validate(data);
    
    if (!valid) {
      return {
        valid: false,
        errors: validate.errors?.map(e => ({
          path: e.instancePath,
          message: e.message || 'Validation failed'
        }))
      };
    }
    return { valid: true, errors: [] };
  }
}

Business Rule Validation (JSONLogic)

// src/validation/jsonlogic-evaluator.ts
import jsonLogic from 'json-logic-js';

export class JsonLogicEvaluator {
  evaluate(rule: object, data: object): boolean {
    return jsonLogic.apply(rule, data) as boolean;
  }

  validateRule(rule: object, data: object, errorMessage: string): ValidationResult {
    const result = this.evaluate(rule, data);
    if (!result) {
      return {
        valid: false,
        errors: [{ message: errorMessage }]
      };
    }
    return { valid: true, errors: [] };
  }
}

Validation Rule Types (from schema)


# events_and_messaging

Asynchronous communication and event patterns

# Event-Driven Architecture Analysis

## Executive Summary

This service implements a **NATS-based event streaming architecture** with event sourcing patterns for ontology synchronization. The system is designed around domain events flowing through NATS JetStream with consumer processing and dead letter queue handling.

---

## Message Brokers & Queues

### 1. NATS JetStream Implementation

**Configuration Source:** `src/config/nats.ts`

```typescript
// Connection configuration
export const natsConfig = {
  servers: process.env.NATS_SERVERS?.split(',') || ['nats://localhost:4222'],
  token: process.env.NATS_TOKEN,
  maxReconnectAttempts: 10,
  reconnectTimeWait: 1000,
};

// Stream configuration
export const streamConfig = {
  name: 'ONTOLOGY',
  subjects: ['ontology.>'],
  retention: 'limits' as const,
  maxAge: 7 * 24 * 60 * 60 * 1000000000, // 7 days in nanoseconds
  maxBytes: 1024 * 1024 * 1024, // 1GB
  storage: 'file' as const,
  replicas: 1,
};

// Consumer configuration
export const consumerConfig = {
  durable_name: 'ontology-service',
  ack_policy: 'explicit' as const,
  max_deliver: 5,
  ack_wait: 30 * 1000000000, // 30 seconds
  filter_subject: 'ontology.>',
};

Dead Letter Queue Configuration:

export const dlqConfig = {
  streamName: 'ONTOLOGY_DLQ',
  subjects: ['ontology.dlq.>'],
  maxAge: 30 * 24 * 60 * 60 * 1000000000, // 30 days
};

Event Patterns

1. Event Types Defined

Source: ontology/event-registry.yaml and src/events/types.ts

Event CategoryEvent TypesDescription
Domain Eventsentity.created, entity.updated, entity.deletedCore entity lifecycle
State Machine Eventsstate_machine.transition, state_machine.loadedState changes
Ontology Eventsontology.synced, ontology.validated, ontology.publishedOntology lifecycle
Command Eventscommand.executed, command.failed, command.approvedCommand processing
System Eventssync.started, sync.completed, sync.failedOperational events

2. Event Structure

Source: src/events/types.ts

export interface OntologyEvent {
  // Event identification
  id: string;
  type: string;
  version: string;
  
  // Event metadata
  timestamp: string;
  correlationId: string;
  causationId?: string;
  source: string;
  tenantId: string;
  
  // Event payload
  payload: {
    entityType?: string;
    entityId?: string;
    previousState?: unknown;
    currentState?: unknown;
    changes?: Record<string, unknown>;
  };
  
  // Tracing
  traceContext?: {
    traceId: string;
    spanId: string;
    parentSpanId?: string;
  };
}

3. Event Producers

Source: src/sync/ontology-sync.service.ts

export class OntologySyncService {
  async publishEvent(event: OntologyEvent): Promise<void> {
    const subject = `ontology.${event.type}.${event.payload.entityType || 'system'}`;
    
    await this.jetstream.publish(subject, this.codec.encode(event), {
      msgID: event.id, // Deduplication
      headers: this.buildHeaders(event),
    });
  }
  
  async publishEntityChange(
    entityType: string,
    entityId: string,
    changeType: 'created' | 'updated' | 'deleted',
    payload: unknown
  ): Promise<void> {
    const event: OntologyEvent = {
      id: uuidv4(),
      type: `entity.${changeType}`,
      version: '1.0',
      timestamp: new Date().toISOString(),
      correlationId: this.correlationId,
      source: 'ontology-service',
      tenantId: this.tenantId,
      payload: {
        entityType,
        entityId,
        currentState: payload,
      },
    };
    
    await this.publishEvent(event);
  }
}

4. Event Consumers

Source: src/sync/event-processor.ts

export class EventProcessor {
  private handlers: Map<string, EventHandler> = new Map();
  
  async processMessage(msg: JsMsg): Promise<void> {
    const event = this.codec.decode(msg.data) as OntologyEvent;
    
    try {
      // Idempotency check
      if (await this.isProcessed(event.id)) {
        msg.ack();
        return;
      }
      
      // Route to handler
      const handler = this.handlers.get(event.type);
      if (handler) {
        await handler.handle(event);
      }
      
      // Mark as processed
      await this.markProcessed(event.id);
      msg.ack();
      
    } catch (error) {
      await this.handleError(msg, event, error);
    }
  }
  
  private async handleError(
    msg: JsMsg, 
    event: OntologyEvent, 
    error: unknown
  ): Promise<void> {
    const deliveryCount = msg.info.redeliveryCount;
    
    if (deliveryCount >= this.maxRetries) {
      // Send to DLQ
      await this.sendToDlq(event, error);
      msg.ack(); // Acknowledge to stop redelivery
    } else {
      // Negative acknowledge for retry
      msg.nak(this.calculateBackoff(deliveryCount));
    }
  }
}

Messaging Patterns

1. Communication Patterns Implemented

PatternImplementationLocation
Publish-SubscribeNATS subjects with wildcardsontology.> subject hierarchy
Competing ConsumersDurable consumer groupsconsumerConfig.durable_name
Fire-and-ForgetAsync event publishingpublishEvent() method
Request-ReplyNot implemented-

2. NATS Connection Management

Source: src/sync/nats-connection.ts

export class NatsConnection {
  private nc: NatsConnection | null = null;
  private js: JetStreamClient | null = null;
  
  async connect(): Promise<void> {
    this.nc = await connect({
      servers: natsConfig.servers,
      token: natsConfig.token,
      maxReconnectAttempts: natsConfig.maxReconnectAttempts,
      reconnectTimeWait: natsConfig.reconnectTimeWait,
    });
    
    // Setup JetStream
    this.js = this.nc.jetstream();
    
    // Ensure stream exists
    const jsm = await this.nc.jetstreamManager();
    await jsm.streams.add(streamConfig);
  }
  
  async subscribe(handler: MessageHandler): Promise<void> {
    const consumer = await this.js.consumers.get(
      streamConfig.name,
      consumerConfig.durable_name
    );
    
    const messages = await consumer.consume();
    for await (const msg of messages) {
      await handler(msg);
    }
  }
}

3. Reliability Patterns

At-Least-Once Delivery:

// Explicit acknowledgment required
consumerConfig.ack_policy = 'explicit';

// Message redelivery on failure
consumerConfig.max_deliver = 5;

Message Deduplication:

// Publisher-side deduplication via msgID
await this.jetstream.publish(subject, data, {
  msgID: event.id, // Unique event ID prevents duplicates
});

// Consumer-side idempotency
async isProcessed(eventId: string): Promise<boolean> {
  const result = await this.db.query(
    'SELECT 1 FROM processed_events WHERE event_id = $1',
    [eventId]
  );
  return result.rows.length > 0;
}

Background Jobs

1. Scheduled Tasks

No dedicated job scheduler found. However, drift monitoring is implemented via GitHub Actions:

Source: .github/workflows/ontology-drift-monitor.yml

name: Ontology Drift Monitor
on:
  schedule:
    - cron: '0 */6 * * *'  # Every 6 hours
  workflow_dispatch:

jobs:
  check-drift:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run check:drift

2. Script-Based Processing

Source: src/scripts/ directory

ScriptPurposeExecution
check-ontology-drift.tsDetect ontology changesScheduled/Manual
check-consumer-compatibility.tsValidate consumer schemasCI/CD
ingest-production-signals.tsProcess production feedbackManual
run-migrations.tsDatabase schema updatesDeployment

Event Sourcing Patterns

1. Event Semantics Registry

Source: src/events/event-semantics-registry.ts

export class EventSemanticsRegistry {
  private events: Map<string, EventDefinition> = new Map();
  
  async loadFromYaml(): Promise<void> {
    const registryPath = path.join(ONTOLOGY_ROOT, 'event-registry.yaml');
    const content = await fs.readFile(registryPath, 'utf-8');
    const registry = yaml.parse(content);
    
    for (const [eventName, definition] of Object.entries(registry.events)) {
      this.events.set(eventName, definition as EventDefinition);
    }
  }
  
  getEventSchema(eventType: string): EventDefinition | undefined {
    return this.events.get(eventType);
  }
  
  validateEvent(event: OntologyEvent): ValidationResult {
    const schema = this.getEventSchema(event.type);
    if (!schema) {
      return { valid: false, errors: [`Unknown event type: ${event.type}`] };
    }
    return this.schemaValidator.validate(event.payload, schema.payloadSchema);
  }
}

2. Event Seeding for Database

Source: src/events/event-semantics-seeder.ts

export class EventSemanticsSeeder {
  async seed(tenantId: string): Promise<void> {
    const registry = new EventSemanticsRegistry();
    await registry.loadFromYaml();
    
    for (const [eventName, definition] of registry.entries()) {
      await this.db.query(`
        INSERT INTO event_definitions (
          tenant_id, event_name, version, payload_schema, 
          source_entity, target_entity, metadata
        ) VALUES ($1, $2, $3, $4, $5, $6, $7)
        ON CONFLICT (tenant_id, event_name, version) 
        DO UPDATE SET payload_schema = $4, metadata = $7
      `, [
        tenantId,
        eventName,
        definition.version,
        JSON.stringify(definition.payloadSchema),
        definition.sourceEntity,
        definition.targetEntity,
        JSON.stringify(definition.metadata),
      ]);
    }
  }
}

Documented Architecture (Not Yet Fully Implemented)

Source: docs/improvements/0010-nats-stream-architecture.md and docs/improvements/0012-dead-letter-queue.md

The following patterns are documented as planned but implementation status varies:

PatternStatusDocumentation
NATS Streams✅ Configuredsrc/config/nats.ts
Dead Letter Queue✅ ConfigureddlqConfig in nats.ts
Event Replay📋 Planneddocs/EVENT-ARCHITECTURE.md
Saga Pattern📋 Planneddocs/ADRs/0015-saga-pattern.md
Transactional Outbox📋 PlannedNot implemented

Event Flow Diagram

┌─────────────────┐     ┌──────────────┐     ┌─────────────────┐
│  API Routes     │────▶│ Sync Service │────▶│ NATS JetStream  │
│  (Commands)     │     │ (Publisher)  │     │ ontology.>      │
└─────────────────┘     └──────────────┘     └────────┬────────┘
                                                      │
                              ┌────────────────────────┤
                              │                        │
                              ▼                        ▼
                    ┌─────────────────┐      ┌─────────────────┐
                    │ Event Processor │      │ External        │
                    │ (Consumer)      │      │ Subscribers     │
                    └────────┬────────┘      └─────────────────┘
                             │
              ┌──────────────┼──────────────┐
              │              │              │
              ▼              ▼              ▼
      ┌───────────┐  ┌───────────┐  ┌───────────┐
      │ Handler A │  │ Handler B │  │ DLQ       │
      │ (Success) │  │ (Retry)   │  │ (Failed)  │
      └───────────┘  └───────────┘  └───────────┘

Summary

ComponentTechnologyStatus
Message BrokerNATS JetStream✅ Implemented
Event PublishingAsync pub/sub✅ Implemented
Event ConsumingDurable consumers✅ Implemented
Dead Letter QueueNATS DLQ stream✅ Configured
IdempotencyEvent ID tracking✅ Implemented
Background JobsGitHub Actions only⚠️ Limited
Event SourcingPartial (registry only)⚠️ Partial
CQRSNot implemented❌ None

Related Documents