Ontology Layer
A single PostgreSQL database (stewardos_db)
with real foreign keys across domain schemas. No bridge-key workarounds, no graph database.
An ontology-mcp server provides
cross-domain graph traversal, decision traces, and entity context assembly.
Consolidated Database
Six separate PostgreSQL databases consolidated into one. Shared tables (people, entities, assets,
documents) live in the core schema.
Domain-specific tables stay in their own schemas. Real cross-schema foreign keys replace
bridge-key workarounds and JSONB identity bridges.
Each MCP server connects with a search_path
that includes both its domain schema and core.
Unqualified queries against people resolve to
core.people everywhere. Cross-schema reads
(e.g. estate reading finance valuations) use explicit grants and schema-qualified JOINs.
Reasoning Memory
Three patterns adopted from neo4j-labs/create-context-graph's three-memory architecture — adapted from Neo4j to PostgreSQL:
Decision Traces
Every non-trivial agent decision records a structured reasoning chain: thought → action → observation, step by step. When the Chief of Staff synthesizes a multi-persona briefing, the reasoning chain is preserved — not lost when the conversation ends.
Adapted from neo4j-agent-memory's
reasoning.start_trace() /
add_step() /
complete_trace() pattern.
Entity Context Assembly
A single get_entity_context(schema, table, pk)
call returns a unified context packet: neighbors, lifecycle state, recent decision traces, and allowed actions.
Runs four queries concurrently via asyncio.gather.
Replaces the pattern of calling 4-5 separate tools before making a decision.
Depth-N Graph Traversal
find_related(schema, table, pk, depth=2)
performs iterative-deepening BFS across the FK catalog. Depth 1 for direct neighbors;
depth 2-3 for impact analysis ("what breaks if this entity changes?"). Capped at depth 3
with a 200-result limit to prevent runaway traversal.
Replaces Neo4j Cypher multi-hop queries with PostgreSQL FK introspection.
The link catalog carries explicit PK field names per table — not assuming column id.
How the Ontology Layer Works
FK-first link catalog
The link catalog is auto-generated from information_schema.referential_constraints
— real FK relationships, not hand-maintained YAML. Curated additions cover external system refs
(Ghostfolio, Paperless-ngx) and JSONB bridges where FKs can't reach.
Each link carries schema-qualified source/target, PK field names, cardinality, and semantic labels.
Domain-owned action manifests
Each MCP server owns its ontology.actions.yaml.
Actions declare typed inputs, preconditions (lifecycle state checks, field requirements),
and effects (create, update, state_transition). Merged at build time into a single action catalog.
Plane-mcp gets a hand-authored catalog (API-backed, no DDL to introspect).
Lifecycle state machines from CHECK constraints
State enums are extracted from PostgreSQL CHECK constraints:
entities.status IN ('active','dissolved','pending'),
liabilities.status IN ('active','delinquent','paid_off','closed').
The validate_action tool
checks preconditions against these state machines before execution.
Persona-scoped capabilities
ontology://persona/{name}/capabilities
returns the MCP servers and governed actions available to each persona. The ontology layer
knows what each agent can see and do — not just what exists in the database.
What We Didn't Adopt
The create-context-graph project is a Neo4j scaffolding tool for greenfield AI agent apps. We took the three patterns above and skipped everything else:
- Neo4j — our entity graphs are ~50 nodes. PostgreSQL recursive CTEs handle it fine.
- POLE+O taxonomy — too generic vs. our domain-specific schemas (finance, estate, health).
- YAML-first ontology authoring — DDL is the source of truth for a mature codebase. Auto-generate the ontology from the database, not the other way around.
- Code generation / scaffolding — 411 tests across 19 projects. Past that stage.
The ontology layer's structural patterns (link catalog, action manifests, lifecycle extraction) come from PuranOS, which implements the same DDL-first approach for industrial engineering at larger scale (198 links, 98 tables, 7 databases).