UAT: NamespacedName.parse() in plan.py does not reject built-in provider namespaces for custom actions/plans #4886

Open
opened 2026-04-08 20:14:52 +00:00 by HAL9000 · 0 comments
Owner

Bug Report

Feature Area: Namespacing — Provider Namespace Protection
Tested by: UAT tester instance uat-namespacing

What Was Tested

Code analysis of src/cleveragents/domain/models/core/plan.py — the NamespacedName.parse() method used as the identity type for actions and plans.

Expected Behavior (from spec)

Per ADR-002 (Namespace System) and the spec's Namespace Rules section:

Built-in Provider Namespaces (openai/, anthropic/, google/, etc.)

  • Reserved for built-in LLM actors
  • Cannot be used for custom actors

The parse_namespaced_name() function in project.py correctly enforces this:

PROVIDER_NAMESPACES = frozenset({
    "openai", "anthropic", "google", "gemini", "deepseek",
    "mistral", "perplexity", "qwen", "amazon",
})

if namespace in PROVIDER_NAMESPACES:
    raise ValueError(
        f"Namespace '{namespace}' is reserved for built-in LLM actors "
        f"and cannot be used for projects"
    )

Actual Behavior

NamespacedName.parse() and NamespacedName(namespace=..., name=...) in plan.py have no check against provider namespaces. This means:

from cleveragents.domain.models.core.plan import NamespacedName

# Should raise ValueError but doesn't:
nn = NamespacedName.parse("openai/my-custom-action")
print(nn)  # "openai/my-custom-action" — accepted incorrectly

nn2 = NamespacedName(namespace="anthropic", name="my-plan")
print(nn2)  # "anthropic/my-plan" — accepted incorrectly

This allows users to register custom actions or plans under provider namespaces like openai/ or anthropic/, which would conflict with built-in LLM actor resolution and violate the spec's reservation rules.

Code Location

  • src/cleveragents/domain/models/core/plan.py, lines 201–274 (NamespacedName class)
  • Compare with correct implementation: src/cleveragents/domain/models/core/project.py, lines 50–63 (PROVIDER_NAMESPACES) and lines 145–149

Impact

  • A user could register openai/my-action as a custom action, which would create namespace collision with built-in LLM actor resolution
  • The _parse_actor_name() function in llm_actors.py splits on / to determine provider — a custom action named openai/my-action would be misinterpreted as an OpenAI model named my-action

Fix

Add PROVIDER_NAMESPACES check to NamespacedName.validate_namespace():

PROVIDER_NAMESPACES = frozenset({
    "openai", "anthropic", "google", "gemini", "deepseek",
    "mistral", "perplexity", "qwen", "amazon",
})

@field_validator("namespace")
@classmethod
def validate_namespace(cls, v: str) -> str:
    if not v:
        return "local"
    if not _NS_PATTERN.match(v):
        raise ValueError("Namespace must start with a letter...")
    if v.lower() in PROVIDER_NAMESPACES:
        raise ValueError(
            f"Namespace '{v}' is reserved for built-in LLM actors "
            "and cannot be used for custom entities"
        )
    return v.lower()

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

## Bug Report **Feature Area:** Namespacing — Provider Namespace Protection **Tested by:** UAT tester instance `uat-namespacing` ### What Was Tested Code analysis of `src/cleveragents/domain/models/core/plan.py` — the `NamespacedName.parse()` method used as the identity type for actions and plans. ### Expected Behavior (from spec) Per ADR-002 (Namespace System) and the spec's Namespace Rules section: > **Built-in Provider Namespaces** (`openai/`, `anthropic/`, `google/`, etc.) > - Reserved for built-in LLM actors > - **Cannot be used for custom actors** The `parse_namespaced_name()` function in `project.py` correctly enforces this: ```python PROVIDER_NAMESPACES = frozenset({ "openai", "anthropic", "google", "gemini", "deepseek", "mistral", "perplexity", "qwen", "amazon", }) if namespace in PROVIDER_NAMESPACES: raise ValueError( f"Namespace '{namespace}' is reserved for built-in LLM actors " f"and cannot be used for projects" ) ``` ### Actual Behavior `NamespacedName.parse()` and `NamespacedName(namespace=..., name=...)` in `plan.py` have **no check** against provider namespaces. This means: ```python from cleveragents.domain.models.core.plan import NamespacedName # Should raise ValueError but doesn't: nn = NamespacedName.parse("openai/my-custom-action") print(nn) # "openai/my-custom-action" — accepted incorrectly nn2 = NamespacedName(namespace="anthropic", name="my-plan") print(nn2) # "anthropic/my-plan" — accepted incorrectly ``` This allows users to register custom actions or plans under provider namespaces like `openai/` or `anthropic/`, which would conflict with built-in LLM actor resolution and violate the spec's reservation rules. ### Code Location - `src/cleveragents/domain/models/core/plan.py`, lines 201–274 (`NamespacedName` class) - Compare with correct implementation: `src/cleveragents/domain/models/core/project.py`, lines 50–63 (`PROVIDER_NAMESPACES`) and lines 145–149 ### Impact - A user could register `openai/my-action` as a custom action, which would create namespace collision with built-in LLM actor resolution - The `_parse_actor_name()` function in `llm_actors.py` splits on `/` to determine provider — a custom action named `openai/my-action` would be misinterpreted as an OpenAI model named `my-action` ### Fix Add `PROVIDER_NAMESPACES` check to `NamespacedName.validate_namespace()`: ```python PROVIDER_NAMESPACES = frozenset({ "openai", "anthropic", "google", "gemini", "deepseek", "mistral", "perplexity", "qwen", "amazon", }) @field_validator("namespace") @classmethod def validate_namespace(cls, v: str) -> str: if not v: return "local" if not _NS_PATTERN.match(v): raise ValueError("Namespace must start with a letter...") if v.lower() in PROVIDER_NAMESPACES: raise ValueError( f"Namespace '{v}' is reserved for built-in LLM actors " "and cannot be used for custom entities" ) return v.lower() ``` --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
HAL9000 added this to the v3.5.0 milestone 2026-04-09 03:02:25 +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#4886
No description provided.