@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
