@phase2 @acms @depth_breadth_projection Feature: Depth/Breadth Projection System and Skeleton Context Propagation As a CleverAgents developer I want a projection system over the UKO graph So that context can be materialized at varying detail levels based on distance from focal entities, and child plans can inherit compressed parent context via skeleton propagation # --------------------------------------------------------------------------- # ProjectionSpec model # --------------------------------------------------------------------------- @projection @model Scenario: ProjectionSpec is a frozen Pydantic model Given the depth/breadth projection modules are available When I create a ProjectionSpec with focus "class://AuthManager" and breadth 2 and depth 9 Then the projection spec focus should contain "class://AuthManager" And the projection spec breadth should be 2 And the projection spec depth should be 9 And the projection spec depth_gradient should be True And the projection spec domain should be "uko-code:" And the projection spec should be immutable @projection @model Scenario: ProjectionSpec rejects empty focus Given the depth/breadth projection modules are available When I create a ProjectionSpec with empty focus Then a projection ValidationError should be raised @projection @model Scenario: ProjectionSpec rejects negative integer depth Given the depth/breadth projection modules are available When I create a ProjectionSpec with negative depth Then a projection ValueError should be raised mentioning "non-negative" @projection @model Scenario: ProjectionSpec accepts named depth levels Given the depth/breadth projection modules are available When I create a ProjectionSpec with focus "module://auth" and named depth "FULL_SOURCE" Then the projection spec depth should be "FULL_SOURCE" # --------------------------------------------------------------------------- # ProjectedNode model # --------------------------------------------------------------------------- @projection @model Scenario: ProjectedNode is a frozen Pydantic model Given the depth/breadth projection modules are available When I create a ProjectedNode with uri "class://Foo" and distance 1 and resolved_depth 4 Then the projected node uri should be "class://Foo" And the projected node distance should be 1 And the projected node resolved_depth should be 4 And the projected node should be immutable # --------------------------------------------------------------------------- # DepthBreadthProjector — BFS traversal # --------------------------------------------------------------------------- @projection @projector Scenario: Projector performs BFS from focus with breadth 0 Given the depth/breadth projection modules are available And a UKO graph with nodes A B C and edges A->B B->C When I project with focus "A" and breadth 0 and depth 9 Then the projection should contain exactly 1 node And the projected nodes should include "A" at distance 0 @projection @projector Scenario: Projector performs BFS from focus with breadth 1 Given the depth/breadth projection modules are available And a UKO graph with nodes A B C and edges A->B B->C When I project with focus "A" and breadth 1 and depth 9 Then the projection should contain exactly 2 nodes And the projected nodes should include "A" at distance 0 And the projected nodes should include "B" at distance 1 @projection @projector Scenario: Projector performs BFS from focus with breadth 2 Given the depth/breadth projection modules are available And a UKO graph with nodes A B C and edges A->B B->C When I project with focus "A" and breadth 2 and depth 9 Then the projection should contain exactly 3 nodes And the projected nodes should include "A" at distance 0 And the projected nodes should include "B" at distance 1 And the projected nodes should include "C" at distance 2 @projection @projector Scenario: Projector applies depth gradient Given the depth/breadth projection modules are available And a UKO graph with nodes A B C and edges A->B B->C When I project with focus "A" and breadth 2 and depth 9 and gradient True Then the projected node "A" should have resolved_depth 9 And the projected node "B" should have resolved_depth greater than 0 And the projected node "B" should have resolved_depth less than 9 And the projected node "C" should have resolved_depth 0 @projection @projector Scenario: Projector without gradient assigns uniform depth Given the depth/breadth projection modules are available And a UKO graph with nodes A B C and edges A->B B->C When I project with focus "A" and breadth 2 and depth 9 and gradient False Then the projected node "A" should have resolved_depth 9 And the projected node "B" should have resolved_depth 9 And the projected node "C" should have resolved_depth 9 @projection @projector Scenario: Projector resolves named depth via DetailLevelMap Given the depth/breadth projection modules are available And a code DetailLevelMap is registered for domain "uko-code:" And a UKO graph with nodes A B and edges A->B When I project with focus "A" and breadth 1 and named depth "FULL_SOURCE" in domain "uko-code:" Then the projected node "A" should have resolved_depth 9 And the projected node "B" should have resolved_depth 0 @projection @projector Scenario: Projector raises error for unresolvable named depth Given the depth/breadth projection modules are available And a UKO graph with nodes A and no edges When I project with focus "A" and breadth 0 and named depth "NONEXISTENT" in domain "unknown:" Then a projection ValueError should be raised mentioning "no DetailLevelMap" @projection @projector Scenario: Projector handles multiple focus nodes Given the depth/breadth projection modules are available And a UKO graph with nodes A B C D and edges A->B C->D When I project with multi-focus "A" and "C" and breadth 1 and depth 5 Then the projection should contain exactly 4 nodes And the projected nodes should include "A" at distance 0 And the projected nodes should include "C" at distance 0 And the projected nodes should include "B" at distance 1 And the projected nodes should include "D" at distance 1 @projection @projector Scenario: Projector converts projection to ContextFragments Given the depth/breadth projection modules are available And a UKO graph with nodes A B and edges A->B When I project to fragments with focus "A" and breadth 1 and depth 4 Then the result should contain 2 ContextFragments And the first fragment uko_node should be "A" And all fragments should have metadata key "projected" set to True # --------------------------------------------------------------------------- # Built-in DetailLevelMap presets # --------------------------------------------------------------------------- @projection @presets Scenario: Code detail level map has correct levels Given the depth/breadth projection modules are available When I create the code detail level map preset Then the code map should resolve "MODULE_LISTING" to 0 And the code map should resolve "SIGNATURES" to 4 And the code map should resolve "FULL_SOURCE" to 9 @projection @presets Scenario: Docs detail level map has correct levels Given the depth/breadth projection modules are available When I create the docs detail level map preset Then the docs map should resolve "TITLE_ONLY" to 0 And the docs map should resolve "FULL_CONTENT" to 10 @projection @presets Scenario: Database detail level map has correct levels Given the depth/breadth projection modules are available When I create the database detail level map preset Then the database map should resolve "SCHEMA_LISTING" to 0 And the database map should resolve "TABLE_LISTING" to 1 And the database map should resolve "FULL_CATALOG" to 11 # --------------------------------------------------------------------------- # PlanContextInheritance — skeleton propagation # --------------------------------------------------------------------------- @inheritance @skeleton Scenario: PlanContextInheritance computes child context request Given the depth/breadth projection modules are available And a parent assembled context with 3 fragments at detail_depth 3 And a PlanContextInheritance service with default config When I compute child context with focus "class://Child" and budget 1000 Then the child result should contain a ContextRequest And the child request focus should contain "class://Child" And the child request depth_gradient should be True And the child result depth_delta should be 1 @inheritance @skeleton Scenario: PlanContextInheritance increases child detail from parent Given the depth/breadth projection modules are available And a parent assembled context with 3 fragments at detail_depth 3 And a PlanContextInheritance service with default config When I compute child context with focus "class://Child" and budget 1000 Then the child request depth should be greater than 3 @inheritance @skeleton Scenario: PlanContextInheritance narrows child breadth Given the depth/breadth projection modules are available And a parent assembled context with 3 fragments at detail_depth 3 And a PlanContextInheritance service with default config When I compute child context with focus "class://Child" and budget 1000 at depth_in_tree 0 to 1 Then the child request breadth should be at most 2 @inheritance @skeleton Scenario: PlanContextInheritance injects skeleton fragments Given the depth/breadth projection modules are available And a parent assembled context with 3 fragments at detail_depth 3 And a mock skeleton compressor that returns 2 fragments And a PlanContextInheritance service with the mock compressor When I compute child context with focus "class://Child" and budget 1000 Then the child result skeleton_fragments should have 2 entries @inheritance @skeleton Scenario: PlanContextInheritance uses DepthReductionCompressor by default Given the depth/breadth projection modules are available And a parent assembled context with the following inheritance fragments: | uko_node | content | tokens | depth | domain | resource_uri | | project://src/app/main.py | def main(): return runner() | 120 | 7 | uko-py: | project://src/app/main.py | And a PlanContextInheritance service with default config When I compute child context with focus "class://Child" and budget 1000 Then the child result skeleton_fragments should have 1 entries And all child skeleton fragments should have detail depth at most 1 And a child skeleton fragment should contain "[MODULE_GRAPH]: symbols=main" @inheritance @skeleton @tdd_issue @tdd_issue_4198 @tdd_expected_fail Scenario: PlanContextInheritance prioritises fragments near the child focus Given the depth/breadth projection modules are available And a parent assembled context with the following inheritance fragments: | uko_node | content | tokens | depth | domain | resource_uri | score | | project://src/app/main.py | def main(): return run | 120 | 7 | | project://src/app/main.py | 0.2 | | project://lib/aux.py | def aux(): return slow | 120 | 7 | | project://lib/aux.py | 0.9 | And a PlanContextInheritance service with default config and min_skeleton_tokens 1 When I compute child context with focus "project://src/app/main.py" and budget 60 Then the child result skeleton_fragments should have 2 entries And the first child skeleton fragment should contain "main.py" @inheritance @skeleton Scenario: PlanContextInheritance skips skeleton when budget too small Given the depth/breadth projection modules are available And a parent assembled context with 3 fragments at detail_depth 3 And a mock skeleton compressor that returns 2 fragments And a PlanContextInheritance service with the mock compressor and min_skeleton_tokens 500 When I compute child context with focus "class://Child" and budget 100 Then the child result skeleton_fragments should have 0 entries @inheritance @skeleton Scenario: PlanContextInheritance rejects invalid depth delta Given the depth/breadth projection modules are available And a parent assembled context with 3 fragments at detail_depth 3 And a PlanContextInheritance service with default config When I compute child context with parent_depth 2 and child_depth 1 Then a projection ValueError should be raised mentioning "child_depth_in_tree" @inheritance @skeleton Scenario: PlanContextInheritance config uses default skeleton_ratio Given the depth/breadth projection modules are available When I create an InheritanceConfig with defaults Then the inheritance config skeleton_ratio should be 0.15 @inheritance @skeleton Scenario: PlanContextInheritance extract_child_focus returns parent decisions Given the depth/breadth projection modules are available When I extract child focus from decisions "class://A" and "class://B" Then the child focus should include both "class://A" and "class://B" @inheritance @skeleton Scenario: PlanContextInheritance extract_child_focus uses fallback Given the depth/breadth projection modules are available When I extract child focus from empty decisions with fallback "class://Default" Then the child focus should contain "class://Default" # --------------------------------------------------------------------------- # ChildContextResult model # --------------------------------------------------------------------------- @inheritance @model Scenario: ChildContextResult is a frozen Pydantic model Given the depth/breadth projection modules are available When I create a ChildContextResult with a request and skeleton data Then the child context result should be immutable And the child context result should contain the request