UAT: Two separate, inconsistent namespace implementations (NamespacedName in plan.py vs ParsedName/parse_namespaced_name in project.py) — spec requires a single universal naming scheme #4427

Open
opened 2026-04-08 12:32:28 +00:00 by HAL9000 · 0 comments
Owner

Metadata

  • Branch: refactor/unify-namespace-implementations
  • Commit Message: refactor(domain): unify NamespacedName and ParsedName into single shared namespace implementation
  • Milestone: Backlog
  • Parent Epic: #399

Bug Report

What was tested: Namespace name parsing and validation consistency across the codebase against ADR-002.

Expected behavior (from spec, ADR-002):

A single naming convention applies uniformly to all entity types, reducing cognitive overhead.
All named entities in CleverAgents use a universal namespace-qualified name format: [[server:]namespace/]name.

Actual behavior:
There are TWO separate, inconsistent implementations of the namespace concept:

Implementation 1: NamespacedName in plan.py (used by plans and actions)

  • validate_namespace(): uses all(c.isalnum() or c == "-" for c in v) — allows names starting with digits
  • validate_name(): uses v.replace("-", "").replace("_", "").isalnum() — allows names starting with digits
  • Does NOT check RESERVED_NAMESPACES (system, internal, admin, root)
  • Does NOT check PROVIDER_NAMESPACES (openai, anthropic, google, etc.)
  • Silently converts empty namespace to "local" instead of raising an error
  • Forces names to lowercase via return v.lower()
  • parse() method: simple split-based parsing, no validation of reserved/provider namespaces

Implementation 2: ParsedName + parse_namespaced_name() in project.py (used by projects)

  • Uses regex _SERVER_NS_NAME_RE = re.compile(r"^(?:(?P<server>[a-zA-Z][a-zA-Z0-9_-]*):)?(?P<namespace>[a-zA-Z][a-zA-Z0-9_-]*)/(?P<name>[a-zA-Z][a-zA-Z0-9_-]*)$") — correctly requires letter-start
  • Checks RESERVED_NAMESPACES
  • Checks PROVIDER_NAMESPACES
  • Does NOT force names to lowercase (preserves case)
  • Raises ValueError for invalid inputs

Validation Rule Differences

Rule NamespacedName (plan.py) ParsedName (project.py)
Must start with letter No Yes
Reserved namespaces blocked No Yes
Provider namespaces blocked No Yes
Forces lowercase Yes No
Empty namespace handling Silent → "local" Raises ValueError

Impact:

  • Plans/actions can be created with namespaces that projects cannot use (e.g., system/, openai/, 123abc/)
  • Projects can be created with mixed-case names that plans/actions would silently lowercase
  • The "universal naming scheme" promise of ADR-002 is broken — different entity types have different namespace rules
  • This creates confusion for users and makes cross-entity namespace references unreliable

Code locations:

  • src/cleveragents/domain/models/core/plan.py lines 201-274 (NamespacedName)
  • src/cleveragents/domain/models/core/project.py lines 27-165 (ParsedName, parse_namespaced_name)

Fix: Consolidate into a single shared namespace implementation. Options:

  1. Move NamespacedName to a shared module (e.g., src/cleveragents/domain/models/core/namespace.py) with the stricter validation from project.py
  2. Have project.py import and use NamespacedName from plan.py (after fixing its validation)
  3. Create a new NamespacedIdentifier class in a shared module that both plan.py and project.py use

The unified implementation should:

  • Require names to start with a letter (regex-based)
  • Check RESERVED_NAMESPACES
  • Check PROVIDER_NAMESPACES
  • Preserve case (don't force lowercase)
  • Raise ValueError for invalid inputs

Related issues:

  • #4419: NamespacedName doesn't check provider namespaces
  • #4423: NamespacedName doesn't check reserved namespaces
  • #2145/#2147: NamespacedName allows names starting with digits

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

## Metadata - **Branch**: `refactor/unify-namespace-implementations` - **Commit Message**: `refactor(domain): unify NamespacedName and ParsedName into single shared namespace implementation` - **Milestone**: Backlog - **Parent Epic**: #399 ## Bug Report **What was tested:** Namespace name parsing and validation consistency across the codebase against ADR-002. **Expected behavior (from spec, ADR-002):** > A single naming convention applies uniformly to all entity types, reducing cognitive overhead. > All named entities in CleverAgents use a universal **namespace-qualified name** format: `[[server:]namespace/]name`. **Actual behavior:** There are TWO separate, inconsistent implementations of the namespace concept: ### Implementation 1: `NamespacedName` in `plan.py` (used by plans and actions) - `validate_namespace()`: uses `all(c.isalnum() or c == "-" for c in v)` — allows names starting with digits - `validate_name()`: uses `v.replace("-", "").replace("_", "").isalnum()` — allows names starting with digits - Does NOT check `RESERVED_NAMESPACES` (`system`, `internal`, `admin`, `root`) - Does NOT check `PROVIDER_NAMESPACES` (`openai`, `anthropic`, `google`, etc.) - Silently converts empty namespace to `"local"` instead of raising an error - Forces names to lowercase via `return v.lower()` - `parse()` method: simple split-based parsing, no validation of reserved/provider namespaces ### Implementation 2: `ParsedName` + `parse_namespaced_name()` in `project.py` (used by projects) - Uses regex `_SERVER_NS_NAME_RE = re.compile(r"^(?:(?P<server>[a-zA-Z][a-zA-Z0-9_-]*):)?(?P<namespace>[a-zA-Z][a-zA-Z0-9_-]*)/(?P<name>[a-zA-Z][a-zA-Z0-9_-]*)$")` — correctly requires letter-start - Checks `RESERVED_NAMESPACES` ✓ - Checks `PROVIDER_NAMESPACES` ✓ - Does NOT force names to lowercase (preserves case) - Raises `ValueError` for invalid inputs ### Validation Rule Differences | Rule | `NamespacedName` (plan.py) | `ParsedName` (project.py) | |------|---------------------------|--------------------------| | Must start with letter | ❌ No | ✅ Yes | | Reserved namespaces blocked | ❌ No | ✅ Yes | | Provider namespaces blocked | ❌ No | ✅ Yes | | Forces lowercase | ✅ Yes | ❌ No | | Empty namespace handling | Silent → "local" | Raises ValueError | **Impact:** - Plans/actions can be created with namespaces that projects cannot use (e.g., `system/`, `openai/`, `123abc/`) - Projects can be created with mixed-case names that plans/actions would silently lowercase - The "universal naming scheme" promise of ADR-002 is broken — different entity types have different namespace rules - This creates confusion for users and makes cross-entity namespace references unreliable **Code locations:** - `src/cleveragents/domain/models/core/plan.py` lines 201-274 (`NamespacedName`) - `src/cleveragents/domain/models/core/project.py` lines 27-165 (`ParsedName`, `parse_namespaced_name`) **Fix:** Consolidate into a single shared namespace implementation. Options: 1. Move `NamespacedName` to a shared module (e.g., `src/cleveragents/domain/models/core/namespace.py`) with the stricter validation from `project.py` 2. Have `project.py` import and use `NamespacedName` from `plan.py` (after fixing its validation) 3. Create a new `NamespacedIdentifier` class in a shared module that both `plan.py` and `project.py` use The unified implementation should: - Require names to start with a letter (regex-based) - Check `RESERVED_NAMESPACES` - Check `PROVIDER_NAMESPACES` - Preserve case (don't force lowercase) - Raise `ValueError` for invalid inputs **Related issues:** - #4419: `NamespacedName` doesn't check provider namespaces - #4423: `NamespacedName` doesn't check reserved namespaces - #2145/#2147: `NamespacedName` allows names starting with digits --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
HAL9000 added this to the v3.5.0 milestone 2026-04-08 17:42:44 +00:00
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#4427
No description provided.