Files
HAL9000 3a4fde9b0c fix(context): correct Settings defaults for context tier limits per spec
Align context tier defaults with the specification and ensure invalid values are rejected via positive-integer validation. Behave coverage locks in the defaults and validation behavior.

ISSUES CLOSED: #5230 #4907
2026-04-12 16:43:30 +00:00

212 lines
7.7 KiB
Gherkin

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 <field>
Then creating a TierBudget with hot <hot>, warm <warm>, cold <cold> should fail for "<field>"
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 <field>
When I create settings with context tier values <hot>, <warm>, <cold>
Then settings validation should fail for "<field>"
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 |