Feature: ACMS Context Tiers As a developer I want hot/warm/cold context tiers with actor views and project scoping So that the context management system can efficiently manage fragment lifecycle # ---- ContextTier enum ---- Scenario: ContextTier has three values Then ContextTier should have values "hot", "warm", "cold" # ---- ActorRole enum ---- Scenario: ActorRole has four values Then ActorRole should have values "strategist", "executor", "reviewer", "estimator" # ---- TieredFragment ---- Scenario: Create a valid TieredFragment Given a TieredFragment with id "frag-001" and content "hello world" Then the fragment tier should be "hot" And the fragment token_count should be 0 And the fragment access_count should be 0 Scenario: TieredFragment rejects empty fragment_id Then creating a TieredFragment with empty fragment_id should raise ValidationError Scenario: TieredFragment rejects negative token_count Then creating a TieredFragment with negative token_count should raise ValidationError # ---- TierBudget ---- Scenario: TierBudget has sensible defaults Given a default TierBudget Then max_tokens_hot should be 16000 And max_decisions_warm should be 100 And max_decisions_cold should be 500 Scenario Outline: TierBudget rejects non-positive Then creating a TierBudget with hot , warm , cold should fail for "" Examples: | hot | warm | cold | field | | 0 | 100 | 500 | max_tokens_hot | | 16000 | 0 | 500 | max_decisions_warm | | 16000 | 100 | 0 | max_decisions_cold | | -50 | 100 | 500 | max_tokens_hot | # ---- ActorContextView ---- Scenario: Strategist sees all tiers by default Given an ActorContextView for "strategist" Then effective tiers should be "hot", "warm", "cold" Scenario: Executor sees hot and warm by default Given an ActorContextView for "executor" Then effective tiers should be "hot", "warm" Scenario: Reviewer sees only hot by default Given an ActorContextView for "reviewer" Then effective tiers should be "hot" # ---- TierMetrics ---- Scenario: TierMetrics defaults to zero Given a default TierMetrics Then total_fragments should be 0 And hot_hit_rate should be 0.0 # ---- ScopedBackendView ---- Scenario: ScopedBackendView filters by project Given a ScopedBackendView for project "proj-a" And a TieredFragment with id "frag-a" in project "proj-a" And a TieredFragment with id "frag-b" in project "proj-b" Then fragment "frag-a" should be visible And fragment "frag-b" should not be visible Scenario: ScopedBackendView excludes empty project_name Given a ScopedBackendView for project "proj-a" And a TieredFragment with id "frag-x" and no project Then fragment "frag-x" should not be visible # ---- ContextTierService: store/get ---- Scenario: Store and retrieve a fragment Given a ContextTierService When I store a fragment with id "f1" content "data" in tier "hot" Then tier getting "f1" should return content "data" Scenario: Get returns None for unknown fragment Given a ContextTierService Then tier getting "nonexistent" should return None # ---- ContextTierService: promotion ---- Scenario: Promote from cold to warm Given a ContextTierService When I store a fragment with id "f2" content "cold-data" in tier "cold" And I promote "f2" Then "f2" should be in tier "warm" Scenario: Promote from warm to hot Given a ContextTierService When I store a fragment with id "f3" content "warm-data" in tier "warm" And I promote "f3" Then "f3" should be in tier "hot" Scenario: Promote unknown fragment returns None Given a ContextTierService Then promoting "unknown" should return None # ---- ContextTierService: demotion ---- Scenario: Demote from hot to warm Given a ContextTierService When I store a fragment with id "f4" content "hot-data" in tier "hot" And I demote "f4" Then "f4" should be in tier "warm" Scenario: Demote from warm to cold with summarization Given a ContextTierService When I store a long fragment "f5" in tier "warm" And I demote "f5" Then "f5" should be in tier "cold" And "f5" content should be summarized Scenario: Demote unknown fragment returns None Given a ContextTierService Then demoting "unknown" should return None # ---- ContextTierService: LRU eviction ---- Scenario: Evict LRU fragments from hot tier Given a ContextTierService When I store a fragment with id "e1" content "first" in tier "hot" And I store a fragment with id "e2" content "second" in tier "hot" And I store a fragment with id "e3" content "third" in tier "hot" And I evict 2 LRU fragments from "hot" Then "hot" tier should have 1 fragment Scenario: Evict with invalid count raises ValueError Given a ContextTierService Then evicting 0 from "hot" should raise ValueError # ---- ContextTierService: actor views ---- Scenario: Strategist sees fragments from all tiers Given a ContextTierService When I store fragment "a1" with content "hot" tier "hot" project "p1" And I store fragment "a2" with content "warm" tier "warm" project "p1" And I store fragment "a3" with content "cold" tier "cold" project "p1" Then strategist for project "p1" should see 3 fragments Scenario: Executor sees only hot and warm Given a ContextTierService When I store fragment "b1" with content "hot" tier "hot" project "p1" And I store fragment "b2" with content "warm" tier "warm" project "p1" And I store fragment "b3" with content "cold" tier "cold" project "p1" Then executor for project "p1" should see 2 fragments Scenario: Reviewer sees only hot Given a ContextTierService When I store fragment "c1" with content "hot" tier "hot" project "p1" And I store fragment "c2" with content "warm" tier "warm" project "p1" Then reviewer for project "p1" should see 1 fragment # ---- ContextTierService: project scoping ---- Scenario: Scoped view filters by project Given a ContextTierService When I store fragment "s1" with content "yes" tier "hot" project "alpha" And I store fragment "s2" with content "no" tier "hot" project "beta" Then scoped view for "alpha" should have 1 fragment # ---- ContextTierService: metrics ---- Scenario: Metrics track hits and misses Given a ContextTierService When I store a fragment with id "m1" content "data" in tier "hot" And I get fragment "m1" And I get fragment "nonexistent" Then hot_hit_count should be 1 And hot_miss_count should be 1 # ---- DI Container ---- Scenario: DI container provides context_tier_service Given the DI container is reset Then the container should provide a context_tier_service And the context_tier_service should be a ContextTierService Scenario: DI container context_tier_service is singleton Given the DI container is reset Then resolving context_tier_service twice should return the same instance # ---- Settings ---- Scenario: Settings expose spec-aligned context tier defaults Then settings should have context_max_tokens_hot And settings should have context_max_decisions_warm And settings should have context_max_decisions_cold Scenario Outline: Context tier settings reject non-positive When I create settings with context tier values , , Then settings validation should fail for "" Examples: | hot | warm | cold | field | | 0 | 100 | 500 | context_max_tokens_hot | | 16000 | 0 | 500 | context_max_decisions_warm | | 16000 | 100 | 0 | context_max_decisions_cold |