Feature: CRP (Context Request Protocol) Domain Models As a developer I want CRP domain models for the Advanced Context Management System So that actors can issue structured context requests during reasoning # ---- DetailLevelMap ---- Scenario: Create a DetailLevelMap with valid levels Given a DetailLevelMap for domain "uko-code:" with max depth 9 And the map has level "MODULE_LISTING" at depth 0 And the map has level "FULL_SOURCE" at depth 9 Then the map should resolve "MODULE_LISTING" to 0 And the map should resolve "FULL_SOURCE" to 9 Scenario: DetailLevelMap clamps integer depth to max_depth Given a DetailLevelMap for domain "uko-code:" with max depth 9 Then the map should resolve integer 15 to 9 And the map should resolve integer 0 to 0 And the map should resolve integer 5 to 5 Scenario: DetailLevelMap resolves from parent map Given a parent DetailLevelMap for domain "uko-code:" with max depth 9 And the parent map has level "MODULE_LISTING" at depth 0 And a child DetailLevelMap for domain "uko-oo:" with max depth 11 And the child map has level "CLASS_HIERARCHY" at depth 3 Then the child map should resolve "MODULE_LISTING" to 0 And the child map should resolve "CLASS_HIERARCHY" to 3 Scenario: DetailLevelMap raises on unknown named level Given a DetailLevelMap for domain "uko-code:" with max depth 9 Then resolving "NONEXISTENT" should raise ValueError Scenario: DetailLevelMap register adds custom level Given a DetailLevelMap for domain "uko-code:" with max depth 9 When I register level "CUSTOM_LEVEL" at depth 7 Then the map should resolve "CUSTOM_LEVEL" to 7 Scenario: DetailLevelMap rejects negative depth in levels Then creating a DetailLevelMap with level "BAD" at depth -1 should raise ValueError Scenario: DetailLevelMap register rejects negative depth Given a DetailLevelMap for domain "uko-code:" with max depth 9 Then registering level "BAD" at depth -1 should raise ValueError Scenario: DetailLevelMap effective_levels merges parent and child Given a parent DetailLevelMap for domain "uko-code:" with max depth 9 And the parent map has level "MODULE_LISTING" at depth 0 And the parent map has level "FULL_SOURCE" at depth 9 And a child DetailLevelMap for domain "uko-oo:" with max depth 11 And the child map has level "CLASS_HIERARCHY" at depth 3 Then the child effective_levels should contain "MODULE_LISTING" at 0 And the child effective_levels should contain "FULL_SOURCE" at 9 And the child effective_levels should contain "CLASS_HIERARCHY" at 3 Scenario: DetailLevelMap created with pre-populated levels dict Given a DetailLevelMap for domain "uko-code:" with max depth 9 and levels "SIGNATURES" at 4 Then the map should resolve "SIGNATURES" to 4 # ---- FragmentProvenance ---- Scenario: Create a valid FragmentProvenance Given a FragmentProvenance with resource URI "uko-py:module/auth" Then the provenance resource_uri should be "uko-py:module/auth" And the provenance location should be empty And the provenance strategy should be empty Scenario: FragmentProvenance rejects empty resource_uri Then creating a FragmentProvenance with empty resource_uri should raise ValueError # ---- ContextBudget ---- Scenario: Create a valid ContextBudget Given a ContextBudget with max_tokens 8000 and reserved_tokens 1000 Then the budget available_tokens should be 7000 And the budget max_tokens should be 8000 And the budget reserved_tokens should be 1000 Scenario: ContextBudget with zero reservation Given a ContextBudget with max_tokens 4000 and reserved_tokens 0 Then the budget available_tokens should be 4000 Scenario: ContextBudget rejects negative max_tokens Then creating a ContextBudget with max_tokens -1 should raise ValueError Scenario: ContextBudget rejects negative reserved_tokens Then creating a ContextBudget with max_tokens 100 and reserved_tokens -5 should raise ValueError Scenario: ContextBudget rejects reserved exceeding max Then creating a ContextBudget with max_tokens 100 and reserved_tokens 200 should raise ValueError # ---- ContextFragment ---- Scenario: Create a valid ContextFragment Given a ContextFragment with uko_node "uko-py:class/AuthManager" and content "class AuthManager: ..." And the fragment has detail_depth 9 and token_count 800 And the fragment has relevance_score 0.95 Then the fragment uko_node should be "uko-py:class/AuthManager" And the fragment token_count should be 800 And the fragment relevance_score should be 0.95 And the fragment detail_depth should be 9 Scenario: ContextFragment rejects negative token_count Then creating a ContextFragment with token_count -1 should raise ValueError Scenario: ContextFragment rejects relevance_score above 1.0 Then creating a ContextFragment with relevance_score 1.5 should raise ValueError Scenario: ContextFragment rejects relevance_score below 0.0 Then creating a ContextFragment with relevance_score -0.1 should raise ValueError Scenario: ContextFragment rejects negative detail_depth Then creating a ContextFragment with detail_depth -1 should raise ValueError Scenario: ContextFragment rejects empty uko_node Then creating a ContextFragment with empty uko_node should raise ValueError # ---- ContextRequest ---- Scenario: Create a ContextRequest with defaults Given a ContextRequest with purpose "Understand the auth module" Then the request purpose should be "Understand the auth module" And the request breadth should be 2 And the request depth should be 3 And the request depth_gradient should be true And the request priority should be 0.5 And the request temporal should be "current" And the request query should be None And the request max_tokens should be None Scenario: Create a ContextRequest with all fields Given a full ContextRequest with query "auth flow" and focus "uko-py:class/AuthManager" And the request has breadth 3 and depth "SIGNATURES" And the request has priority 0.8 and purpose "Review auth" Then the request query should be "auth flow" And the request breadth should be 3 And the request depth should be "SIGNATURES" And the request priority should be 0.8 Scenario: ContextRequest rejects negative breadth Then creating a ContextRequest with breadth -1 should raise ValueError Scenario: ContextRequest rejects negative integer depth Then creating a ContextRequest with depth -1 should raise ValueError Scenario: ContextRequest rejects priority above 1.0 Then creating a ContextRequest with priority 1.5 should raise ValueError Scenario: ContextRequest rejects priority below 0.0 Then creating a ContextRequest with priority -0.1 should raise ValueError Scenario: ContextRequest accepts string depth Given a ContextRequest with depth "FULL_SOURCE" Then the request depth should be "FULL_SOURCE" Scenario: ContextRequest accepts zero breadth Given a ContextRequest with breadth 0 Then the request breadth should be 0 Scenario: ContextRequest accepts max_tokens Given a ContextRequest with max_tokens 4096 Then the request max_tokens should be 4096 Scenario: ContextRequest rejects negative max_tokens Then creating a ContextRequest with max_tokens -100 should raise ValueError # ---- AssembledContext ---- Scenario: Create a valid AssembledContext Given an AssembledContext with total_tokens 1500 and budget_used 0.75 And the assembled context has hash "abc123def" Then the assembled total_tokens should be 1500 And the assembled budget_used should be 0.75 And the assembled context_hash should be "abc123def" Scenario: AssembledContext rejects budget_used above 1.0 Then creating an AssembledContext with budget_used 1.5 should raise ValueError Scenario: AssembledContext rejects negative total_tokens Then creating an AssembledContext with total_tokens -1 should raise ValueError # ---- Context Skill Tools (Wired to ACMS Pipeline) ---- Scenario: request_context returns assembled context with fragments Given a context tier service with sample fragments When I call the request_context tool with purpose "test context" Then the request_context result should contain "fragments" key And the request_context result should contain "total_tokens" key Scenario: request_context returns empty result with no stored fragments Given an empty context tier service When I call the request_context tool with purpose "test context" Then the request_context result "fragments" should be an empty list And the request_context result "total_tokens" should be 0 Scenario: request_context filters fragments by query Given a context tier service with sample fragments When I call the request_context tool filtering by query "auth" Then the request_context result "fragments" should only contain matching content Scenario: request_context filters fragments by focus targets Given a context tier service with sample fragments When I call the request_context tool with focus on "auth" Then the request_context result "fragments" should only contain matching content Scenario: query_history returns entries for stored fragments Given a context tier service with sample fragments When I call the query_history tool with query "auth" Then the query_history result should contain "entries" key And the query_history result "entries" should not be empty Scenario: query_history returns empty entries when no match Given a context tier service with sample fragments When I call the query_history tool with query "nonexistent_xyz_content" Then the query_history result "entries" should be an empty list Scenario: get_context_budget returns budget state Given an empty context tier service When I call the get_context_budget tool Then the budget result should contain "max_tokens" key And the budget result should contain "reserved_tokens" key And the budget result should contain "available_tokens" key And the budget result should contain "used_tokens" key And the budget result "used_tokens" should be 0 Scenario: get_context_budget reports used tokens from hot tier Given a context tier service with sample fragments When I call the get_context_budget tool Then the budget result "used_tokens" should be greater than 0 Scenario: builtin/context SkillDefinition can be built When I build the builtin/context SkillDefinition Then the skill definition name should be "builtin/context" And the skill definition should have 3 resolved tools And the skill definition should be read-only Scenario: Context skill tools are registered in the tool registry Given a CRP tool registry with context tools registered Then the CRP registry should contain tool "builtin/request-context" And the CRP registry should contain tool "builtin/query-history" And the CRP registry should contain tool "builtin/get-context-budget" Scenario: Context skill tools have read-only capability Given a CRP tool registry with context tools registered Then CRP tool "builtin/request-context" should have read_only capability And CRP tool "builtin/query-history" should have read_only capability And CRP tool "builtin/get-context-budget" should have read_only capability Scenario: request_context tool requires purpose in schema Given a CRP tool registry with context tools registered Then CRP tool "builtin/request-context" should require "purpose" in input schema Scenario: query_history tool requires query in schema Given a CRP tool registry with context tools registered Then CRP tool "builtin/query-history" should require "query" in input schema