fix(v3.7.0): ContextTierService defaults #1443 #1485
@@ -235,6 +235,8 @@ ensuring data is stored with proper parameter values.
|
||||
under `.opencode/` are covered by the lint gate.
|
||||
|
||||
### Fixed
|
||||
- **ContextTierService defaults aligned with TierBudget model** (#1443): Fixed three budget default constants in ``context_tier_settings.py`` that did not match the canonical ``TierBudget`` model defaults. ``DEFAULT_MAX_TOKENS_HOT`` was 8000 but should match the ``TierBudget`` default of 16000; ``DEFAULT_MAX_DECISIONS_WARM`` was 500 but should be 100; and ``DEFAULT_MAX_DECISIONS_COLD`` was 5000 but should be 500. These incorrect values caused wrong budget enforcement when settings were not provided (i.e. ``budget_from_settings(None)``).
|
||||
|
||||
- **ACMS execute-phase assembler respects project-level hot_max_tokens** (#11035): Fixed
|
||||
``_resolve_hot_max_tokens()`` to read ``hot_max_tokens`` from
|
||||
``context_policy_json["acms_config"]["hot_max_tokens"]`` — the correct sub-key written
|
||||
|
||||
@@ -108,6 +108,7 @@ Below are some of the specific details of various contributions.
|
||||
* HAL 9000 has contributed the ContextStrategy protocol and plugin registration system (PR #11106 / issue #8616): implemented the domain-model `ContextStrategy` Protocol with BackendSet, PlanContext, StrategyCapabilities, StrategyConfig, ContextStrategyResult, and StrategyRegistryEntry models. Six built-in strategies each implement real backend query logic respecting budget constraints. The StrategyRegistry service provides thread-safe registration/unregistration, Pydantic-validated config updates with immutable MappingProxyType fields, plugin discovery via register_from_module() with CWE-706 module-prefix allowlist guard, enabled list management, deterministic fragment ordering, and validation warnings. Comprehensive BDD test coverage in features/context_strategies.feature and features/context_strategy_registry.feature (120+ scenarios) (#8616).
|
||||
* HAL 9000 has contributed the A2A stdio transport for local mode (#691): implemented ``A2aStdioTransport`` class with JSON-RPC 2.0 message framing over stdin/stdout for subprocess communication, including process lifecycle management (connect/disconnect), request/response serialization, graceful shutdown with timeout-based termination, and type-safe path resolution for Python modules vs. executable scripts. Added full BDD test coverage (18 scenarios) in ``features/a2a_stdio_transport.feature`` with mock subprocess behavior in step definitions.
|
||||
* HAL 9000 has contributed the `plan apply --format json` spec-compliant envelope fix (PR #9817 / issue #9449): replaced raw plan dictionary output with a spec-required JSON envelope containing structured data fields for artifacts, changes, validation, sandbox cleanup, and lifecycle metrics across all output formats. Full BDD test suite in behave + Robot Framework integration tests added.
|
||||
* HAL 9000 has contributed the ContextTierService defaults fix (PR #1485 / issue #1443): corrected spec-aligned default values for `max_tokens_hot` (16000), `max_decisions_warm` (100), and `max_decisions_cold` (500) in ``context_tier_settings.py``. Added comprehensive BDD regression tests verifying all three interface contracts. (Parent Epic: #935)
|
||||
|
||||
# Details (PR Contributions)
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
"""Step definitions for TDD Issue #1443 regression tests.
|
||||
|
||||
Verifies that :file:`context_tier_settings.py` uses spec-aligned default values
|
||||
(hot=16000, warm=100, cold=500) rather than the old wrong values
|
||||
(hot=8000, warm=500, cold=5000).
|
||||
|
||||
Tests ``budget_from_settings(None)`` and module-level :data:`DEFAULT_MAX_*` constants.
|
||||
|
||||
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 (
|
||||
DEFAULT_MAX_DECISIONS_COLD,
|
||||
DEFAULT_MAX_DECISIONS_WARM,
|
||||
DEFAULT_MAX_TOKENS_HOT,
|
||||
budget_from_settings,
|
||||
)
|
||||
|
||||
__all__: list[str] = []
|
||||
|
||||
# Spec-aligned correct defaults and old wrong values (for assertion in steps)
|
||||
_SPEC_HOT: int = 16000
|
||||
_SPEC_WARM: int = 100
|
||||
_SPEC_COLD: int = 500
|
||||
_OLD_HOT: int = 8000
|
||||
_OLD_WARM: int = 500
|
||||
_OLD_COLD: int = 5000
|
||||
|
||||
|
||||
# --- budget_from_settings scenario steps ---
|
||||
|
||||
|
||||
@given("the budget helper has not been called yet")
|
||||
def step_given_budget_helper_not_called(context: Any) -> None:
|
||||
if not hasattr(context, "_budget_result"):
|
||||
context._budget_result = None
|
||||
|
||||
|
||||
@when("I invoke budget_from_settings with None config")
|
||||
def step_when_invoke_budget_helper(context: Any) -> None:
|
||||
context._budget_result = budget_from_settings(None)
|
||||
|
||||
|
|
||||
|
||||
# --- Budget capacity assertions (avoid collision with {val:d} param patterns) ---
|
||||
|
||||
|
||||
@then("the budget hot capacity matches 16000")
|
||||
def step_then_budget_hot_16000(context: Any) -> None:
|
||||
|
HAL9001
commented
BLOCKING: Three step definitions are missing for the first TierBudget scenario. The feature file at lines 28-30 references:
This step file only defines steps with the prefix 'the budget ...' (lines 79-91), which are different strings. Behave does exact string matching — these will raise UndefinedStep at runtime. Add these three step definitions:
Automated by CleverAgents Bot BLOCKING: Three step definitions are missing for the first TierBudget scenario.
The feature file at lines 28-30 references:
- Then max_tokens_hot should be 16000
- And max_decisions_warm should be 100
- And max_decisions_cold should be 500
This step file only defines steps with the prefix 'the budget ...' (lines 79-91), which are different strings. Behave does exact string matching — these will raise UndefinedStep at runtime.
Add these three step definitions:
@then("max_tokens_hot should be 16000")
def step_then_tier_budget_hot(context: Any) -> None:
assert context.budget.max_tokens_hot == _SPEC_HOT
@then("max_decisions_warm should be 100")
def step_then_tier_budget_warm(context: Any) -> None:
assert context.budget.max_decisions_warm == _SPEC_WARM
@then("max_decisions_cold should be 500")
def step_then_tier_budget_cold(context: Any) -> None:
assert context.budget.max_decisions_cold == _SPEC_COLD
---
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
|
||||
"""Verify budget.max_tokens_hot is the spec value, not the old wrong one."""
|
||||
assert context._budget_result.max_tokens_hot == _SPEC_HOT
|
||||
assert context._budget_result.max_tokens_hot != _OLD_HOT
|
||||
|
||||
|
||||
@then("the budget warm capacity matches 100")
|
||||
def step_then_budget_warm_100(context: Any) -> None:
|
||||
"""Verify budget.max_decisions_warm is the spec value, not the old wrong one."""
|
||||
assert context._budget_result.max_decisions_warm == _SPEC_WARM
|
||||
assert context._budget_result.max_decisions_warm != _OLD_WARM
|
||||
|
||||
|
||||
@then("the budget cold capacity matches 500")
|
||||
def step_then_budget_cold_500(context: Any) -> None:
|
||||
"""Verify budget.max_decisions_cold is the spec value, not the old wrong one."""
|
||||
assert context._budget_result.max_decisions_cold == _SPEC_COLD
|
||||
assert context._budget_result.max_decisions_cold != _OLD_COLD
|
||||
|
||||
|
||||
# --- Module constant scenarios ---
|
||||
|
||||
|
||||
@given("the module default constants exist")
|
||||
def step_given_module_constants_exist(context: Any) -> None:
|
||||
"""Verify we can import the module-level DEFAULT_MAX_* constants."""
|
||||
pass # Already imported at module level above
|
||||
|
||||
|
||||
@when(
|
||||
"I read DEFAULT_MAX_TOKENS_HOT, DEFAULT_MAX_DECISIONS_WARM and "
|
||||
"DEFAULT_MAX_DECISIONS_COLD"
|
||||
)
|
||||
def step_when_read_module_constants(context: Any) -> None:
|
||||
context._hot_const = DEFAULT_MAX_TOKENS_HOT
|
||||
context._warm_const = DEFAULT_MAX_DECISIONS_WARM
|
||||
context._cold_const = DEFAULT_MAX_DECISIONS_COLD
|
||||
|
||||
|
||||
@then("all three module constants must equal spec-aligned values")
|
||||
def step_then_module_constants_correct(context: Any) -> None:
|
||||
assert context._hot_const == _SPEC_HOT
|
||||
assert context._warm_const == _SPEC_WARM
|
||||
assert context._cold_const == _SPEC_COLD
|
||||
|
||||
|
||||
# --- Anti-regression assertion ---
|
||||
|
||||
|
||||
@then("every budget field must NOT be an old wrong default value")
|
||||
def step_then_budget_not_legacy(context: Any) -> None:
|
||||
"""Ensure none of the three fields reverted to old wrong defaults."""
|
||||
assert context._budget_result.max_tokens_hot not in (_OLD_HOT,)
|
||||
assert context._budget_result.max_decisions_warm not in (_OLD_WARM,)
|
||||
assert context._budget_result.max_decisions_cold not in (_OLD_COLD,)
|
||||
@@ -0,0 +1,46 @@
|
||||
# TDD regression test for bug #1443 - context_tier_settings.py wrong defaults.
|
||||
|
HAL9001
commented
Question: do your test assertions use correct spec values (hot=16000/warm=100/cold=500) or wrong defaults (8000/500/5000)? If wrong, tests validate broken behavior. Question: do your test assertions use correct spec values (hot=16000/warm=100/cold=500) or wrong defaults (8000/500/5000)? If wrong, tests validate broken behavior.
|
||||
#
|
||||
# Issue #1443 documented that DEFAULT constants in ``context_tier_settings.py``
|
||||
# were hardcoded to wrong values (hot=8000, warm=500, cold=5000) instead of the
|
||||
# spec-aligned values (hot=16000, warm=100, cold=500). This test verifies that
|
||||
# ``budget_from_settings(None)`` and module-level default constants use correct
|
||||
# spec-defined values.
|
||||
#
|
||||
# See: https://git.cleverthis.com/cleveragents/cleveragents-core/issues/1443
|
||||
|
||||
@tdd_issue @tdd_issue_1443
|
||||
Feature: TDD Issue #1443 - Correct defaults in context_tier_settings.py
|
||||
|
||||
As a developer calling budget_from_settings with no configuration
|
||||
I want the returned TierBudget to use spec-defined capacity limits
|
||||
So that hot/warm/cold tier eviction behavior matches the specification
|
||||
|
||||
@tdd_issue @tdd_issue_1443
|
||||
Scenario: budget_from_settings(None) hot value meets spec 16000
|
||||
Given the budget helper has not been called yet
|
||||
When I invoke budget_from_settings with None config
|
||||
Then the budget hot capacity matches 16000
|
||||
|
HAL9001
commented
Good BDD test coverage with 6 Gherkin scenarios tagging @tdd_issue @tdd_issue_1443. Covers TierBudget(), ContextTierService(none args/None), Settings(), and budget_from_settings(None). Each scenario is named as living documentation. Suggestion: Consider adding edge case scenarios for field validators (negative values rejected by gt=0 on TierBudget fields, ge=1 on Settings fields) to ensure the validation layer works correctly alongside default value changes.Automated by CleverAgents Bot Good BDD test coverage with 6 Gherkin scenarios tagging @tdd_issue @tdd_issue_1443. Covers TierBudget(), ContextTierService(none args/None), Settings(), and budget_from_settings(None). Each scenario is named as living documentation.
Suggestion: Consider adding edge case scenarios for field validators (negative values rejected by gt=0 on TierBudget fields, ge=1 on Settings fields) to ensure the validation layer works correctly alongside default value changes.
---
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
|
||||
|
||||
@tdd_issue @tdd_issue_1443
|
||||
Scenario: budget_from_settings(None) warm value meets spec 100
|
||||
Given the budget helper has not been called yet
|
||||
When I invoke budget_from_settings with None config
|
||||
Then the budget warm capacity matches 100
|
||||
|
HAL9001
commented
BLOCKING: The step Fix option A: Add the bare step definitions to the step file: Fix option B: Change the feature file steps to match existing definitions: Automated by CleverAgents Bot BLOCKING: The step `Then max_tokens_hot should be 16000` (and the two `And` steps on lines 29-30) have no matching step definition decorator in `tdd_context_tier_defaults_1443_steps.py`. The step file defines `@then("the budget max_tokens_hot should be 16000")` — a **different string**. Behave uses exact string matching, so these steps will raise `UndefinedStep` at runtime, causing Scenario 1 to fail entirely.
Fix option A: Add the bare step definitions to the step file:
```python
@then("max_tokens_hot should be 16000")
def step_then_tier_budget_hot_bare(context: Any) -> None:
assert context.budget.max_tokens_hot == _SPEC_HOT
@then("max_decisions_warm should be 100")
def step_then_tier_budget_warm_bare(context: Any) -> None:
assert context.budget.max_decisions_warm == _SPEC_WARM
@then("max_decisions_cold should be 500")
def step_then_tier_budget_cold_bare(context: Any) -> None:
assert context.budget.max_decisions_cold == _SPEC_COLD
```
Fix option B: Change the feature file steps to match existing definitions:
```gherkin
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
```
---
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
|
||||
|
||||
@tdd_issue @tdd_issue_1443
|
||||
Scenario: budget_from_settings(None) cold value meets spec 500
|
||||
Given the budget helper has not been called yet
|
||||
When I invoke budget_from_settings with None config
|
||||
Then the budget cold capacity matches 500
|
||||
|
||||
@tdd_issue @tdd_issue_1443
|
||||
Scenario: Module-level DEFAULT_MAX constants match spec values
|
||||
Given the module default constants exist
|
||||
When I read DEFAULT_MAX_TOKENS_HOT, DEFAULT_MAX_DECISIONS_WARM and DEFAULT_MAX_DECISIONS_COLD
|
||||
Then all three module constants must equal spec-aligned values
|
||||
|
||||
@tdd_issue @tdd_issue_1443
|
||||
Scenario: budget_from_settings result differs from old wrong defaults entirely
|
||||
Given the budget helper has not been called yet
|
||||
When I invoke budget_from_settings with None config
|
||||
Then every budget field must NOT be an old wrong default value
|
||||
@@ -18,9 +18,9 @@ from cleveragents.domain.models.acms.tiers import TierBudget
|
||||
# Default budget when settings are not provided
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
DEFAULT_MAX_TOKENS_HOT = 8000
|
||||
DEFAULT_MAX_DECISIONS_WARM = 500
|
||||
DEFAULT_MAX_DECISIONS_COLD = 5000
|
||||
DEFAULT_MAX_TOKENS_HOT = 16000
|
||||
|
HAL9001
commented
BLOCKING: DEFAULT_MAX_TOKENS_HOT=8000 wrong per spec. Must be 16000. Also line 22 (WARM:500-100) and line 23 (COLD:5000-500). BLOCKING: DEFAULT_MAX_TOKENS_HOT=8000 wrong per spec. Must be 16000. Also line 22 (WARM:500-100) and line 23 (COLD:5000-500).
HAL9001
commented
Production fix verified correct -- default values changed from wrong defaults (8000/500/5000) to spec-aligned values (16000/100/500). Matches specs/docs/specification.md lines 30591-30593. OK.Automated by CleverAgents Bot Production fix verified correct -- default values changed from wrong defaults (8000/500/5000) to spec-aligned values (16000/100/500). Matches specs/docs/specification.md lines 30591-30593. OK.
---
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
|
||||
DEFAULT_MAX_DECISIONS_WARM = 100
|
||||
DEFAULT_MAX_DECISIONS_COLD = 500
|
||||
|
HAL9001
commented
Suggestion: The module docstring references issue #7547 but the defaults were wrong until this fix. Consider adding a comment referencing issue #1443 and the spec-correct values, e.g.: Suggestion: The module docstring references issue #7547 but the defaults were wrong until this fix. Consider adding a comment referencing issue #1443 and the spec-correct values, e.g.: `# Corrected in PR #1485/Issue #1443 to match docs/specification.md defaults.`
HAL9001
commented
Production fix verified correct: DEFAULT_MAX_TOKENS_HOT=16000, DEFAULT_MAX_DECISIONS_WARM=100, DEFAULT_MAX_DECISIONS_COLD=500. These match docs/specification.md ACMS tier sections and issue #1443 requirements. Good.Automated by CleverAgents Bot Production fix verified correct: DEFAULT_MAX_TOKENS_HOT=16000, DEFAULT_MAX_DECISIONS_WARM=100, DEFAULT_MAX_DECISIONS_COLD=500. These match docs/specification.md ACMS tier sections and issue #1443 requirements. Good.
---
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Default runtime policy values
|
||||
|
||||
Step definitions file -- 167 lines, well under the 500-line limit. All public functions have docstrings.
Suggestion: Function step_then_inspect_budget_defaults uses a @when decorator but has "then" in its name. Consider renaming to step_when_inspect_budget_defaults for naming consistency (non-blocking).
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker