fix(decomposition): enforce plan.max-child-depth recursion limit to prevent unbounded hierarchy growth #11248

Merged
CoreRasurae merged 1 commit from fix/enforce-max-child-depth into master 2026-05-20 09:52:37 +00:00
Member

Closes #10269

Summary

Enforces the plan.max-child-depth configuration limit in DecompositionService._build_hierarchy() to prevent unbounded recursive plan decomposition.

Changes

DecompositionConfig (decomposition_models.py)

  • Added max_child_depth field (default: 5, matching plan.max-child-depth)
  • Added validation in __post_init__ (value must be >= 1)
  • Updated docstring with new attribute

DecompositionService (decomposition_service.py)

  • Added max_child_depth guard in _build_hierarchy()
  • Stops recursion when depth >= config.max_child_depth
  • Emits warning log when limit is reached: Decomposition reached max-child-depth limit (%d) at depth %d. Creating terminal node for %d files.
  • Both max_depth and max_child_depth are respected; the more restrictive one wins

BDD Tests

  • New feature file: features/decomposition_max_child_depth.feature
    • Decomposition stops when max_child_depth limit is reached
    • max_child_depth guard triggers before max_depth when more restrictive
    • max_depth can be more restrictive than max_child_depth
    • Default config value is correct (5)
    • Invalid max_child_depth value is rejected
  • Updated default config scenario to assert max_child_depth = 5

Verification

  • All 711 features pass (0 failures)
  • Lint and typecheck pass
  • All new code paths covered by tests
Closes #10269 ## Summary Enforces the `plan.max-child-depth` configuration limit in `DecompositionService._build_hierarchy()` to prevent unbounded recursive plan decomposition. ## Changes ### `DecompositionConfig` (decomposition_models.py) - Added `max_child_depth` field (default: 5, matching `plan.max-child-depth`) - Added validation in `__post_init__` (value must be >= 1) - Updated docstring with new attribute ### `DecompositionService` (decomposition_service.py) - Added `max_child_depth` guard in `_build_hierarchy()` - Stops recursion when `depth >= config.max_child_depth` - Emits warning log when limit is reached: `Decomposition reached max-child-depth limit (%d) at depth %d. Creating terminal node for %d files.` - Both `max_depth` and `max_child_depth` are respected; the more restrictive one wins ### BDD Tests - New feature file: `features/decomposition_max_child_depth.feature` - Decomposition stops when max_child_depth limit is reached - max_child_depth guard triggers before max_depth when more restrictive - max_depth can be more restrictive than max_child_depth - Default config value is correct (5) - Invalid max_child_depth value is rejected - Updated default config scenario to assert max_child_depth = 5 ## Verification - All 711 features pass (0 failures) - Lint and typecheck pass - All new code paths covered by tests
fix(decomposition): enforce plan.max-child-depth recursion limit to prevent unbounded hierarchy growth
Some checks failed
CI / push-validation (pull_request) Successful in 43s
CI / helm (pull_request) Successful in 52s
CI / build (pull_request) Successful in 1m15s
CI / lint (pull_request) Failing after 1m27s
CI / quality (pull_request) Successful in 2m2s
CI / typecheck (pull_request) Successful in 2m13s
CI / security (pull_request) Successful in 2m13s
CI / unit_tests (pull_request) Has started running
CI / integration_tests (pull_request) Has been cancelled
CI / coverage (pull_request) Has been cancelled
CI / docker (pull_request) Has been cancelled
CI / status-check (pull_request) Has been cancelled
16c6469d83
Add max_child_depth field to DecompositionConfig (default: 5, matching
plan.max-child-depth config) with validation in __post_init__. Update
_build_hierarchy() in DecompositionService to stop recursion and emit
a warning when the depth limit is reached.

BDD tests verify: max_child_depth guards trigger before max_depth
when more restrictive, warnings are logged, default config value is
correct, and invalid values are rejected.

ISSUES CLOSED: #10269
CoreRasurae added this to the v3.5.0 milestone 2026-05-19 20:12:13 +00:00
CoreRasurae force-pushed fix/enforce-max-child-depth from 16c6469d83
Some checks failed
CI / push-validation (pull_request) Successful in 43s
CI / helm (pull_request) Successful in 52s
CI / build (pull_request) Successful in 1m15s
CI / lint (pull_request) Failing after 1m27s
CI / quality (pull_request) Successful in 2m2s
CI / typecheck (pull_request) Successful in 2m13s
CI / security (pull_request) Successful in 2m13s
CI / unit_tests (pull_request) Has started running
CI / integration_tests (pull_request) Has been cancelled
CI / coverage (pull_request) Has been cancelled
CI / docker (pull_request) Has been cancelled
CI / status-check (pull_request) Has been cancelled
to 3a95701d9a
Some checks failed
CI / lint (pull_request) Successful in 1m19s
CI / quality (pull_request) Successful in 1m39s
CI / typecheck (pull_request) Successful in 1m43s
CI / security (pull_request) Successful in 1m56s
CI / build (pull_request) Successful in 33s
CI / helm (pull_request) Successful in 40s
CI / unit_tests (pull_request) Successful in 6m36s
CI / integration_tests (pull_request) Successful in 3m57s
CI / push-validation (pull_request) Successful in 19s
CI / docker (pull_request) Successful in 1m28s
CI / coverage (pull_request) Successful in 12m46s
CI / status-check (pull_request) Successful in 4s
CI / lint (push) Failing after 12s
CI / typecheck (push) Failing after 11s
CI / integration_tests (push) Failing after 7s
CI / unit_tests (push) Failing after 12s
CI / quality (push) Failing after 12s
CI / security (push) Failing after 13s
CI / coverage (push) Has been skipped
CI / docker (push) Has been skipped
CI / push-validation (push) Failing after 13s
CI / helm (push) Failing after 14s
CI / build (push) Failing after 15s
CI / status-check (push) Failing after 2s
CI / benchmark-regression (push) Failing after 34s
CI / e2e_tests (push) Successful in 1m1s
CI / benchmark-publish (push) Failing after 35m10s
2026-05-19 20:56:50 +00:00
Compare
brent.edwards left a comment

PR Review — #11248 APPROVED

PR: fix(decomposition): enforce plan.max-child-depth recursion limit to prevent unbounded hierarchy growth
Branch: fix/enforce-max-child-depth
Author: CoreRasurae (Luis Mendes)
Linked Issue: #10269
Milestone: v3.5.0
CI: 12/12 checks green (lint, quality, typecheck, security, build, helm, unit_tests, integration_tests, push-validation, docker, coverage, status-check)


Overall Assessment

All 10 checklist categories pass. The implementation is correct, well-tested, and fully addresses issue #10269. No blocking findings.


Checklist Breakdown

Category Status Notes
Correctness PASS reached_child_depth_limit = depth >= config.max_child_depth correctly guards _build_hierarchy(). All 5 acceptance criteria from #10269 are met. The more-restrictive-wins behavior (max_depth vs max_child_depth) is correctly implemented.
Specification Alignment PASS plan.max-child-depth (default 5) is enforced exactly as described in the spec: recursion stops at the limit, warning log is emitted, and terminal node is created.
Test Quality PASS 5 new BDD scenarios covering depth-limit enforcement, default value, guard priority (max_child_depth vs max_depth), inverse priority, and validation rejection. Existing large_project_decomposition.feature updated to assert max_child_depth=5. All 711 features pass with zero failures.
Type Safety PASS Zero # type: ignore comments. All function signatures annotated. Pydantic v2 ConfigDict(arbitrary_types_allowed=True) used appropriately.
Readability PASS Clear variable names (reached_child_depth_limit). Good docstring. Comment explains M6 4+ level context.
Performance PASS reached_child_depth_limit computed once per recursion, short-circuits via is_leaf - no inefficiencies.
Security PASS No secrets, no external inputs, no injection risks.
Code Style PASS SOLID, frozen dataclasses with __post_init__ validation. No magic numbers.
Documentation PASS DecompositionConfig docstring updated with max_child_depth attribute. No new public API surface.
Commit and PR Quality PASS Type/Bug label correct (matches issue #10269). Milestone v3.5.0 correct. PR body uses Closes #10269. Appropriately scoped (5 files, 139 additions).

Minor Observations (non-blocking, P3)

  • Unused import (P3:nit): decomposition_max_child_depth_steps.py imports when from behave but only uses then. The when import is dead code - suggest removing before merge.

  • Branch naming (P3:nit): The contributing guide specifies bugfix/mN- for bug fixes; this branch uses fix/. The repo's actual branch history uses fix/ universally, so this is consistent with established convention.


CI Gate Verification

All 5 required-for-merge CI jobs are green:

  • CI / lint (pull_request) - Successful in 1m19s
  • CI / typecheck (pull_request) - Successful in 1m43s
  • CI / unit_tests (pull_request) - Successful in 6m36s
  • CI / coverage (pull_request) - Successful in 12m46s
  • CI / security (pull_request) - Successful in 1m56s

Coverage job passed with >=97% threshold as confirmed by the CI / coverage (pull_request) success check.


Conclusion

This PR correctly enforces the plan.max-child-depth configuration limit in DecompositionService._build_hierarchy(), preventing unbounded recursive plan decomposition as described in issue #10269. All acceptance criteria pass, all tests pass, and no blocking issues were found. Approved for merge.


Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker

## PR Review — #11248 APPROVED **PR**: fix(decomposition): enforce plan.max-child-depth recursion limit to prevent unbounded hierarchy growth **Branch**: fix/enforce-max-child-depth **Author**: CoreRasurae (Luis Mendes) **Linked Issue**: #10269 **Milestone**: v3.5.0 **CI**: 12/12 checks green (lint, quality, typecheck, security, build, helm, unit_tests, integration_tests, push-validation, docker, coverage, status-check) --- ### Overall Assessment All 10 checklist categories pass. The implementation is correct, well-tested, and fully addresses issue #10269. No blocking findings. --- ### Checklist Breakdown | Category | Status | Notes | |---|---|---| | **Correctness** | PASS | `reached_child_depth_limit = depth >= config.max_child_depth` correctly guards `_build_hierarchy()`. All 5 acceptance criteria from #10269 are met. The more-restrictive-wins behavior (max_depth vs max_child_depth) is correctly implemented. | | **Specification Alignment** | PASS | `plan.max-child-depth` (default 5) is enforced exactly as described in the spec: recursion stops at the limit, warning log is emitted, and terminal node is created. | | **Test Quality** | PASS | 5 new BDD scenarios covering depth-limit enforcement, default value, guard priority (max_child_depth vs max_depth), inverse priority, and validation rejection. Existing `large_project_decomposition.feature` updated to assert `max_child_depth=5`. All 711 features pass with zero failures. | | **Type Safety** | PASS | Zero `# type: ignore` comments. All function signatures annotated. Pydantic v2 `ConfigDict(arbitrary_types_allowed=True)` used appropriately. | | **Readability** | PASS | Clear variable names (`reached_child_depth_limit`). Good docstring. Comment explains M6 4+ level context. | | **Performance** | PASS | `reached_child_depth_limit` computed once per recursion, short-circuits via `is_leaf` - no inefficiencies. | | **Security** | PASS | No secrets, no external inputs, no injection risks. | | **Code Style** | PASS | SOLID, frozen dataclasses with `__post_init__` validation. No magic numbers. | | **Documentation** | PASS | `DecompositionConfig` docstring updated with `max_child_depth` attribute. No new public API surface. | | **Commit and PR Quality** | PASS | Type/Bug label correct (matches issue #10269). Milestone v3.5.0 correct. PR body uses `Closes #10269`. Appropriately scoped (5 files, 139 additions). | --- ### Minor Observations (non-blocking, P3) - **Unused import (P3:nit)**: `decomposition_max_child_depth_steps.py` imports `when` from behave but only uses `then`. The `when` import is dead code - suggest removing before merge. - **Branch naming (P3:nit)**: The contributing guide specifies `bugfix/mN-` for bug fixes; this branch uses `fix/`. The repo's actual branch history uses `fix/` universally, so this is consistent with established convention. --- ### CI Gate Verification All 5 required-for-merge CI jobs are green: - `CI / lint (pull_request)` - Successful in 1m19s - `CI / typecheck (pull_request)` - Successful in 1m43s - `CI / unit_tests (pull_request)` - Successful in 6m36s - `CI / coverage (pull_request)` - Successful in 12m46s - `CI / security (pull_request)` - Successful in 1m56s Coverage job passed with >=97% threshold as confirmed by the `CI / coverage (pull_request)` success check. --- ### Conclusion This PR correctly enforces the `plan.max-child-depth` configuration limit in `DecompositionService._build_hierarchy()`, preventing unbounded recursive plan decomposition as described in issue #10269. All acceptance criteria pass, all tests pass, and no blocking issues were found. Approved for merge. --- Automated by CleverAgents Bot Supervisor: PR Review | Agent: pr-review-worker
CoreRasurae deleted branch fix/enforce-max-child-depth 2026-05-20 09:52:37 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
cleveragents/cleveragents-core!11248
No description provided.