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.