From 7b0533b34d1a6a3d54fc850801c0bb9d82c55feb Mon Sep 17 00:00:00 2001 From: Jeffrey Phillips Freeman Date: Sun, 5 Apr 2026 07:43:56 +0000 Subject: [PATCH] fix(skills): add lowercase-only namespace/name pattern validation to SkillConfigSchema.name field Enforce lowercase-only namespace/name pattern in both SkillConfigSchema and ActionConfigSchema by updating NAMESPACED_NAME_RE from the permissive [a-zA-Z0-9] pattern to the strict [a-z0-9] pattern. This fixes a UAT-identified bug where uppercase letters were incorrectly accepted in the namespace/name fields of skill and action configurations, violating the spec's naming convention (^[a-z0-9_-]+/[a-z0-9_-]+$). Changes: - src/cleveragents/skills/schema.py: Update NAMESPACED_NAME_RE to reject uppercase letters in namespace and name parts - src/cleveragents/action/schema.py: Apply the same lowercase-only fix - features/skill_schema.feature: Add BDD scenarios for uppercase namespace, uppercase name part, fully uppercase name, uppercase tool ref, and uppercase include name rejection - features/consolidated_action.feature: Add BDD scenarios for uppercase namespace, uppercase name part, and fully uppercase name rejection ISSUES CLOSED: #3029 --- features/consolidated_action.feature | 21 +++++++++++++++++++ features/skill_schema.feature | 30 ++++++++++++++++++++++++++++ src/cleveragents/action/schema.py | 6 ++---- src/cleveragents/skills/schema.py | 6 ++---- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/features/consolidated_action.feature b/features/consolidated_action.feature index fdb5ddb8d..ead59b0ea 100644 --- a/features/consolidated_action.feature +++ b/features/consolidated_action.feature @@ -700,6 +700,27 @@ Feature: Consolidated Action And the action schema error should mention "namespace/name" + Scenario: Uppercase namespace is rejected by ActionConfigSchema + Given an action YAML string with name "MyOrg/my-action" + When I validate the action schema expecting failure + Then the action schema validation should fail + And the action schema error should mention "namespace/name" + + + Scenario: Uppercase name part is rejected by ActionConfigSchema + Given an action YAML string with name "myorg/MyAction" + When I validate the action schema expecting failure + Then the action schema validation should fail + And the action schema error should mention "namespace/name" + + + Scenario: Fully uppercase namespaced name is rejected by ActionConfigSchema + Given an action YAML string with name "MyOrg/MyAction" + When I validate the action schema expecting failure + Then the action schema validation should fail + And the action schema error should mention "namespace/name" + + Scenario: Invalid argument type Given an action YAML string with an argument of type "array" When I validate the action schema expecting failure diff --git a/features/skill_schema.feature b/features/skill_schema.feature index 5704307c6..144dcf8c2 100644 --- a/features/skill_schema.feature +++ b/features/skill_schema.feature @@ -137,6 +137,36 @@ Feature: Skill YAML schema validation Then the skill schema validation should fail And the skill schema error should mention "namespace/name" + Scenario: Uppercase namespace is rejected by SkillConfigSchema + Given a skill YAML string with name "MyOrg/my-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: Uppercase name part is rejected by SkillConfigSchema + Given a skill YAML string with name "myorg/MySkill" + 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: Fully uppercase namespaced name is rejected by SkillConfigSchema + Given a skill YAML string with name "MyOrg/MySkill" + 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: Uppercase tool reference name is rejected by SkillToolRefSchema + Given a skill YAML string with an invalid tool ref name "MyOrg/MyTool" + 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: Uppercase include name is rejected by SkillIncludeSchema + Given a skill YAML string with an invalid include name "MyOrg/MySkill" + 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 tool reference name Given a skill YAML string with an invalid tool ref name "no-slash-tool" When I validate the skill schema expecting failure diff --git a/src/cleveragents/action/schema.py b/src/cleveragents/action/schema.py index be1a697ff..8ce054207 100644 --- a/src/cleveragents/action/schema.py +++ b/src/cleveragents/action/schema.py @@ -39,10 +39,8 @@ logger = logging.getLogger(__name__) # Constants # ──────────────────────────────────────────────────────────── -#: Pattern for ``/`` with hyphens, underscores, alphanum. -NAMESPACED_NAME_RE = re.compile( - r"^[a-zA-Z0-9][a-zA-Z0-9_-]*/[a-zA-Z0-9][a-zA-Z0-9_-]*$" -) +#: 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_-]*$") #: Pattern for ``${VAR}`` environment variable references. _ENV_VAR_RE = re.compile(r"\$\{([A-Za-z_][A-Za-z0-9_]*)\}") diff --git a/src/cleveragents/skills/schema.py b/src/cleveragents/skills/schema.py index ddd4a0556..25cfa722c 100644 --- a/src/cleveragents/skills/schema.py +++ b/src/cleveragents/skills/schema.py @@ -37,10 +37,8 @@ logger = logging.getLogger(__name__) # Constants # ──────────────────────────────────────────────────────────── -#: Pattern for ``/`` with hyphens, underscores, alphanum. -NAMESPACED_NAME_RE = re.compile( - r"^[a-zA-Z0-9][a-zA-Z0-9_-]*/[a-zA-Z0-9][a-zA-Z0-9_-]*$" -) +#: 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_-]*$") #: Pattern for ``${VAR}`` environment variable references. _ENV_VAR_RE = re.compile(r"\$\{([A-Za-z_][A-Za-z0-9_]*)\}") -- 2.52.0