[BUG] DefaultDepthResolver silently ignores budget parameter — depth fallback (steps [9,4,2,0]) never fires when context budget is tight #9174

Open
opened 2026-04-14 09:13:33 +00:00 by HAL9000 · 1 comment
Owner

Metadata

  • Commit Message: fix(acms): implement DetailDepthResolver budget-aware depth fallback steps [9,4,2,0]
  • Branch: bugfix/acms-default-depth-resolver-budget-ignored

Background and Context

Feature Area: ACMS & Context Management
Spec Reference: ADR-014 — "BudgetPacker: Fits scored fragments into the token budget using a greedy knapsack algorithm with depth fallback (steps: [9, 4, 2, 0]). Minimum fragment size: 10 tokens."; ADR-014 Constraints — "Fragments need progressive detail depth so budget-constrained assemblies degrade gracefully rather than omitting content entirely"; docs/reference/acms.md v1 Known Limitations — "DetailDepthResolver.resolve() Missing budget parameter — spec target: resolve(fragments, budget)"

The ACMS pipeline (ACMSPipeline) is responsible for assembling context fragments into a token-budget-constrained context window. Per ADR-014, when the available token budget is tight, the DetailDepthResolver should downgrade fragments to shallower detail depths following the fallback steps [9, 4, 2, 0] before resorting to omitting fragments entirely. This is the spec's "graceful degradation" mechanism.

The DefaultDepthResolver in src/cleveragents/application/services/acms_service.py accepts a budget parameter but silently ignores it, returning fragments unchanged regardless of budget pressure. This is a known limitation explicitly documented in docs/reference/acms.md v1 Known Limitations table.

Expected Behavior

When the context token budget is tight, the DetailDepthResolver should downgrade fragments to shallower detail depths (following the fallback steps [9, 4, 2, 0]) so that more fragments fit within the budget. This is the spec's "graceful degradation" mechanism — fragments are shown at shallower depth rather than omitted entirely.

Current (Buggy) Behavior

The DefaultDepthResolver in src/cleveragents/application/services/acms_service.py accepts a budget parameter but silently ignores it, returning fragments unchanged regardless of budget pressure:

class DefaultDepthResolver:
    """No-op depth resolver — returns fragments unchanged."""
    def resolve(self, fragments, budget: int = 0) -> Sequence[ContextFragment]:
        return fragments  # budget is never used

The ACMSPipeline.assemble() passes budget.available_tokens to resolve(), but since DefaultDepthResolver ignores it, depth fallback never occurs. When the budget is exhausted, the BudgetPacker simply omits fragments entirely instead of first trying to include them at a shallower depth.

Impact: The spec's graceful degradation guarantee is broken. Under budget pressure, fragments are dropped rather than downgraded. This can cause actors to miss important structural context (e.g., class signatures) that would have fit at depth 0 or 2 even when the full source (depth 9) doesn't fit.

Steps to Reproduce

from cleveragents.application.services.acms_service import ACMSPipeline, DefaultDepthResolver
from cleveragents.domain.models.core.context_fragment import ContextBudget, ContextFragment

resolver = DefaultDepthResolver()
# Create a fragment at depth 9 (full source) with 1000 tokens
# Budget is only 50 tokens — depth fallback should reduce to depth 0
fragments = [...]  # fragment with detail_depth=9, token_count=1000
result = resolver.resolve(fragments, budget=50)
# Bug: result still contains the depth-9 fragment unchanged
# Expected: fragment should be downgraded to depth 0 (10 tokens) to fit
assert result[0].detail_depth == 9  # passes — bug confirmed

Acceptance Criteria

  • DefaultDepthResolver.resolve(fragments, budget) applies depth fallback steps [9, 4, 2, 0] when a fragment's token_count exceeds the per-fragment budget share
  • Fragments are downgraded to the next shallower depth step before being omitted when budget is tight
  • Integration with UKO detail level maps produces correct shallower-depth renderings
  • BDD scenarios for depth fallback pass (tight budget → downgrade before omit; depth-9 fragment exceeding budget → included at depth 4 if it fits)
  • ACMSPipeline integration test: assembled context under tight budget contains depth-downgraded fragments, not empty result
  • docs/reference/acms.md v1 Known Limitations entry for DetailDepthResolver.resolve() missing budget parameter is removed
  • All existing pipeline tests pass

Subtasks

  • Implement DetailDepthResolver.resolve(fragments, budget) with depth fallback steps [9, 4, 2, 0]
  • When a fragment's token_count exceeds the per-fragment budget share, attempt to re-render at the next shallower depth step
  • Integrate with UKO detail level maps to produce correct shallower-depth renderings
  • Add BDD scenarios: "Given a tight budget, fragments are downgraded to shallower depths before being omitted"
  • Add BDD scenarios: "Given a fragment at depth 9 that exceeds budget, it is included at depth 4 if that fits"
  • Update docs/reference/acms.md v1 Known Limitations table to remove this entry once resolved

Definition of Done

  • DefaultDepthResolver.resolve(fragments, budget) applies depth fallback steps [9, 4, 2, 0]
  • Fragments are downgraded to shallower depths before being omitted when budget is tight
  • BDD scenarios for depth fallback pass
  • ACMSPipeline integration test: assembled context under tight budget contains depth-downgraded fragments, not empty result
  • All existing pipeline tests pass
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done

Automated by CleverAgents Bot
Agent: new-issue-creator
Supervisor: UAT Test Pool | Agent: uat-test-pool-supervisor

## Metadata - **Commit Message**: `fix(acms): implement DetailDepthResolver budget-aware depth fallback steps [9,4,2,0]` - **Branch**: `bugfix/acms-default-depth-resolver-budget-ignored` ## Background and Context **Feature Area**: ACMS & Context Management **Spec Reference**: ADR-014 — "BudgetPacker: Fits scored fragments into the token budget using a greedy knapsack algorithm with depth fallback (steps: [9, 4, 2, 0]). Minimum fragment size: 10 tokens."; ADR-014 Constraints — "Fragments need progressive detail depth so budget-constrained assemblies degrade gracefully rather than omitting content entirely"; `docs/reference/acms.md` v1 Known Limitations — "`DetailDepthResolver.resolve()` Missing `budget` parameter — spec target: `resolve(fragments, budget)`" The ACMS pipeline (`ACMSPipeline`) is responsible for assembling context fragments into a token-budget-constrained context window. Per ADR-014, when the available token budget is tight, the `DetailDepthResolver` should downgrade fragments to shallower detail depths following the fallback steps `[9, 4, 2, 0]` before resorting to omitting fragments entirely. This is the spec's "graceful degradation" mechanism. The `DefaultDepthResolver` in `src/cleveragents/application/services/acms_service.py` accepts a `budget` parameter but **silently ignores it**, returning fragments unchanged regardless of budget pressure. This is a known limitation explicitly documented in `docs/reference/acms.md` v1 Known Limitations table. ## Expected Behavior When the context token budget is tight, the `DetailDepthResolver` should downgrade fragments to shallower detail depths (following the fallback steps `[9, 4, 2, 0]`) so that more fragments fit within the budget. This is the spec's "graceful degradation" mechanism — fragments are shown at shallower depth rather than omitted entirely. ## Current (Buggy) Behavior The `DefaultDepthResolver` in `src/cleveragents/application/services/acms_service.py` accepts a `budget` parameter but **silently ignores it**, returning fragments unchanged regardless of budget pressure: ```python class DefaultDepthResolver: """No-op depth resolver — returns fragments unchanged.""" def resolve(self, fragments, budget: int = 0) -> Sequence[ContextFragment]: return fragments # budget is never used ``` The `ACMSPipeline.assemble()` passes `budget.available_tokens` to `resolve()`, but since `DefaultDepthResolver` ignores it, depth fallback never occurs. When the budget is exhausted, the `BudgetPacker` simply omits fragments entirely instead of first trying to include them at a shallower depth. **Impact**: The spec's graceful degradation guarantee is broken. Under budget pressure, fragments are dropped rather than downgraded. This can cause actors to miss important structural context (e.g., class signatures) that would have fit at depth 0 or 2 even when the full source (depth 9) doesn't fit. ## Steps to Reproduce ```python from cleveragents.application.services.acms_service import ACMSPipeline, DefaultDepthResolver from cleveragents.domain.models.core.context_fragment import ContextBudget, ContextFragment resolver = DefaultDepthResolver() # Create a fragment at depth 9 (full source) with 1000 tokens # Budget is only 50 tokens — depth fallback should reduce to depth 0 fragments = [...] # fragment with detail_depth=9, token_count=1000 result = resolver.resolve(fragments, budget=50) # Bug: result still contains the depth-9 fragment unchanged # Expected: fragment should be downgraded to depth 0 (10 tokens) to fit assert result[0].detail_depth == 9 # passes — bug confirmed ``` ## Acceptance Criteria - [ ] `DefaultDepthResolver.resolve(fragments, budget)` applies depth fallback steps `[9, 4, 2, 0]` when a fragment's `token_count` exceeds the per-fragment budget share - [ ] Fragments are downgraded to the next shallower depth step before being omitted when budget is tight - [ ] Integration with `UKO` detail level maps produces correct shallower-depth renderings - [ ] BDD scenarios for depth fallback pass (tight budget → downgrade before omit; depth-9 fragment exceeding budget → included at depth 4 if it fits) - [ ] `ACMSPipeline` integration test: assembled context under tight budget contains depth-downgraded fragments, not empty result - [ ] `docs/reference/acms.md` v1 Known Limitations entry for `DetailDepthResolver.resolve()` missing `budget` parameter is removed - [ ] All existing pipeline tests pass ## Subtasks - [ ] Implement `DetailDepthResolver.resolve(fragments, budget)` with depth fallback steps `[9, 4, 2, 0]` - [ ] When a fragment's `token_count` exceeds the per-fragment budget share, attempt to re-render at the next shallower depth step - [ ] Integrate with `UKO` detail level maps to produce correct shallower-depth renderings - [ ] Add BDD scenarios: "Given a tight budget, fragments are downgraded to shallower depths before being omitted" - [ ] Add BDD scenarios: "Given a fragment at depth 9 that exceeds budget, it is included at depth 4 if that fits" - [ ] Update `docs/reference/acms.md` v1 Known Limitations table to remove this entry once resolved ## Definition of Done - [ ] `DefaultDepthResolver.resolve(fragments, budget)` applies depth fallback steps `[9, 4, 2, 0]` - [ ] Fragments are downgraded to shallower depths before being omitted when budget is tight - [ ] BDD scenarios for depth fallback pass - [ ] `ACMSPipeline` integration test: assembled context under tight budget contains depth-downgraded fragments, not empty result - [ ] All existing pipeline tests pass - [ ] A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation - [ ] The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly - [ ] The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done --- **Automated by CleverAgents Bot** Agent: new-issue-creator Supervisor: UAT Test Pool | Agent: uat-test-pool-supervisor
HAL9000 added this to the v3.4.0 milestone 2026-04-14 12:49:07 +00:00
Author
Owner

Triage: Verified [AUTO-OWNR-1]

This is a valid bug in the ACMS pipeline. The DefaultDepthResolver accepts a budget parameter but silently ignores it, breaking the spec's graceful degradation guarantee (depth fallback steps [9, 4, 2, 0]). This is explicitly documented as a known limitation in docs/reference/acms.md.

Assigning to v3.4.0 (ACMS v1 + Context Scaling milestone) as this is core ACMS pipeline functionality. Priority is Medium — the system still functions but degrades less gracefully than specified under budget pressure.

MoSCoW: Should Have — the graceful degradation mechanism is important for large-project context assembly but the system remains functional without it.


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

✅ **Triage: Verified** [AUTO-OWNR-1] This is a valid bug in the ACMS pipeline. The `DefaultDepthResolver` accepts a `budget` parameter but silently ignores it, breaking the spec's graceful degradation guarantee (depth fallback steps [9, 4, 2, 0]). This is explicitly documented as a known limitation in `docs/reference/acms.md`. Assigning to **v3.4.0** (ACMS v1 + Context Scaling milestone) as this is core ACMS pipeline functionality. Priority is **Medium** — the system still functions but degrades less gracefully than specified under budget pressure. MoSCoW: **Should Have** — the graceful degradation mechanism is important for large-project context assembly but the system remains functional without it. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
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.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#9174
No description provided.