UAT: ContextBudget validation inconsistency — CRP model allows reserved_tokens == max_tokens but core model rejects it #2083

Open
opened 2026-04-03 03:55:20 +00:00 by freemo · 1 comment
Owner

Metadata

  • Branch: fix/acms-context-budget-validation-inconsistency
  • Commit Message: fix(acms): align ContextBudget validation between CRP and core models
  • Milestone: v3.7.0
  • Parent Epic: #396

Summary

There is a validation inconsistency between the two ContextBudget implementations in the ACMS subsystem:

  1. cleveragents/domain/models/acms/crp.py (ContextBudget): Uses > comparison — allows reserved_tokens == max_tokens (available_tokens would be 0).
  2. cleveragents/domain/models/core/context_fragment.py (ContextBudget): Uses >= comparison — rejects reserved_tokens == max_tokens.

Expected Behavior (from spec)

The spec defines available_tokens = max_tokens - reserved_tokens. A budget where reserved_tokens == max_tokens results in available_tokens = 0, which is a degenerate state that would cause the pipeline to produce empty context. Both models should consistently reject this case.

The BDD test in features/acms_pipeline.feature explicitly tests:

Scenario: Budget rejects reserved_tokens >= max_tokens
  When I create a budget with reserved_tokens equal to max_tokens
  Then an ACMS validation error should be raised

This test passes for the core ContextBudget but would FAIL if the CRP ContextBudget were used directly.

Actual Behavior

  • crp.ContextBudget(max_tokens=100, reserved_tokens=100)succeeds (available_tokens=0)
  • context_fragment.ContextBudget(max_tokens=100, reserved_tokens=100)raises ValueError

Code Locations

  • CRP model (permissive): src/cleveragents/domain/models/acms/crp.py, line 122: if self.reserved_tokens > self.max_tokens:
  • Core model (strict): src/cleveragents/domain/models/core/context_fragment.py, line 151: if self.reserved_tokens >= self.max_tokens:

Steps to Reproduce

from cleveragents.domain.models.acms.crp import ContextBudget as CRPBudget
from cleveragents.domain.models.core.context_fragment import ContextBudget as CoreBudget

# This succeeds (bug — should fail)
b = CRPBudget(max_tokens=100, reserved_tokens=100)
assert b.available_tokens == 0  # Degenerate state

# This correctly raises ValueError
try:
    CoreBudget(max_tokens=100, reserved_tokens=100)
except ValueError:
    pass  # Expected

Impact

  • Any code that uses crp.ContextBudget directly (rather than context_fragment.ContextBudget) can create degenerate budgets with 0 available tokens, causing the pipeline to silently produce empty context payloads.
  • The _simulate_context_assembly function in project_context.py uses crp.ContextFragment and crp.FragmentProvenance — if it also used crp.ContextBudget, it would be vulnerable.

Subtasks

  • Update crp.ContextBudget._validate_reservation to use >= instead of > for consistency
  • Add a BDD scenario to features/crp_models.feature testing that crp.ContextBudget also rejects reserved_tokens == max_tokens
  • Verify no existing code relies on the permissive behavior

Definition of Done

  • crp.ContextBudget rejects reserved_tokens >= max_tokens with a ValueError
  • BDD test added and passing
  • No regressions in existing tests
  • PR merged

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-uat-tester

## Metadata - **Branch**: `fix/acms-context-budget-validation-inconsistency` - **Commit Message**: `fix(acms): align ContextBudget validation between CRP and core models` - **Milestone**: v3.7.0 - **Parent Epic**: #396 ## Summary There is a validation inconsistency between the two `ContextBudget` implementations in the ACMS subsystem: 1. **`cleveragents/domain/models/acms/crp.py` (`ContextBudget`)**: Uses `>` comparison — allows `reserved_tokens == max_tokens` (available_tokens would be 0). 2. **`cleveragents/domain/models/core/context_fragment.py` (`ContextBudget`)**: Uses `>=` comparison — rejects `reserved_tokens == max_tokens`. ## Expected Behavior (from spec) The spec defines `available_tokens = max_tokens - reserved_tokens`. A budget where `reserved_tokens == max_tokens` results in `available_tokens = 0`, which is a degenerate state that would cause the pipeline to produce empty context. Both models should consistently reject this case. The BDD test in `features/acms_pipeline.feature` explicitly tests: ```gherkin Scenario: Budget rejects reserved_tokens >= max_tokens When I create a budget with reserved_tokens equal to max_tokens Then an ACMS validation error should be raised ``` This test passes for the core `ContextBudget` but would FAIL if the CRP `ContextBudget` were used directly. ## Actual Behavior - `crp.ContextBudget(max_tokens=100, reserved_tokens=100)` → **succeeds** (available_tokens=0) - `context_fragment.ContextBudget(max_tokens=100, reserved_tokens=100)` → **raises ValueError** ## Code Locations - **CRP model** (permissive): `src/cleveragents/domain/models/acms/crp.py`, line 122: `if self.reserved_tokens > self.max_tokens:` - **Core model** (strict): `src/cleveragents/domain/models/core/context_fragment.py`, line 151: `if self.reserved_tokens >= self.max_tokens:` ## Steps to Reproduce ```python from cleveragents.domain.models.acms.crp import ContextBudget as CRPBudget from cleveragents.domain.models.core.context_fragment import ContextBudget as CoreBudget # This succeeds (bug — should fail) b = CRPBudget(max_tokens=100, reserved_tokens=100) assert b.available_tokens == 0 # Degenerate state # This correctly raises ValueError try: CoreBudget(max_tokens=100, reserved_tokens=100) except ValueError: pass # Expected ``` ## Impact - Any code that uses `crp.ContextBudget` directly (rather than `context_fragment.ContextBudget`) can create degenerate budgets with 0 available tokens, causing the pipeline to silently produce empty context payloads. - The `_simulate_context_assembly` function in `project_context.py` uses `crp.ContextFragment` and `crp.FragmentProvenance` — if it also used `crp.ContextBudget`, it would be vulnerable. ## Subtasks - [ ] Update `crp.ContextBudget._validate_reservation` to use `>=` instead of `>` for consistency - [ ] Add a BDD scenario to `features/crp_models.feature` testing that `crp.ContextBudget` also rejects `reserved_tokens == max_tokens` - [ ] Verify no existing code relies on the permissive behavior ## Definition of Done - [ ] `crp.ContextBudget` rejects `reserved_tokens >= max_tokens` with a `ValueError` - [ ] BDD test added and passing - [ ] No regressions in existing tests - [ ] PR merged --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-uat-tester
freemo added this to the v3.7.0 milestone 2026-04-03 03:56:32 +00:00
freemo self-assigned this 2026-04-03 16:58:09 +00:00
Author
Owner

MoSCoW classification: Could Have

Rationale: This is a low-priority or backlog item. Desirable but not necessary for the milestone. Include only if time permits.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

MoSCoW classification: **Could Have** Rationale: This is a low-priority or backlog item. Desirable but not necessary for the milestone. Include only if time permits. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#396 Epic: ACMS Context Pipeline
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#2083
No description provided.