Files
cleveragents-core/features/acms/uko_layer3_vocabularies.feature
T
hamza.khyari 89eaee008d
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 19s
CI / build (pull_request) Successful in 27s
CI / quality (pull_request) Successful in 29s
CI / security (pull_request) Successful in 41s
CI / typecheck (pull_request) Successful in 45s
CI / e2e_tests (pull_request) Successful in 1m29s
CI / unit_tests (pull_request) Successful in 3m19s
CI / integration_tests (pull_request) Successful in 3m30s
CI / docker (pull_request) Successful in 54s
CI / coverage (pull_request) Successful in 6m8s
CI / benchmark-regression (pull_request) Successful in 38m9s
feat(acms): implement UKO Layer 3 Technology Vocabularies (uko-py, uko-ts, uko-rs, uko-java)
Implement Layer 3 technology-specific UKO vocabulary extensions for Python,
TypeScript, Rust, and Java with language-specific classes, properties, and
DetailLevelMap insertions.

- 4 OWL/Turtle ontology files with language-specific semantic classes
- DetailLevelMap insertion logic with correct integer reassignment
- Provenance contract (5 required fields per spec)
- Full 4-layer chain resolution (Layer 3 -> Layer 2 -> Layer 1 -> Layer 0)
- Comprehensive Behave test suite (63 scenarios)

ISSUES CLOSED: #576
2026-03-16 12:11:08 +00:00

519 lines
26 KiB
Gherkin

@acms @uko @layer3
Feature: UKO Layer 3 Technology Vocabularies
As a developer
I want language-specific UKO vocabulary extensions for Python, TypeScript, Rust, and Java
So that the ACMS can represent technology-specific semantic refinements with correct DetailLevelMap resolution
# ===========================================================================
# ProvenanceInfo construction and validation
# ===========================================================================
@provenance
Scenario: Create a ProvenanceInfo with all fields for uko_l3
Given a provenance info with resource "res-01HXM7" and path "src/auth/manager.py" for uko_l3
Then the provenance source_resource should be "res-01HXM7" for uko_l3
And the provenance source_path should be "src/auth/manager.py" for uko_l3
And the provenance is_current should be true for uko_l3
And the provenance valid_from should be a UTC datetime for uko_l3
@provenance
Scenario: Create a ProvenanceInfo with source range for uko_l3
Given a ranged provenance info with resource "res-01ABC" and path "lib/util.py" and range "15:1-87:0" for uko_l3
Then the provenance source_range should be "15:1-87:0" for uko_l3
@provenance
Scenario: ProvenanceInfo rejects empty source_resource for uko_l3
Then creating a provenance info with empty source_resource should raise ValueError for uko_l3
@provenance
Scenario: ProvenanceInfo rejects whitespace-only source_resource for uko_l3
Then creating a provenance info with whitespace source_resource should raise ValueError for uko_l3
@provenance
Scenario: ProvenanceInfo rejects empty source_path for uko_l3
Then creating a provenance info with empty source_path should raise ValueError for uko_l3
@provenance
Scenario: ProvenanceInfo rejects whitespace-only source_path for uko_l3
Then creating a provenance info with whitespace source_path should raise ValueError for uko_l3
@provenance
Scenario: ProvenanceInfo is immutable for uko_l3
Given a provenance info with resource "res-FROZEN" and path "frozen.py" for uko_l3
Then modifying provenance is_current should raise an error for uko_l3
# ===========================================================================
# UKOClass — construction and validation
# ===========================================================================
@uko_class
Scenario: Create a UKOClass with subclass_of for uko_l3
Given a UKO class with uri "https://example.com/Test" and label "Test" for uko_l3
Then the UKO class uri should be "https://example.com/Test" for uko_l3
And the UKO class label should be "Test" for uko_l3
And the UKO class subclass_of should be empty for uko_l3
@uko_class
Scenario: UKOClass rejects empty uri for uko_l3
Then creating a UKO class with empty uri should raise ValueError for uko_l3
@uko_class
Scenario: UKOClass rejects whitespace-only label for uko_l3
Then creating a UKO class with whitespace label should raise ValueError for uko_l3
@uko_class
Scenario: UKOClass is immutable for uko_l3
Given a UKO class with uri "https://example.com/Frozen" and label "Frozen" for uko_l3
Then modifying UKO class label should raise an error for uko_l3
@uko_class @provenance
Scenario: UKOClass carries provenance when provided for uko_l3
Given a UKO class with provenance resource "res-42" and path "src/main.py" for uko_l3
Then the UKO class provenance source_resource should be "res-42" for uko_l3
And the UKO class provenance source_path should be "src/main.py" for uko_l3
@uko_class @provenance
Scenario: UKOClass provenance defaults to None for uko_l3
Given a UKO class with uri "https://example.com/NoProv" and label "NoProv" for uko_l3
Then the UKO class provenance should be None for uko_l3
# ===========================================================================
# UKOProperty — construction and validation
# ===========================================================================
@uko_property
Scenario: Create a UKOProperty for uko_l3
Given a UKO property with uri "https://example.com/hasFoo" and label "hasFoo" for uko_l3
Then the UKO property uri should be "https://example.com/hasFoo" for uko_l3
And the UKO property is_object_property should be true for uko_l3
@uko_property
Scenario: UKOProperty rejects empty uri for uko_l3
Then creating a UKO property with empty uri should raise ValueError for uko_l3
# ===========================================================================
# Layer2Dependency — construction
# ===========================================================================
@layer2_dep
Scenario: Create a Layer2Dependency for uko_l3
Given a layer2 dependency with uri "https://cleveragents.ai/ontology/uko/oo#Class" and prefix "uko-oo:" for uko_l3
Then the layer2 dependency layer should be 2 for uko_l3
And the layer2 dependency prefix should be "uko-oo:" for uko_l3
# ===========================================================================
# UKOVocabulary — container for classes/properties/deps
# ===========================================================================
@vocabulary
Scenario: Create a UKOVocabulary container for uko_l3
Given a UKO vocabulary with namespace "https://example.com/test#" and prefix "test:" and label "Test" for uko_l3
Then the vocabulary layer should be 3 for uko_l3
And the vocabulary prefix should be "test:" for uko_l3
# ===========================================================================
# Python vocabulary (uko-py:) — classes and properties
# ===========================================================================
@python_vocab
Scenario: Python vocabulary has correct namespace for uko_l3
Then the Python vocabulary namespace should be "https://cleveragents.ai/ontology/uko/py#" for uko_l3
And the Python vocabulary prefix should be "uko-py:" for uko_l3
And the Python vocabulary layer should be 3 for uko_l3
@python_vocab
Scenario: Python vocabulary has 5 classes for uko_l3
Then the Python vocabulary should have 5 classes for uko_l3
And the Python vocabulary should contain class "PythonModule" for uko_l3
And the Python vocabulary should contain class "PythonClass" for uko_l3
And the Python vocabulary should contain class "PythonFunction" for uko_l3
And the Python vocabulary should contain class "PythonDecorator" for uko_l3
And the Python vocabulary should contain class "PythonTypeStub" for uko_l3
@python_vocab
Scenario: Python vocabulary has 5 properties for uko_l3
Then the Python vocabulary should have 5 properties for uko_l3
And the Python vocabulary should contain property "hasDecorator" for uko_l3
And the Python vocabulary should contain property "hasTypeStub" for uko_l3
And the Python vocabulary should contain property "hasTest" for uko_l3
And the Python vocabulary should contain property "decoratorName" for uko_l3
And the Python vocabulary should contain property "stubAnnotation" for uko_l3
@python_vocab
Scenario: Python vocabulary extends uko-oo: for uko_l3
Then the Python vocabulary parent_prefixes should contain "uko-oo:" for uko_l3
@python_vocab
Scenario: PythonClass subclass_of includes uko-oo:Class for uko_l3
Then the PythonClass subclass_of should contain "https://cleveragents.ai/ontology/uko/oo#Class" for uko_l3
@python_vocab
Scenario: Python vocabulary has 3 inserted levels for uko_l3
Then the Python vocabulary should have 3 inserted levels for uko_l3
And the Python vocabulary inserted levels should include "DECORATED_SIGNATURES" for uko_l3
And the Python vocabulary inserted levels should include "TYPE_STUBS" for uko_l3
And the Python vocabulary inserted levels should include "WITH_TESTS" for uko_l3
# ===========================================================================
# TypeScript vocabulary (uko-ts:)
# ===========================================================================
@typescript_vocab
Scenario: TypeScript vocabulary has correct namespace for uko_l3
Then the TypeScript vocabulary namespace should be "https://cleveragents.ai/ontology/uko/ts#" for uko_l3
And the TypeScript vocabulary prefix should be "uko-ts:" for uko_l3
And the TypeScript vocabulary layer should be 3 for uko_l3
@typescript_vocab
Scenario: TypeScript vocabulary has 4 classes for uko_l3
Then the TypeScript vocabulary should have 4 classes for uko_l3
And the TypeScript vocabulary should contain class "TypeScriptModule" for uko_l3
And the TypeScript vocabulary should contain class "TypeScriptClass" for uko_l3
And the TypeScript vocabulary should contain class "TypeScriptInterface" for uko_l3
And the TypeScript vocabulary should contain class "TypeScriptFunction" for uko_l3
@typescript_vocab
Scenario: TypeScript vocabulary has 6 properties for uko_l3
Then the TypeScript vocabulary should have 6 properties for uko_l3
And the TypeScript vocabulary should contain property "exportKind" for uko_l3
And the TypeScript vocabulary should contain property "isAmbient" for uko_l3
And the TypeScript vocabulary should contain property "genericParameters" for uko_l3
And the TypeScript vocabulary should contain property "isMappedType" for uko_l3
And the TypeScript vocabulary should contain property "isConditionalType" for uko_l3
And the TypeScript vocabulary should contain property "implementsInterface" for uko_l3
@typescript_vocab
Scenario: TypeScript vocabulary extends uko-oo: for uko_l3
Then the TypeScript vocabulary parent_prefixes should contain "uko-oo:" for uko_l3
@typescript_vocab
Scenario: TypeScriptClass subclass_of includes uko-oo:Class for uko_l3
Then the TypeScriptClass subclass_of should contain "https://cleveragents.ai/ontology/uko/oo#Class" for uko_l3
@typescript_vocab
Scenario: TypeScript vocabulary has 0 inserted levels for uko_l3
Then the TypeScript vocabulary should have 0 inserted levels for uko_l3
# ===========================================================================
# Rust vocabulary (uko-rs:)
# ===========================================================================
@rust_vocab
Scenario: Rust vocabulary has correct namespace for uko_l3
Then the Rust vocabulary namespace should be "https://cleveragents.ai/ontology/uko/rs#" for uko_l3
And the Rust vocabulary prefix should be "uko-rs:" for uko_l3
And the Rust vocabulary layer should be 3 for uko_l3
@rust_vocab
Scenario: Rust vocabulary has 5 classes for uko_l3
Then the Rust vocabulary should have 5 classes for uko_l3
And the Rust vocabulary should contain class "RustStruct" for uko_l3
And the Rust vocabulary should contain class "RustTrait" for uko_l3
And the Rust vocabulary should contain class "RustImpl" for uko_l3
And the Rust vocabulary should contain class "RustFunction" for uko_l3
And the Rust vocabulary should contain class "RustDeriveAttribute" for uko_l3
@rust_vocab
Scenario: Rust vocabulary has 8 properties for uko_l3
Then the Rust vocabulary should have 8 properties for uko_l3
And the Rust vocabulary should contain property "visibility" for uko_l3
And the Rust vocabulary should contain property "lifetimeParameters" for uko_l3
And the Rust vocabulary should contain property "traitBounds" for uko_l3
And the Rust vocabulary should contain property "isUnsafe" for uko_l3
And the Rust vocabulary should contain property "deriveTraits" for uko_l3
And the Rust vocabulary should contain property "mustUse" for uko_l3
And the Rust vocabulary should contain property "hasDerive" for uko_l3
And the Rust vocabulary should contain property "implementsTrait" for uko_l3
@rust_vocab
Scenario: Rust vocabulary extends uko-oo: for uko_l3
Then the Rust vocabulary parent_prefixes should contain "uko-oo:" for uko_l3
@rust_vocab
Scenario: RustStruct subclass_of includes uko-oo:Class for uko_l3
Then the RustStruct subclass_of should contain "https://cleveragents.ai/ontology/uko/oo#Class" for uko_l3
@rust_vocab
Scenario: Rust vocabulary has 0 inserted levels for uko_l3
Then the Rust vocabulary should have 0 inserted levels for uko_l3
# ===========================================================================
# Java vocabulary (uko-java:)
# ===========================================================================
@java_vocab
Scenario: Java vocabulary has correct namespace for uko_l3
Then the Java vocabulary namespace should be "https://cleveragents.ai/ontology/uko/java#" for uko_l3
And the Java vocabulary prefix should be "uko-java:" for uko_l3
And the Java vocabulary layer should be 3 for uko_l3
@java_vocab
Scenario: Java vocabulary has 5 classes for uko_l3
Then the Java vocabulary should have 5 classes for uko_l3
And the Java vocabulary should contain class "JavaClass" for uko_l3
And the Java vocabulary should contain class "JavaInterface" for uko_l3
And the Java vocabulary should contain class "JavaMethod" for uko_l3
And the Java vocabulary should contain class "JavaAnnotation" for uko_l3
And the Java vocabulary should contain class "JavaCheckedException" for uko_l3
@java_vocab
Scenario: Java vocabulary has 8 properties for uko_l3
Then the Java vocabulary should have 8 properties for uko_l3
And the Java vocabulary should contain property "packageVisibility" for uko_l3
And the Java vocabulary should contain property "isFinal" for uko_l3
And the Java vocabulary should contain property "isAbstract" for uko_l3
And the Java vocabulary should contain property "isSealed" for uko_l3
And the Java vocabulary should contain property "hasAnnotation" for uko_l3
And the Java vocabulary should contain property "annotationName" for uko_l3
And the Java vocabulary should contain property "throwsException" for uko_l3
And the Java vocabulary should contain property "exceptionClass" for uko_l3
@java_vocab
Scenario: Java vocabulary extends uko-oo: for uko_l3
Then the Java vocabulary parent_prefixes should contain "uko-oo:" for uko_l3
@java_vocab
Scenario: JavaClass subclass_of includes uko-oo:Class for uko_l3
Then the JavaClass subclass_of should contain "https://cleveragents.ai/ontology/uko/oo#Class" for uko_l3
@java_vocab
Scenario: Java vocabulary has 0 inserted levels for uko_l3
Then the Java vocabulary should have 0 inserted levels for uko_l3
# ===========================================================================
# DetailLevelMap — build_detail_level_map
# ===========================================================================
@detail_level_map
Scenario: build_detail_level_map with no insertions produces identity for uko_l3
Given a parent level map with entries "A=0,B=1,C=2" for uko_l3
When I build a detail level map with no insertions for uko_l3
Then the resulting map should have 3 entries for uko_l3
And the resulting map entry "A" should have depth 0 for uko_l3
And the resulting map entry "B" should have depth 1 for uko_l3
And the resulting map entry "C" should have depth 2 for uko_l3
@detail_level_map
Scenario: build_detail_level_map with one insertion shifts subsequent depths for uko_l3
Given a parent level map with entries "A=0,B=1,C=2" for uko_l3
When I build a detail level map with insertion "X=1" for uko_l3
Then the resulting map should have 4 entries for uko_l3
And the resulting map entry "A" should have depth 0 for uko_l3
And the resulting map entry "B" should have depth 1 for uko_l3
And the resulting map entry "X" should have depth 2 for uko_l3
And the resulting map entry "C" should have depth 3 for uko_l3
@detail_level_map
Scenario: build_detail_level_map with multiple insertions for uko_l3
Given a parent level map with entries "A=0,B=1,C=2,D=3" for uko_l3
When I build a detail level map with insertions "X=1,Y=2" for uko_l3
Then the resulting map should have 6 entries for uko_l3
And the resulting map entry "A" should have depth 0 for uko_l3
And the resulting map entry "B" should have depth 1 for uko_l3
And the resulting map entry "X" should have depth 2 for uko_l3
And the resulting map entry "C" should have depth 3 for uko_l3
And the resulting map entry "Y" should have depth 4 for uko_l3
And the resulting map entry "D" should have depth 5 for uko_l3
@detail_level_map
Scenario: build_detail_level_map rejects duplicate names for uko_l3
Given a parent level map with entries "A=0,B=1" for uko_l3
Then building a detail level map with duplicate insertion "A=0" should raise ValueError for uko_l3
# ===========================================================================
# Python effective DetailLevelMap — 4-layer resolution
# ===========================================================================
@python_detail_map
Scenario: Python effective map has 15 levels for uko_l3
Then the Python detail level map should have 15 entries for uko_l3
@python_detail_map
Scenario: Python effective map has correct depth for MODULE_LISTING for uko_l3
Then the Python detail level "MODULE_LISTING" should resolve to depth 0 for uko_l3
@python_detail_map
Scenario: Python effective map has correct depth for DECORATED_SIGNATURES for uko_l3
Then the Python detail level "DECORATED_SIGNATURES" should resolve to depth 7 for uko_l3
@python_detail_map
Scenario: Python effective map has correct depth for TYPE_STUBS for uko_l3
Then the Python detail level "TYPE_STUBS" should resolve to depth 11 for uko_l3
@python_detail_map
Scenario: Python effective map has correct depth for WITH_TESTS for uko_l3
Then the Python detail level "WITH_TESTS" should resolve to depth 14 for uko_l3
@python_detail_map
Scenario: Python effective map has correct depth for FULL_SOURCE for uko_l3
Then the Python detail level "FULL_SOURCE" should resolve to depth 13 for uko_l3
@python_detail_map
Scenario: Python effective map has correct depth for SIGNATURES for uko_l3
Then the Python detail level "SIGNATURES" should resolve to depth 5 for uko_l3
@python_detail_map
Scenario: Python effective map has correct depth for CLASS_HIERARCHY for uko_l3
Then the Python detail level "CLASS_HIERARCHY" should resolve to depth 3 for uko_l3
@python_detail_map
Scenario: Python effective map has correct depth for VISIBILITY_ANNOTATED for uko_l3
Then the Python detail level "VISIBILITY_ANNOTATED" should resolve to depth 8 for uko_l3
# ===========================================================================
# resolve_detail_level — chain resolution
# ===========================================================================
@resolve_level
Scenario: resolve_detail_level finds name in current map for uko_l3
Given a detail level map with entries "FOO=0,BAR=1" for uko_l3
Then resolving "FOO" should return 0 for uko_l3
And resolving "BAR" should return 1 for uko_l3
@resolve_level
Scenario: resolve_detail_level falls back to parent map for uko_l3
Given a detail level map with entries "CHILD=5" for uko_l3
And a parent detail level map with entries "PARENT=3" for uko_l3
Then resolving "PARENT" with parent fallback should return 3 for uko_l3
@resolve_level
Scenario: resolve_detail_level raises for unknown name for uko_l3
Given a detail level map with entries "KNOWN=1" for uko_l3
Then resolving "UNKNOWN" should raise ValueError for uko_l3
@resolve_level
Scenario: resolve_detail_level raises for empty name for uko_l3
Given a detail level map with entries "KNOWN=1" for uko_l3
Then resolving empty string should raise ValueError for uko_l3
@resolve_level
Scenario: resolve_detail_level raises for whitespace-only name for uko_l3
Given a detail level map with entries "KNOWN=1" for uko_l3
Then resolving whitespace string should raise ValueError for uko_l3
@resolve_level
Scenario: resolve_detail_level raises when not found in child or parent for uko_l3
Given a detail level map with entries "CHILD=5" for uko_l3
And a parent detail level map with entries "PARENT=3" for uko_l3
Then resolving "MISSING" with parent fallback should raise ValueError for uko_l3
# ===========================================================================
# 4-layer chain resolution end-to-end
# ===========================================================================
@four_layer_chain
Scenario: 4-layer resolution Layer3 -> Layer2 -> Layer1 -> Layer0 for uko_l3
Given a layer 0 map with "UNIVERSAL=0" for uko_l3
And a layer 1 map with "MODULE_LISTING=0,SIGNATURES=4" inheriting layer 0 for uko_l3
And a layer 2 map with "CLASS_HIERARCHY=3" inheriting layer 1 for uko_l3
And a layer 3 map with "DECORATED_SIGNATURES=7" inheriting layer 2 for uko_l3
Then resolving "DECORATED_SIGNATURES" through layer 3 should return 7 for uko_l3
And resolving "CLASS_HIERARCHY" through layer 3 should return 3 for uko_l3
And resolving "SIGNATURES" through layer 3 should return 4 for uko_l3
And resolving "UNIVERSAL" through layer 3 should return 0 for uko_l3
And resolving "NONEXISTENT" through layer 3 should raise ValueError for uko_l3
# ===========================================================================
# TypeScript / Rust / Java detail level maps
# ===========================================================================
@ts_detail_map
Scenario: TypeScript effective map has 12 levels for uko_l3
Then the TypeScript detail level map should have 12 entries for uko_l3
@ts_detail_map
Scenario: TypeScript SIGNATURES resolves to depth 5 for uko_l3
Then the TypeScript detail level "SIGNATURES" should resolve to depth 5 for uko_l3
@ts_detail_map
Scenario: TypeScript MODULE_LISTING resolves to depth 0 for uko_l3
Then the TypeScript detail level "MODULE_LISTING" should resolve to depth 0 for uko_l3
@ts_detail_map
Scenario: TypeScript CLASS_HIERARCHY resolves to depth 3 for uko_l3
Then the TypeScript detail level "CLASS_HIERARCHY" should resolve to depth 3 for uko_l3
@ts_detail_map
Scenario: TypeScript FULL_SOURCE resolves to depth 11 for uko_l3
Then the TypeScript detail level "FULL_SOURCE" should resolve to depth 11 for uko_l3
@rs_detail_map
Scenario: Rust effective map has 12 levels for uko_l3
Then the Rust detail level map should have 12 entries for uko_l3
@rs_detail_map
Scenario: Rust SIGNATURES resolves to depth 5 for uko_l3
Then the Rust detail level "SIGNATURES" should resolve to depth 5 for uko_l3
@rs_detail_map
Scenario: Rust MODULE_LISTING resolves to depth 0 for uko_l3
Then the Rust detail level "MODULE_LISTING" should resolve to depth 0 for uko_l3
@rs_detail_map
Scenario: Rust CLASS_HIERARCHY resolves to depth 3 for uko_l3
Then the Rust detail level "CLASS_HIERARCHY" should resolve to depth 3 for uko_l3
@rs_detail_map
Scenario: Rust FULL_SOURCE resolves to depth 11 for uko_l3
Then the Rust detail level "FULL_SOURCE" should resolve to depth 11 for uko_l3
@java_detail_map
Scenario: Java effective map has 12 levels for uko_l3
Then the Java detail level map should have 12 entries for uko_l3
@java_detail_map
Scenario: Java SIGNATURES resolves to depth 5 for uko_l3
Then the Java detail level "SIGNATURES" should resolve to depth 5 for uko_l3
@java_detail_map
Scenario: Java MODULE_LISTING resolves to depth 0 for uko_l3
Then the Java detail level "MODULE_LISTING" should resolve to depth 0 for uko_l3
@java_detail_map
Scenario: Java CLASS_HIERARCHY resolves to depth 3 for uko_l3
Then the Java detail level "CLASS_HIERARCHY" should resolve to depth 3 for uko_l3
@java_detail_map
Scenario: Java FULL_SOURCE resolves to depth 11 for uko_l3
Then the Java detail level "FULL_SOURCE" should resolve to depth 11 for uko_l3
# ===========================================================================
# Provenance contract — every vocabulary class has provenance fields
# ===========================================================================
@provenance_contract
Scenario: ProvenanceInfo has all 5 required fields for uko_l3
Then ProvenanceInfo should have field "source_resource" for uko_l3
And ProvenanceInfo should have field "source_path" for uko_l3
And ProvenanceInfo should have field "source_range" for uko_l3
And ProvenanceInfo should have field "valid_from" for uko_l3
And ProvenanceInfo should have field "is_current" for uko_l3
# ===========================================================================
# Layer 2 dependency tracking
# ===========================================================================
@layer2_deps
Scenario: Python vocabulary declares Layer 2 dependencies for uko_l3
Then the Python vocabulary should have at least 4 layer2 dependencies for uko_l3
And the Python vocabulary layer2 dependencies should include uri containing "uko/oo#Class" for uko_l3
@layer2_deps
Scenario: Rust vocabulary declares both uko-oo: and uko-func: dependencies for uko_l3
Then the Rust vocabulary layer2 dependencies should include prefix "uko-oo:" for uko_l3
And the Rust vocabulary layer2 dependencies should include prefix "uko-func:" for uko_l3
# ===========================================================================
# Package-level imports
# ===========================================================================
@imports
Scenario: All Layer 3 symbols are importable from acms.uko for uko_l3
Then importing PythonVocabulary from acms.uko should succeed for uko_l3
And importing TypeScriptVocabulary from acms.uko should succeed for uko_l3
And importing RustVocabulary from acms.uko should succeed for uko_l3
And importing JavaVocabulary from acms.uko should succeed for uko_l3
And importing ProvenanceInfo from acms.uko should succeed for uko_l3
And importing build_detail_level_map from acms.uko should succeed for uko_l3
And importing resolve_detail_level from acms.uko should succeed for uko_l3