From 8e7e3cdfc2318568b6df5094f74fb7f29bfcca79 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Tue, 14 Apr 2026 09:17:41 +0000 Subject: [PATCH 1/6] fix(schema): update actor, skill, and tool name validators to accept [[server:]namespace/]name format - Updated ActorConfigSchema.validate_name to accept optional server prefix - Updated NAMESPACED_NAME_RE in skills/schema.py to support server-qualified names - Updated _TOOL_NAME_PATTERN in tool.py to support server-qualified names - All validators now accept both 'namespace/name' and 'server:namespace/name' formats - Maintains backward compatibility with existing non-server-qualified names - Fixes spec compliance issue where server-qualified names were incorrectly rejected ISSUES CLOSED: #9074 --- src/cleveragents/actor/schema.py | 44 ++++++++++++++++----- src/cleveragents/domain/models/core/tool.py | 2 +- src/cleveragents/skills/schema.py | 3 +- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/cleveragents/actor/schema.py b/src/cleveragents/actor/schema.py index 81789c6d8..49a2ac75d 100644 --- a/src/cleveragents/actor/schema.py +++ b/src/cleveragents/actor/schema.py @@ -810,21 +810,45 @@ class ActorConfigSchema(BaseModel): @field_validator("name") @classmethod def validate_name(cls, v: str) -> str: - """Ensure actor name follows namespace/name format.""" + """Ensure actor name follows [[server:]namespace/]name format. + + Supports: + - namespace/name (e.g., 'local/my-actor') + - server:namespace/name (e.g., 'dev:freemo/custom-analysis') + """ if "/" not in v: msg = f"Actor name must be namespaced (namespace/name): {v}" raise ValueError(msg) - # Check for exactly one slash - parts = v.split("/") - if len(parts) != 2: - msg = ( - f"Actor name must be namespaced with exactly one slash " - f"(namespace/name): {v}" - ) - raise ValueError(msg) + # Split by colon first to extract optional server prefix + if ":" in v: + server_part, rest = v.split(":", 1) + if not server_part: + msg = f"Actor name has empty server prefix: {v}" + raise ValueError(msg) + # rest should be namespace/name + if "/" not in rest: + msg = f"Actor name must have namespace/name after server prefix: {v}" + raise ValueError(msg) + parts = rest.split("/") + if len(parts) != 2: + msg = ( + f"Actor name must have exactly one slash in namespace/name " + f"(after optional server prefix): {v}" + ) + raise ValueError(msg) + namespace, name = parts + else: + # No server prefix, just namespace/name + parts = v.split("/") + if len(parts) != 2: + msg = ( + f"Actor name must be namespaced with exactly one slash " + f"(namespace/name): {v}" + ) + raise ValueError(msg) + namespace, name = parts - namespace, name = parts if not namespace or not name: msg = ( f"Actor name must be namespaced with non-empty namespace and name: {v}" diff --git a/src/cleveragents/domain/models/core/tool.py b/src/cleveragents/domain/models/core/tool.py index 0ff79b3a6..84e33e58d 100644 --- a/src/cleveragents/domain/models/core/tool.py +++ b/src/cleveragents/domain/models/core/tool.py @@ -77,7 +77,7 @@ from cleveragents.domain.models.core.execution_environment_preference import ( # Regex patterns # --------------------------------------------------------------------------- -_TOOL_NAME_PATTERN = re.compile(r"^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$") +_TOOL_NAME_PATTERN = re.compile(r"^(?:[a-zA-Z0-9_-]+:)?[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$") # --------------------------------------------------------------------------- # Enums diff --git a/src/cleveragents/skills/schema.py b/src/cleveragents/skills/schema.py index 25cfa722c..47e814d54 100644 --- a/src/cleveragents/skills/schema.py +++ b/src/cleveragents/skills/schema.py @@ -38,7 +38,8 @@ logger = logging.getLogger(__name__) # ──────────────────────────────────────────────────────────── #: Pattern for ``/`` with hyphens, underscores, lowercase alphanum. -NAMESPACED_NAME_RE = re.compile(r"^[a-z0-9][a-z0-9_-]*/[a-z0-9][a-z0-9_-]*$") +#: Supports optional server prefix: ``[server:]namespace/name`` +NAMESPACED_NAME_RE = re.compile(r"^(?:[a-z0-9][a-z0-9_-]*:)?[a-z0-9][a-z0-9_-]*/[a-z0-9][a-z0-9_-]*$") #: Pattern for ``${VAR}`` environment variable references. _ENV_VAR_RE = re.compile(r"\$\{([A-Za-z_][A-Za-z0-9_]*)\}") -- 2.52.0 From 86525a4ba4571ee5fb1deb06c943a76e4b2dcf18 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Tue, 14 Apr 2026 12:48:47 +0000 Subject: [PATCH 2/6] fix(schema): add BDD scenarios and fix lint for server-qualified name validators Add BDD test scenarios for server-qualified name acceptance in: - features/actor_schema.feature: Accept/reject scenarios for server:namespace/name format - features/skill_schema.feature: Accept scenarios for server:namespace/name format - features/consolidated_tool.feature: Accept scenarios for server:namespace/name format Also fix lint issues in the previous commit: - Remove trailing whitespace from actor/schema.py docstring - Split long NAMESPACED_NAME_RE line in skills/schema.py ISSUES CLOSED: #9074 --- features/actor_schema.feature | 16 ++++++++++++++++ features/consolidated_tool.feature | 10 ++++++++++ features/skill_schema.feature | 10 ++++++++++ src/cleveragents/actor/schema.py | 2 +- src/cleveragents/skills/schema.py | 4 +++- 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/features/actor_schema.feature b/features/actor_schema.feature index 0d833efb0..d8afd103d 100644 --- a/features/actor_schema.feature +++ b/features/actor_schema.feature @@ -197,6 +197,22 @@ Feature: Actor YAML schema validation Then the actor schema validation should fail And the validation error should contain "namespaced" + Scenario: Accept actor with server-qualified name + Given an actor YAML string with name "dev:freemo/custom-analysis" + When I validate the actor schema + Then the actor schema validation should succeed + + Scenario: Accept actor with server-qualified name using cleverthis server + Given an actor YAML string with name "cleverthis:local/my-actor" + When I validate the actor schema + Then the actor schema validation should succeed + + Scenario: Reject actor with server-qualified name but multiple slashes + Given an actor YAML string with name "dev:namespace/sub/actor" + When I validate the actor schema + Then the actor schema validation should fail + And the validation error should contain "namespaced" + # ──────────────────────────────────────────────────────────── # Invalid LLM Actor scenarios # ──────────────────────────────────────────────────────────── diff --git a/features/consolidated_tool.feature b/features/consolidated_tool.feature index b602a6087..6236ffc74 100644 --- a/features/consolidated_tool.feature +++ b/features/consolidated_tool.feature @@ -153,6 +153,16 @@ Feature: Consolidated Tool And the tool model namespace should be "my-ns" And the tool model short name should be "my_tool" + + Scenario: Tool name accepts server-qualified format + When I create a tool with name "dev:freemo/custom-analysis" and source "builtin" + Then the tool model should be created + + + Scenario: Tool name accepts server-qualified format with cleverthis server + When I create a tool with name "cleverthis:local/run-migrations" and source "builtin" + Then the tool model should be created + # ---- Source-conditional field requirements ---- diff --git a/features/skill_schema.feature b/features/skill_schema.feature index 144dcf8c2..020db96de 100644 --- a/features/skill_schema.feature +++ b/features/skill_schema.feature @@ -131,6 +131,16 @@ Feature: Skill YAML schema validation Then the skill schema validation should fail And the skill schema error should mention "namespace/name" + Scenario: Accept skill with server-qualified name + Given a skill YAML string with name "dev:freemo/custom-skill" + When I validate the skill schema + Then the skill schema validation should succeed + + Scenario: Accept skill with server-qualified name using cleverthis server + Given a skill YAML string with name "cleverthis:local/my-skill" + When I validate the skill schema + Then the skill schema validation should succeed + Scenario: Invalid namespaced name with special characters Given a skill YAML string with name "local/bad name!!" When I validate the skill schema expecting failure diff --git a/src/cleveragents/actor/schema.py b/src/cleveragents/actor/schema.py index 49a2ac75d..33cc6846b 100644 --- a/src/cleveragents/actor/schema.py +++ b/src/cleveragents/actor/schema.py @@ -811,7 +811,7 @@ class ActorConfigSchema(BaseModel): @classmethod def validate_name(cls, v: str) -> str: """Ensure actor name follows [[server:]namespace/]name format. - + Supports: - namespace/name (e.g., 'local/my-actor') - server:namespace/name (e.g., 'dev:freemo/custom-analysis') diff --git a/src/cleveragents/skills/schema.py b/src/cleveragents/skills/schema.py index 47e814d54..7b851b040 100644 --- a/src/cleveragents/skills/schema.py +++ b/src/cleveragents/skills/schema.py @@ -39,7 +39,9 @@ logger = logging.getLogger(__name__) #: Pattern for ``/`` with hyphens, underscores, lowercase alphanum. #: Supports optional server prefix: ``[server:]namespace/name`` -NAMESPACED_NAME_RE = re.compile(r"^(?:[a-z0-9][a-z0-9_-]*:)?[a-z0-9][a-z0-9_-]*/[a-z0-9][a-z0-9_-]*$") +NAMESPACED_NAME_RE = re.compile( + r"^(?:[a-z0-9][a-z0-9_-]*:)?[a-z0-9][a-z0-9_-]*/[a-z0-9][a-z0-9_-]*$" +) #: Pattern for ``${VAR}`` environment variable references. _ENV_VAR_RE = re.compile(r"\$\{([A-Za-z_][A-Za-z0-9_]*)\}") -- 2.52.0 From ed1dc481285eed2b0f63f11ece63d15c44bbb979 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Thu, 23 Apr 2026 02:03:13 +0000 Subject: [PATCH 3/6] fix(schema): fix actor validator error message and add changelog for server-qualified name support Fixed the error message in ActorConfigSchema.validate_name for the server-qualified name with multiple slashes case to include the word "namespaced", matching the BDD test assertion expectation. Added CHANGELOG.md entry documenting the server-qualified name format fix (#9074). ISSUES CLOSED: #9074 --- CHANGELOG.md | 8 ++++++++ src/cleveragents/actor/schema.py | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ac313e96..bc61e3e2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,14 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - **Bug Hunt Pool Supervisor Non-Blocking Tracking**: Updated `bug-hunt-pool-supervisor` to make the automation tracking step non-blocking. The `automation-tracking-manager` call in step 5 is now best-effort — if it does not complete within a reasonable time or fails, the supervisor skips it and continues to the next cycle. Added explicit rule 9 clarifying that tracking must never block the main loop. Core functionality (module scanning and worker dispatch) takes priority over status reporting. +- **Name Validator Server-Qualified Format** (#9074): Updated actor, skill, and tool name + validators to accept the spec-required `[[server:]namespace/]name` format. Previously, + server-qualified names like `dev:freemo/custom-analysis` were incorrectly rejected. + Added BDD scenarios for server-qualified name acceptance and rejection. All three + validators (`ActorConfigSchema.validate_name`, `NAMESPACED_NAME_RE`, + `_TOOL_NAME_PATTERN`) now correctly support optional server prefixes while maintaining + backward compatibility with existing `namespace/name` names. + - **Automation Profile Silent Fallback** (#8232): `_resolve_profile_for_plan` in `PlanLifecycleService` now raises a clear `ValidationError` when a plan's automation profile name is not a known built-in profile, instead of silently diff --git a/src/cleveragents/actor/schema.py b/src/cleveragents/actor/schema.py index 33cc6846b..865a79c86 100644 --- a/src/cleveragents/actor/schema.py +++ b/src/cleveragents/actor/schema.py @@ -833,8 +833,8 @@ class ActorConfigSchema(BaseModel): parts = rest.split("/") if len(parts) != 2: msg = ( - f"Actor name must have exactly one slash in namespace/name " - f"(after optional server prefix): {v}" + f"Actor name must be namespaced with exactly one slash " + f"(namespace/name after optional server prefix): {v}" ) raise ValueError(msg) namespace, name = parts -- 2.52.0 From 8738d6b9211d238f86aa01eee8a90d5bec53da09 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Thu, 23 Apr 2026 04:21:45 +0000 Subject: [PATCH 4/6] fix(schema): add provider field to actor name test template for master compatibility The merge with master introduced a new 'provider' field requirement for LLM and GRAPH actors. Updated the step_given_actor_with_name test template to include 'provider: openai' so server-qualified name acceptance scenarios pass with the new validation rule. ISSUES CLOSED: #9074 --- features/steps/actor_schema_steps.py | 1 + 1 file changed, 1 insertion(+) diff --git a/features/steps/actor_schema_steps.py b/features/steps/actor_schema_steps.py index cd1995425..44df790ce 100644 --- a/features/steps/actor_schema_steps.py +++ b/features/steps/actor_schema_steps.py @@ -404,6 +404,7 @@ def step_given_actor_with_name(context: Context, name: str) -> None: name: {name} type: llm description: Test actor +provider: openai model: gpt-4 """ -- 2.52.0 From 6d0622c6982b3e2bf755c224b67038bace5f81ad Mon Sep 17 00:00:00 2001 From: HAL9000 Date: Thu, 23 Apr 2026 06:16:51 +0000 Subject: [PATCH 5/6] test(schema): add BDD scenarios for uncovered server-qualified name validator branches Add rejection scenarios for actor names with empty server prefix and server prefix without namespace slash to cover all error branches in the updated validate_name method. Add skill rejection scenario for server-qualified names with multiple slashes for parity with actor tests. ISSUES CLOSED: #9074 --- features/actor_schema.feature | 12 ++++++++++++ features/skill_schema.feature | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/features/actor_schema.feature b/features/actor_schema.feature index d8afd103d..59b1ab6ac 100644 --- a/features/actor_schema.feature +++ b/features/actor_schema.feature @@ -213,6 +213,18 @@ Feature: Actor YAML schema validation Then the actor schema validation should fail And the validation error should contain "namespaced" + Scenario: Reject actor with empty server prefix + Given an actor YAML string with name ":namespace/name" + When I validate the actor schema + Then the actor schema validation should fail + And the validation error should contain "empty server prefix" + + Scenario: Reject actor with server prefix but no namespace slash + Given an actor YAML string with name "dev/server:name" + When I validate the actor schema + Then the actor schema validation should fail + And the validation error should contain "namespace/name after server prefix" + # ──────────────────────────────────────────────────────────── # Invalid LLM Actor scenarios # ──────────────────────────────────────────────────────────── diff --git a/features/skill_schema.feature b/features/skill_schema.feature index 020db96de..e09d9d4f0 100644 --- a/features/skill_schema.feature +++ b/features/skill_schema.feature @@ -141,6 +141,12 @@ Feature: Skill YAML schema validation When I validate the skill schema Then the skill schema validation should succeed + Scenario: Reject skill with server-qualified name but multiple slashes + Given a skill YAML string with name "dev:namespace/sub/skill" + When I validate the skill schema expecting failure + Then the skill schema validation should fail + And the skill schema error should mention "namespace/name" + Scenario: Invalid namespaced name with special characters Given a skill YAML string with name "local/bad name!!" When I validate the skill schema expecting failure -- 2.52.0 From 0e130e39c382438451ceb65354633287bfa1ca47 Mon Sep 17 00:00:00 2001 From: HAL9000 Date: Thu, 23 Apr 2026 07:22:36 +0000 Subject: [PATCH 6/6] chore(ci): trigger CI re-run for transient e2e_tests failure The e2e_tests CI job failed transiently on the previous push. All other CI gates pass. This empty commit triggers a new CI run. ISSUES CLOSED: #9074 -- 2.52.0