BUG: [consistency] Conflicting lazy vs. eager command registration logic in cli/main.py undermines startup optimization #7069

Open
opened 2026-04-10 07:28:54 +00:00 by HAL9000 · 2 comments
Owner

Background

The CLI entry point src/cleveragents/cli/main.py contains contradictory command-registration
logic. The function _register_subcommands() is documented as a lazy registration helper
(docstring: "Register CLI subcommands lazily to reduce startup time"), yet it is called
eagerly on module import at line 236. A second, conditional call at line 789 then attempts
to re-apply the same lazy-registration guard that was already bypassed, making the optimisation
entirely ineffective and the comments actively misleading.

Current Behaviour

Three conflicting code sites exist simultaneously:

# Line 74-75 — docstring promises lazy registration
def _register_subcommands() -> None:
    """Register CLI subcommands lazily to reduce startup time."""

# Line 235-236 — immediately calls it eagerly on import
# Register subcommands eagerly on import so Typer recognizes nested commands
_register_subcommands()

# Lines 786-789 — conditional guard that is now dead code
if hasattr(app, "add_typer") and not (
    args and args[0] in _LIGHTWEIGHT_COMMANDS
):
    _register_subcommands()  # This may be redundant

Because _register_subcommands() sets _subcommands_registered = True on first call and
returns early on subsequent calls, the conditional call at line 789 is always a no-op. The
_LIGHTWEIGHT_COMMANDS fast-path optimisation (skipping heavy imports for version, help,
etc.) is therefore never exercised — every invocation pays the full import cost.

Expected Behaviour

The registration strategy must be internally consistent:

  • Option A — True lazy registration: Remove the eager call at line 236. Rely solely on the
    conditional call at line 789 (and ensure_cli_commands_registered() where needed). Update
    the docstring to reflect this.
  • Option B — Intentional eager registration: Remove the conditional call at line 789 and
    the _LIGHTWEIGHT_COMMANDS guard (now dead code). Update the docstring to say "eagerly".

Either option is acceptable; the current hybrid is not.

Impact

  • Performance: The stated startup-time optimisation for lightweight commands (version,
    help, --version) is silently disabled. Every CLI invocation imports all subcommand
    modules regardless of the command used.
  • Correctness risk: The contradictory comments create a maintenance hazard — future
    contributors may add logic that assumes lazy registration is active when it is not, leading
    to subtle ordering bugs or race conditions.
  • Code clarity: The comment on line 235 ("eagerly") directly contradicts the docstring on
    line 74 ("lazily"), violating the project's documentation standards.

Location

Site File Lines
Docstring (lazy claim) src/cleveragents/cli/main.py 74–75
Eager call on import src/cleveragents/cli/main.py 235–236
Conditional (dead) call src/cleveragents/cli/main.py 786–789

Metadata

  • Branch: fix/cli-command-registration-consistency
  • Commit Message: fix(cli): resolve contradictory lazy/eager subcommand registration in main.py
  • Milestone: (none — backlog)
  • Parent Epic: (none identified — see orphan note below)

Subtasks

  • Decide on registration strategy (lazy vs. eager) and document the decision
  • Remove the conflicting call site (either line 236 or lines 786–789)
  • Update _register_subcommands() docstring to accurately reflect chosen strategy
  • Update inline comment at line 235 to match chosen strategy
  • Add/update BDD scenario covering lightweight-command startup path
  • Verify _LIGHTWEIGHT_COMMANDS fast-path is exercised (or remove it if eager strategy chosen)
  • Run full nox suite; confirm coverage ≥ 97 %

Definition of Done

  • Exactly one registration strategy is implemented with no contradictory call sites
  • All inline comments and docstrings accurately describe the implemented behaviour
  • _LIGHTWEIGHT_COMMANDS fast-path is either functional (lazy) or removed (eager)
  • BDD scenario added or updated to cover the chosen registration path
  • All nox stages pass
  • Coverage ≥ 97%

Backlog note: This issue was discovered during autonomous operation
on milestone v3.2.0. It does not block milestone completion and has been
placed in the backlog for human review and future milestone assignment.


Automated by CleverAgents Bot
Supervisor: Acting on behalf of: UAT Testing | Agent: new-issue-creator

## Background The CLI entry point `src/cleveragents/cli/main.py` contains contradictory command-registration logic. The function `_register_subcommands()` is documented as a *lazy* registration helper (docstring: "Register CLI subcommands lazily to reduce startup time"), yet it is called **eagerly on module import** at line 236. A second, conditional call at line 789 then attempts to re-apply the same lazy-registration guard that was already bypassed, making the optimisation entirely ineffective and the comments actively misleading. ## Current Behaviour Three conflicting code sites exist simultaneously: ```python # Line 74-75 — docstring promises lazy registration def _register_subcommands() -> None: """Register CLI subcommands lazily to reduce startup time.""" # Line 235-236 — immediately calls it eagerly on import # Register subcommands eagerly on import so Typer recognizes nested commands _register_subcommands() # Lines 786-789 — conditional guard that is now dead code if hasattr(app, "add_typer") and not ( args and args[0] in _LIGHTWEIGHT_COMMANDS ): _register_subcommands() # This may be redundant ``` Because `_register_subcommands()` sets `_subcommands_registered = True` on first call and returns early on subsequent calls, the conditional call at line 789 is always a no-op. The `_LIGHTWEIGHT_COMMANDS` fast-path optimisation (skipping heavy imports for `version`, `help`, etc.) is therefore never exercised — every invocation pays the full import cost. ## Expected Behaviour The registration strategy must be internally consistent: - **Option A — True lazy registration**: Remove the eager call at line 236. Rely solely on the conditional call at line 789 (and `ensure_cli_commands_registered()` where needed). Update the docstring to reflect this. - **Option B — Intentional eager registration**: Remove the conditional call at line 789 and the `_LIGHTWEIGHT_COMMANDS` guard (now dead code). Update the docstring to say "eagerly". Either option is acceptable; the current hybrid is not. ## Impact - **Performance**: The stated startup-time optimisation for lightweight commands (`version`, `help`, `--version`) is silently disabled. Every CLI invocation imports all subcommand modules regardless of the command used. - **Correctness risk**: The contradictory comments create a maintenance hazard — future contributors may add logic that assumes lazy registration is active when it is not, leading to subtle ordering bugs or race conditions. - **Code clarity**: The comment on line 235 ("eagerly") directly contradicts the docstring on line 74 ("lazily"), violating the project's documentation standards. ## Location | Site | File | Lines | |------|------|-------| | Docstring (lazy claim) | `src/cleveragents/cli/main.py` | 74–75 | | Eager call on import | `src/cleveragents/cli/main.py` | 235–236 | | Conditional (dead) call | `src/cleveragents/cli/main.py` | 786–789 | ## Metadata - **Branch**: `fix/cli-command-registration-consistency` - **Commit Message**: `fix(cli): resolve contradictory lazy/eager subcommand registration in main.py` - **Milestone**: *(none — backlog)* - **Parent Epic**: *(none identified — see orphan note below)* ## Subtasks - [ ] Decide on registration strategy (lazy vs. eager) and document the decision - [ ] Remove the conflicting call site (either line 236 or lines 786–789) - [ ] Update `_register_subcommands()` docstring to accurately reflect chosen strategy - [ ] Update inline comment at line 235 to match chosen strategy - [ ] Add/update BDD scenario covering lightweight-command startup path - [ ] Verify `_LIGHTWEIGHT_COMMANDS` fast-path is exercised (or remove it if eager strategy chosen) - [ ] Run full nox suite; confirm coverage ≥ 97 % ## Definition of Done - [ ] Exactly one registration strategy is implemented with no contradictory call sites - [ ] All inline comments and docstrings accurately describe the implemented behaviour - [ ] `_LIGHTWEIGHT_COMMANDS` fast-path is either functional (lazy) or removed (eager) - [ ] BDD scenario added or updated to cover the chosen registration path - [ ] All nox stages pass - [ ] Coverage ≥ 97% > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.2.0. It does not block milestone completion and has been > placed in the backlog for human review and future milestone assignment. --- **Automated by CleverAgents Bot** Supervisor: Acting on behalf of: UAT Testing | Agent: new-issue-creator
Author
Owner

⚠️ Orphan Issue — Manual Epic Linking Required

No open CLI-related Epic was found at the time this issue was created. This issue must be linked to a parent Epic before work begins.

Suggested parent candidates:

  • A CLI refactoring or code-quality Epic (none currently open)
  • Issue #6989 ([AUTO-GUARD] File too long: src/cleveragents/cli/main.py) is a related task covering the same file — a maintainer may wish to create a CLI clean-up Epic that parents both issues

Action required: A maintainer should either:

  1. Link this issue to an existing Epic via Forgejo's dependency system (this issue blocks the parent Epic), or
  2. Create a new CLI quality/refactoring Epic and link this issue as a child

Automated by CleverAgents Bot
Supervisor: Acting on behalf of: UAT Testing | Agent: new-issue-creator

⚠️ **Orphan Issue — Manual Epic Linking Required** No open CLI-related Epic was found at the time this issue was created. This issue must be linked to a parent Epic before work begins. **Suggested parent candidates:** - A CLI refactoring or code-quality Epic (none currently open) - Issue [#6989](https://git.cleverthis.com/cleveragents/cleveragents-core/issues/6989) (`[AUTO-GUARD] File too long: src/cleveragents/cli/main.py`) is a related task covering the same file — a maintainer may wish to create a CLI clean-up Epic that parents both issues **Action required:** A maintainer should either: 1. Link this issue to an existing Epic via Forgejo's dependency system (this issue **blocks** the parent Epic), or 2. Create a new CLI quality/refactoring Epic and link this issue as a child --- **Automated by CleverAgents Bot** Supervisor: Acting on behalf of: UAT Testing | Agent: new-issue-creator
Author
Owner

Verified — Consistency bug: conflicting lazy vs. eager command registration in cli/main.py. MoSCoW: Should-have. Priority: Medium.


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

✅ **Verified** — Consistency bug: conflicting lazy vs. eager command registration in cli/main.py. MoSCoW: Should-have. Priority: Medium. --- **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#7069
No description provided.