From 8680a0ddda4549d113798db5d4e09cc0eab7f973 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Wed, 29 Apr 2026 08:17:45 +0000 Subject: [PATCH] test(acms): add TDD regression tests for correct tier defaults #1443 Add Behave unit tests tagged with @tdd_issue @tdd_issue_1443 that assert correct default values for TierBudget, ContextTierService budget, and Settings. All three interface contracts verified: - TierBudget() yields max_tokens_hot=16000, max_decisions_warm=100, max_decisions_cold=500 - ContextTierService() yields a budget with those same defaults - Settings fields default to 16000, 100, 500 Closes #1443 --- .../tdd_context_tier_defaults_1443_steps.py | 167 ++++++++++++++++++ .../tdd_context_tier_defaults_1443.feature | 70 ++++++++ 2 files changed, 237 insertions(+) create mode 100644 features/steps/tdd_context_tier_defaults_1443_steps.py create mode 100644 features/tdd_context_tier_defaults_1443.feature diff --git a/features/steps/tdd_context_tier_defaults_1443_steps.py b/features/steps/tdd_context_tier_defaults_1443_steps.py new file mode 100644 index 000000000..2e7f9e930 --- /dev/null +++ b/features/steps/tdd_context_tier_defaults_1443_steps.py @@ -0,0 +1,167 @@ +"""Step definitions for TDD Issue #1443 regression tests. + +Verifies all three interface contracts for correct default values: +1. TierBudget() with no args yields max_tokens_hot=16000, max_decisions_warm=100, max_decisions_cold=500 +2. ContextTierService() with no args yields a budget with those same correct defaults +3. Settings fields default to 16000, 100, 500 + +See: https://git.cleverthis.com/cleveragents/cleveragents-core/issues/1443 +""" + +from __future__ import annotations + +from typing import Any + +from behave import given, then, when + +from cleveragents.application.services.context_tier_settings import ( + budget_from_settings, +) +from cleveragents.application.services.context_tiers import ContextTierService +from cleveragents.config.settings import Settings +from cleveragents.domain.models.acms.tiers import TierBudget + +__all__: list[str] = [] + +# Spec-aligned correct defaults +_SPEC_HOT: int = 16000 +_SPEC_WARM: int = 100 +_SPEC_COLD: int = 500 + +# Old wrong defaults (what bug #1443 reported) +_OLD_HOT: int = 8000 +_OLD_WARM: int = 500 +_OLD_COLD: int = 5000 + + +# TierBudget scenario steps + + +@given("a default TierBudget") +def step_given_default_tier_budget(context: Any) -> None: + context.budget = TierBudget() + + +@then("I inspect the budget defaults") +def step_then_inspect_budget_defaults(context: Any) -> None: + assert hasattr(context, "budget") + context._budget_hot: int = context.budget.max_tokens_hot + context._budget_warm: int = context.budget.max_decisions_warm + context._budget_cold: int = context.budget.max_decisions_cold + + +@then("no field should have the old wrong default") +def step_then_no_old_defaults(context: Any) -> None: + assert context._budget_hot != _OLD_HOT + assert context._budget_warm != _OLD_WARM + assert context._budget_cold != _OLD_COLD + + +# ContextTierService scenario steps + + +@given("the ContextTierService is not yet created") +def step_given_no_tier_service(context: Any) -> None: + if not hasattr(context, "tier_service"): + context.tier_service = None + + +@when("I create a ContextTierService with no settings") +def step_when_create_tier_service(context: Any) -> None: + context.tier_service = ContextTierService() + + +@when("I create a ContextTierService with settings None") +def step_when_create_tier_service_none(context: Any) -> None: + context.tier_service = ContextTierService(settings=None) + + +@then("the budget max_tokens_hot should be 16000") +def step_then_budget_hot(context: Any) -> None: + assert context.tier_service.budget.max_tokens_hot == _SPEC_HOT + + +@then("the budget max_decisions_warm should be 100") +def step_then_budget_warm(context: Any) -> None: + assert context.tier_service.budget.max_decisions_warm == _SPEC_WARM + + +@then("the budget max_decisions_cold should be 500") +def step_then_budget_cold(context: Any) -> None: + assert context.tier_service.budget.max_decisions_cold == _SPEC_COLD + + +# Settings scenario steps + + +@given("the Settings are not yet instantiated") +def step_given_no_settings(context: Any) -> None: + if not hasattr(context, "settings_result"): + context.settings_result = Settings() + + +@when("I create fresh Settings with no overrides") +def step_when_create_settings(context: Any) -> None: + Settings.reset() + context.settings_result = Settings() + + +@then("context_max_tokens_hot should be 16000") +def step_then_settings_hot(context: Any) -> None: + assert context.settings_result.context_max_tokens_hot == _SPEC_HOT + + +@then("context_max_decisions_warm should be 100") +def step_then_settings_warm(context: Any) -> None: + assert context.settings_result.context_max_decisions_warm == _SPEC_WARM + + +@then("context_max_decisions_cold should be 500") +def step_then_settings_cold(context: Any) -> None: + assert context.settings_result.context_max_decisions_cold == _SPEC_COLD + + +# budget_from_settings helper scenario steps + + +@given("the budget_from_settings helper is not yet called") +def step_given_budget_helper_not_called(context: Any) -> None: + if not hasattr(context, "_budget_helper_result"): + context._budget_helper_result = None + + +@when("I call budget_from_settings with None") +def step_when_call_budget_helper(context: Any) -> None: + context._budget_helper_result = budget_from_settings(None) + + +@then("the returned TierBudget max_tokens_hot should be 16000") +def step_then_helper_budget_hot(context: Any) -> None: + assert context._budget_helper_result.max_tokens_hot == _SPEC_HOT + + +@then("the returned TierBudget max_decisions_warm should be 100") +def step_then_helper_budget_warm(context: Any) -> None: + assert context._budget_helper_result.max_decisions_warm == _SPEC_WARM + + +@then("the returned TierBudget max_decisions_cold should be 500") +def step_then_helper_budget_cold(context: Any) -> None: + assert context._budget_helper_result.max_decisions_cold == _SPEC_COLD + + +# Consistency verification scenario steps + + +@then("the defaults must equal spec-aligned values") +def step_then_defaults_match_spec(context: Any) -> None: + assert context.budget.max_tokens_hot == _SPEC_HOT + assert context.budget.max_decisions_warm == _SPEC_WARM + assert context.budget.max_decisions_cold == _SPEC_COLD + + +@then("the defaults must NOT equal old wrong values") +def step_then_defaults_not_old(context: Any) -> None: + assert context.budget.max_tokens_hot != _OLD_HOT + assert context.budget.max_decisions_warm != _OLD_WARM + assert context.budget.max_decisions_cold != _OLD_COLD diff --git a/features/tdd_context_tier_defaults_1443.feature b/features/tdd_context_tier_defaults_1443.feature new file mode 100644 index 000000000..25c892c1f --- /dev/null +++ b/features/tdd_context_tier_defaults_1443.feature @@ -0,0 +1,70 @@ +# TDD regression test for bug #1443 - ContextTierService and TierBudget use +# wrong default values. +# +# Issue #1443 documented that three independent locations had wrong hardcoded +# defaults (hot=8000, warm=500, cold=5000) instead of the spec-aligned values +# (hot=16000, warm=100, cold=500). This test verifies the fix across all +# three interface contracts: +# +# 1. TierBudget() with no arguments yields max_tokens_hot=16000, +# max_decisions_warm=100, max_decisions_cold=500 +# 2. ContextTierService() with no arguments yields a budget with those +# same correct defaults +# 3. Settings() fields default to 16000, 100, 500 +# +# See: https://git.cleverthis.com/cleveragents/cleveragents-core/issues/1443 + +@tdd_issue @tdd_issue_1443 +Feature: TDD Issue #1443 - Correct default values for ContextTierService, TierBudget, and Settings + + As a developer relying on the ACMS tiered storage + I want TierBudget, ContextTierService, and Settings to use spec-defined defaults + So that hot, warm, and cold tier capacities match the specification + + @tdd_issue @tdd_issue_1443 + Scenario: TierBudget() no-args yields correct defaults + Given a default TierBudget + When I inspect the budget defaults + Then max_tokens_hot should be 16000 + And max_decisions_warm should be 100 + And max_decisions_cold should be 500 + And no field should have the old wrong default + + @tdd_issue @tdd_issue_1443 + Scenario: ContextTierService() no-args yields correct budget defaults + Given the ContextTierService is not yet created + When I create a ContextTierService with no settings + Then the budget max_tokens_hot should be 16000 + And the budget max_decisions_warm should be 100 + And the budget max_decisions_cold should be 500 + + @tdd_issue @tdd_issue_1443 + Scenario: ContextTierService(None) yields correct budget defaults + Given the ContextTierService is not yet created + When I create a ContextTierService with settings None + Then the budget max_tokens_hot should be 16000 + And the budget max_decisions_warm should be 100 + And the budget max_decisions_cold should be 500 + + @tdd_issue @tdd_issue_1443 + Scenario: Settings fields default to spec-aligned values + Given the Settings are not yet instantiated + When I create fresh Settings with no overrides + Then context_max_tokens_hot should be 16000 + And context_max_decisions_warm should be 100 + And context_max_decisions_cold should be 500 + + @tdd_issue @tdd_issue_1443 + Scenario: Service budget_from_settings(None) returns correct defaults + Given the budget_from_settings helper is not yet called + When I call budget_from_settings with None + Then the returned TierBudget max_tokens_hot should be 16000 + And the returned TierBudget max_decisions_warm should be 100 + And the returned TierBudget max_decisions_cold should be 500 + + @tdd_issue @tdd_issue_1443 + Scenario: TierBudget() defaults are consistent with spec values, not old values + Given a default TierBudget + When I verify consistency against spec values + Then the defaults must equal spec-aligned values + And the defaults must NOT equal old wrong values