Files
cleveragents-core/features/uko_ontology_registry.feature
T
hamza.khyari 04f24b39c0
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / build (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 19s
CI / security (pull_request) Successful in 33s
CI / typecheck (pull_request) Successful in 38s
CI / unit_tests (pull_request) Successful in 2m26s
CI / docker (pull_request) Successful in 40s
CI / integration_tests (pull_request) Successful in 3m29s
CI / coverage (pull_request) Successful in 4m30s
CI / benchmark-regression (pull_request) Has been cancelled
feat(acms): implement UKO Layer 1 Domain Ontologies (uko-code, uko-doc, uko-data, uko-infra)
Implement the four Layer 1 domain-specific OWL/Turtle ontology vocabularies
that specialize Layer 0 universal concepts for specific knowledge domains.

Ontology (docs/ontology/uko.ttl):
- Added uko-doc: namespace with 17 classes (Document, Part, Chapter, Section,
  Subsection, Paragraph, Sentence, CodeBlock, Citation, Figure, Table,
  Footnote, Annotation, Bookmark, CrossReference, PageBreak, SectionBreak),
  5 properties, and 4 relationships
- Added uko-data: namespace with 13 classes (Schema, Table, Column, View,
  StoredProcedure, Constraint, Index, ForeignKey, Trigger, Annotation,
  Bookmark, PartitionBoundary, ShardBoundary), 6 properties, and
  5 relationships
- Added uko-infra: namespace with 7 classes (Service, Network, Endpoint,
  ConfigKey, Volume, FirewallRule, SubnetBoundary) and 2 relationships
- All classes use rdfs:subClassOf from Layer 0 base classes

Domain registry (ontology_registry.py):
- DomainDescriptor dataclass with namespace IRI, prefix, layer, classes,
  superclass mappings, and DetailLevelMap
- Registry functions: get_domain(), list_domains(), get_layer1_domains()
- DetailLevelMap chain builder for hierarchical depth resolution
- Turtle validation with TurtleValidationError (no rdflib dependency)
- All DetailLevelMap data inlined to maintain DIP compliance (domain
  layer does not import from application layer)

DetailLevelMap presets (depth_breadth_projection.py):
- code_detail_map: 10 spec-complete levels (depths 0-9)
- docs_detail_map: 11 spec-complete levels (depths 0-10)
- database_detail_map: 12 spec-complete levels (depths 0-11)
- infra_detail_map: 9 spec-complete levels (depths 0-8)

Tests:
- 31 BDD scenarios in uko_ontology_registry.feature covering domain
  lookup, all DetailLevelMap levels, inheritance chains, Turtle
  validation, Universal View Guarantee, and negative/edge cases
- 6 Robot Framework integration tests
- Updated existing tests: depth_breadth_projection.feature (TABLE_LISTING
  depth 0->1, added SCHEMA_LISTING), uko_ontology.feature (Layer 1
  node count 8->67)

Spec reference: docs/specification.md §41830-42332

ISSUES CLOSED: #574
2026-03-06 23:14:30 +00:00

323 lines
14 KiB
Gherkin

@ontology @uko
Feature: UKO Ontology Domain Registry and Turtle Validation
As an ACMS developer
I need a central registry for UKO domain ontologies
So that analyzers, strategies, and the graph backend can discover
namespace IRIs, class inventories, and DetailLevelMaps for each domain
Background:
Given the UKO ontology registry module is available
# ---------------------------------------------------------------------------
# Domain Lookup
# ---------------------------------------------------------------------------
@ontology @registry
Scenario: Look up Layer 0 domain by prefix
When I look up domain "uko:"
Then the domain IRI should be "https://cleveragents.ai/ontology/uko#"
And the domain layer should be 0
And the domain classes should contain "uko:InformationUnit"
And the domain classes should contain "uko:Container"
And the domain classes should contain "uko:Atom"
And the domain classes should contain "uko:Annotation"
And the domain classes should contain "uko:Boundary"
@ontology @registry
Scenario: Look up uko-code: domain by prefix
When I look up domain "uko-code:"
Then the domain IRI should be "https://cleveragents.ai/ontology/uko/code#"
And the domain layer should be 1
And the domain classes should contain "uko-code:Module"
And the domain classes should contain "uko-code:Callable"
And the domain classes should contain "uko-code:TypeDefinition"
And the domain classes should contain "uko-code:TestCase"
And the domain classes should contain "uko-code:Import"
@ontology @registry
Scenario: Look up uko-doc: domain by prefix
When I look up domain "uko-doc:"
Then the domain IRI should be "https://cleveragents.ai/ontology/uko/doc#"
And the domain layer should be 1
And the domain should have 17 classes
And the domain classes should contain "uko-doc:Document"
And the domain classes should contain "uko-doc:Section"
And the domain classes should contain "uko-doc:Paragraph"
And the domain classes should contain "uko-doc:Citation"
And the domain classes should contain "uko-doc:TableOfContents"
@ontology @registry
Scenario: Look up uko-data: domain by prefix
When I look up domain "uko-data:"
Then the domain IRI should be "https://cleveragents.ai/ontology/uko/data#"
And the domain layer should be 1
And the domain should have 13 classes
And the domain classes should contain "uko-data:Table"
And the domain classes should contain "uko-data:Column"
And the domain classes should contain "uko-data:ForeignKey"
And the domain classes should contain "uko-data:StoredProcedure"
And the domain classes should contain "uko-data:View"
@ontology @registry
Scenario: Look up uko-infra: domain by prefix
When I look up domain "uko-infra:"
Then the domain IRI should be "https://cleveragents.ai/ontology/uko/infra#"
And the domain layer should be 1
And the domain should have 7 classes
And the domain classes should contain "uko-infra:Service"
And the domain classes should contain "uko-infra:Endpoint"
And the domain classes should contain "uko-infra:Port"
And the domain classes should contain "uko-infra:ConfigBlock"
And the domain classes should contain "uko-infra:ConfigKey"
@ontology @registry @negative
Scenario: Look up unknown domain raises ValueError
When I look up domain "uko-xyz:"
Then a ValueError should have been raised with message "Unknown UKO domain prefix"
@ontology @registry @negative
Scenario: Look up empty domain prefix raises ValueError
When I look up an empty domain prefix
Then a ValueError should have been raised with message "must not be empty"
# ---------------------------------------------------------------------------
# List Domains
# ---------------------------------------------------------------------------
@ontology @registry
Scenario: list_domains returns all 5 registered domains
When I list all domains
Then the domain list should have 5 entries
And the domain list should be sorted by layer then prefix
@ontology @registry
Scenario: get_layer1_domains returns exactly 4 domains
When I get Layer 1 domains
Then the Layer 1 list should have 4 entries
And every domain in the Layer 1 list should have layer 1
# ---------------------------------------------------------------------------
# DetailLevelMap — spec-complete resolution for uko-code:
# ---------------------------------------------------------------------------
@ontology @detail_levels
Scenario: uko-code: map resolves all 10 named levels
When I look up domain "uko-code:"
Then the detail map should resolve "MODULE_LISTING" to 0
And the detail map should resolve "MODULE_GRAPH" to 1
And the detail map should resolve "MEMBER_LISTING" to 2
And the detail map should resolve "MEMBER_SUMMARY" to 3
And the detail map should resolve "SIGNATURES" to 4
And the detail map should resolve "SIGNATURES_WITH_DOCS" to 5
And the detail map should resolve "STRUCTURAL_OUTLINE" to 6
And the detail map should resolve "KEY_LOGIC" to 7
And the detail map should resolve "NEAR_COMPLETE" to 8
And the detail map should resolve "FULL_SOURCE" to 9
# ---------------------------------------------------------------------------
# DetailLevelMap — spec-complete resolution for uko-doc:
# ---------------------------------------------------------------------------
@ontology @detail_levels
Scenario: uko-doc: map resolves all 11 named levels
When I look up domain "uko-doc:"
Then the detail map should resolve "TITLE_ONLY" to 0
And the detail map should resolve "TABLE_OF_CONTENTS_L1" to 1
And the detail map should resolve "TABLE_OF_CONTENTS_L2" to 2
And the detail map should resolve "FULL_TOC" to 3
And the detail map should resolve "TOC_WITH_SUMMARIES" to 4
And the detail map should resolve "SECTION_OVERVIEWS" to 5
And the detail map should resolve "TOPIC_SENTENCES" to 6
And the detail map should resolve "PARAGRAPH_SUMMARIES" to 7
And the detail map should resolve "STRUCTURAL_DETAIL" to 8
And the detail map should resolve "NEAR_COMPLETE" to 9
And the detail map should resolve "FULL_CONTENT" to 10
# ---------------------------------------------------------------------------
# DetailLevelMap — spec-complete resolution for uko-data:
# ---------------------------------------------------------------------------
@ontology @detail_levels
Scenario: uko-data: map resolves all 12 named levels
When I look up domain "uko-data:"
Then the detail map should resolve "SCHEMA_LISTING" to 0
And the detail map should resolve "TABLE_LISTING" to 1
And the detail map should resolve "COLUMN_LISTING" to 2
And the detail map should resolve "TYPED_COLUMNS" to 3
And the detail map should resolve "CONSTRAINTS" to 4
And the detail map should resolve "RELATIONSHIPS" to 5
And the detail map should resolve "INDEXES_AND_STATS" to 6
And the detail map should resolve "DDL" to 7
And the detail map should resolve "DDL_WITH_TRIGGERS" to 8
And the detail map should resolve "FULL_PROCEDURES" to 9
And the detail map should resolve "WITH_SAMPLE_DATA" to 10
And the detail map should resolve "FULL_CATALOG" to 11
# ---------------------------------------------------------------------------
# DetailLevelMap — spec-complete resolution for uko-infra:
# ---------------------------------------------------------------------------
@ontology @detail_levels
Scenario: uko-infra: map resolves all 9 named levels
When I look up domain "uko-infra:"
Then the detail map should resolve "SERVICE_LISTING" to 0
And the detail map should resolve "SERVICE_GRAPH" to 1
And the detail map should resolve "ENDPOINT_LISTING" to 2
And the detail map should resolve "ENDPOINT_DETAIL" to 3
And the detail map should resolve "CONFIG_KEYS" to 4
And the detail map should resolve "CONFIG_VALUES" to 5
And the detail map should resolve "RESOURCE_LIMITS" to 6
And the detail map should resolve "FULL_CONFIG" to 7
And the detail map should resolve "WITH_DEPLOYMENT" to 8
# ---------------------------------------------------------------------------
# DetailLevelMap — integer depth resolution
# ---------------------------------------------------------------------------
@ontology @detail_levels
Scenario: Integer depth is clamped to max_depth
When I look up domain "uko-code:"
Then the detail map should clamp depth 15 to 9
And the detail map should clamp depth 0 to 0
And the detail map should clamp depth 5 to 5
@ontology @detail_levels @negative
Scenario: Unknown named level raises ValueError
When I look up domain "uko-code:"
And I try to resolve level "NONEXISTENT_LEVEL"
Then a ValueError should have been raised with message "Unknown detail level"
# ---------------------------------------------------------------------------
# DetailLevelMap — inheritance chain (Layer 3 → 2 → 1 → 0)
# ---------------------------------------------------------------------------
@ontology @detail_levels @inheritance
Scenario: build_detail_map_chain wires parent linkage
When I build a detail map chain from "uko-code:"
Then the chain should resolve "MODULE_LISTING" to 0
And the chain should resolve "FULL_SOURCE" to 9
And the chain max depth should be 9
@ontology @detail_levels @inheritance
Scenario: Two-level chain inherits parent levels
Given a custom DetailLevelMap for domain "uko-oo:" with parent "uko-code:" and levels:
| level | depth |
| CLASS_HIERARCHY | 3 |
When I resolve "MODULE_LISTING" on the custom map
Then the resolved depth should be 0
When I resolve "CLASS_HIERARCHY" on the custom map
Then the resolved depth should be 3
@ontology @detail_levels @inheritance @negative
Scenario: build_detail_map_chain with no prefixes raises ValueError
When I build a detail map chain with no prefixes
Then a ValueError should have been raised with message "At least one domain prefix"
# ---------------------------------------------------------------------------
# Turtle Validation — well-formed file
# ---------------------------------------------------------------------------
@ontology @turtle
Scenario: The project uko.ttl file passes Turtle validation
When I validate the project Turtle file "docs/ontology/uko.ttl"
Then the validation should produce 0 errors
@ontology @turtle
Scenario: Valid minimal Turtle content passes validation
When I validate Turtle content:
"""
@prefix ex: <http://example.org/> .
ex:Thing a ex:Class .
"""
Then the validation should produce 0 errors
# ---------------------------------------------------------------------------
# Turtle Validation — error detection
# ---------------------------------------------------------------------------
@ontology @turtle @negative
Scenario: Undeclared prefix is caught
When I validate Turtle content:
"""
@prefix ex: <http://example.org/> .
bogus:Thing a ex:Class .
"""
Then the validation should produce at least 1 error
And the first error should contain "undeclared prefix"
@ontology @turtle @negative
Scenario: Unbalanced angle brackets are caught
When I validate Turtle content:
"""
@prefix ex: <http://example.org/> .
ex:Thing a <http://example.org/Class .
"""
Then the validation should produce at least 1 error
And the first error should contain "unbalanced angle brackets"
@ontology @turtle @negative
Scenario: Empty content is caught
When I validate empty Turtle content
Then the validation should produce at least 1 error
And the first error should contain "Empty"
@ontology @turtle @negative
Scenario: validate_turtle_file with missing file raises FileNotFoundError
When I validate Turtle file "/nonexistent/path/to/file.ttl"
Then a FileNotFoundError should have been raised
@ontology @turtle @negative
Scenario: validate_turtle_file with empty path raises ValueError
When I validate Turtle file with empty path
Then a ValueError should have been raised with message "must not be empty"
# ---------------------------------------------------------------------------
# Turtle Content — Layer 1 prefix declarations
# ---------------------------------------------------------------------------
@ontology @turtle
Scenario: The project uko.ttl declares all Layer 1 prefixes
When I read the project Turtle file "docs/ontology/uko.ttl"
Then the content should contain prefix "uko-code:"
And the content should contain prefix "uko-doc:"
And the content should contain prefix "uko-data:"
And the content should contain prefix "uko-infra:"
@ontology @turtle
Scenario: The project uko.ttl declares uko-doc: classes
When I read the project Turtle file "docs/ontology/uko.ttl"
Then the content should contain "uko-doc:Document"
And the content should contain "uko-doc:Section"
And the content should contain "uko-doc:Paragraph"
And the content should contain "uko-doc:Citation"
@ontology @turtle
Scenario: The project uko.ttl declares uko-data: classes
When I read the project Turtle file "docs/ontology/uko.ttl"
Then the content should contain "uko-data:Table"
And the content should contain "uko-data:Column"
And the content should contain "uko-data:ForeignKey"
And the content should contain "uko-data:View"
@ontology @turtle
Scenario: The project uko.ttl declares uko-infra: classes
When I read the project Turtle file "docs/ontology/uko.ttl"
Then the content should contain "uko-infra:Service"
And the content should contain "uko-infra:Endpoint"
And the content should contain "uko-infra:Port"
And the content should contain "uko-infra:ConfigBlock"
# ---------------------------------------------------------------------------
# Universal View Guarantee
# ---------------------------------------------------------------------------
@ontology @universal_view
Scenario: Every Layer 1 class ultimately inherits from uko:InformationUnit
When I read the project Turtle file "docs/ontology/uko.ttl"
Then every Layer 1 class should have a subClassOf chain to uko:InformationUnit
@ontology @universal_view
Scenario: All Layer 1 domain DetailLevelMaps include depth 0
When I get Layer 1 domains
Then every domain detail map should resolve integer depth 0 to 0