UAT: SkillService._schema_to_skill_dict() silently drops SkillIncludeSchema.description override and SkillAgentFolderSchema.name override fields #2916

Open
opened 2026-04-05 02:48:00 +00:00 by freemo · 1 comment
Owner

Metadata

  • Branch: fix/skill-service-include-agent-folder-override-fields
  • Commit Message: fix(skills): preserve include description and agent folder name overrides in SkillService._schema_to_skill_dict()
  • Milestone: v3.7.0
  • Parent Epic: #374

Background

The SkillService._schema_to_skill_dict() method in
src/cleveragents/application/services/skill_service.py silently discards
two spec-defined override fields when a skill is registered:

  1. SkillIncludeSchema.description — an optional override for the
    included skill's description, defined in docs/schema/skill.schema.yaml
    under includes.items.fields.description.
  2. SkillAgentFolderSchema.name — an optional override for the agent
    skill bundle name, defined in docs/schema/skill.schema.yaml under
    agent_skill_folders.items.fields.name.

Both fields are correctly captured by their respective Pydantic schema
classes in src/cleveragents/skills/schema.py, but are never forwarded
into the dict that is passed to the domain layer.

Additionally, the corresponding domain models in
src/cleveragents/domain/models/core/skill.py do not yet carry these
fields — SkillInclude has no description attribute and
SkillAgentSource has no name attribute — so even if the mapping were
fixed in isolation, the domain model would silently discard the values.

Actual vs. Expected Behaviour

Includes mapping (actual — broken)

data["includes"] = [{"name": i.name} for i in config.includes]

i.description is never read; any YAML-supplied description override is
lost after schema validation.

Includes mapping (expected)

data["includes"] = [
    {"name": i.name, **({"description": i.description} if i.description is not None else {})}
    for i in config.includes
]

Agent skill folders mapping (actual — broken)

data["agent_skills"] = [{"path": f.path} for f in config.agent_skill_folders]

f.name is never read; any YAML-supplied bundle name override is lost.

Agent skill folders mapping (expected)

data["agent_skills"] = [
    {"path": f.path, **({"name": f.name} if f.name is not None else {})}
    for f in config.agent_skill_folders
]

Steps to Reproduce

Include description override:

  1. Create a skill YAML:
    name: local/my-skill
    description: "My skill"
    includes:
      - name: local/base-tools
        description: "Custom description for base tools in this context"
    
  2. Register: agents skill add --config my-skill.yaml
  3. Inspect: agents skill show local/my-skill
  4. Observe that the include description override is absent from the output.

Agent folder name override:

  1. Create a skill YAML:
    name: local/my-skill
    description: "My skill"
    agent_skill_folders:
      - path: ./tools
        name: "My Custom Bundle Name"
    
  2. Register: agents skill add --config my-skill.yaml
  3. Inspect: agents skill show local/my-skill
  4. Observe that the bundle name override is absent from the output.

Affected Files

File Issue
src/cleveragents/application/services/skill_service.py _schema_to_skill_dict() drops description from includes and name from agent folders
src/cleveragents/domain/models/core/skill.py SkillInclude missing description: str | None field; SkillAgentSource missing name: str | None field
src/cleveragents/skills/schema.py Correctly captures both fields — no change needed
docs/schema/skill.schema.yaml Authoritative spec — no change needed

Severity

Medium — Both override fields are spec-defined, accepted by the schema
validator without error, and then silently discarded during registration.
This constitutes silent data loss and reduces user trust in the system.
Users have no indication that their overrides are being ignored.

Subtasks

  • Add description: str | None field to SkillInclude domain model in src/cleveragents/domain/models/core/skill.py
  • Add name: str | None field to SkillAgentSource domain model in src/cleveragents/domain/models/core/skill.py
  • Update _schema_to_skill_dict() in src/cleveragents/application/services/skill_service.py to forward description from SkillIncludeSchema into the includes dict
  • Update _schema_to_skill_dict() in src/cleveragents/application/services/skill_service.py to forward name from SkillAgentFolderSchema into the agent_skills dict
  • Write Behave unit tests covering include description override round-trip (schema → dict → domain model)
  • Write Behave unit tests covering agent folder name override round-trip (schema → dict → domain model)
  • Verify Pyright type-checks pass with no # type: ignore suppressions (nox -e typecheck)
  • Verify coverage remains ≥ 97% (nox -e coverage_report)

Definition of Done

  • SkillInclude domain model carries a description: str | None field
  • SkillAgentSource domain model carries a name: str | None field
  • _schema_to_skill_dict() correctly forwards both override fields into the output dict
  • Registering a skill with an include description override preserves that override end-to-end
  • Registering a skill with an agent folder name override preserves that override end-to-end
  • All new behaviour is covered by Behave unit tests in features/
  • All nox stages pass
  • Coverage >= 97%

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

## Metadata - **Branch**: `fix/skill-service-include-agent-folder-override-fields` - **Commit Message**: `fix(skills): preserve include description and agent folder name overrides in SkillService._schema_to_skill_dict()` - **Milestone**: v3.7.0 - **Parent Epic**: #374 ## Background The `SkillService._schema_to_skill_dict()` method in `src/cleveragents/application/services/skill_service.py` silently discards two spec-defined override fields when a skill is registered: 1. **`SkillIncludeSchema.description`** — an optional override for the included skill's description, defined in `docs/schema/skill.schema.yaml` under `includes.items.fields.description`. 2. **`SkillAgentFolderSchema.name`** — an optional override for the agent skill bundle name, defined in `docs/schema/skill.schema.yaml` under `agent_skill_folders.items.fields.name`. Both fields are correctly captured by their respective Pydantic schema classes in `src/cleveragents/skills/schema.py`, but are never forwarded into the dict that is passed to the domain layer. Additionally, the corresponding domain models in `src/cleveragents/domain/models/core/skill.py` do not yet carry these fields — `SkillInclude` has no `description` attribute and `SkillAgentSource` has no `name` attribute — so even if the mapping were fixed in isolation, the domain model would silently discard the values. ## Actual vs. Expected Behaviour ### Includes mapping (actual — broken) ```python data["includes"] = [{"name": i.name} for i in config.includes] ``` `i.description` is never read; any YAML-supplied description override is lost after schema validation. ### Includes mapping (expected) ```python data["includes"] = [ {"name": i.name, **({"description": i.description} if i.description is not None else {})} for i in config.includes ] ``` ### Agent skill folders mapping (actual — broken) ```python data["agent_skills"] = [{"path": f.path} for f in config.agent_skill_folders] ``` `f.name` is never read; any YAML-supplied bundle name override is lost. ### Agent skill folders mapping (expected) ```python data["agent_skills"] = [ {"path": f.path, **({"name": f.name} if f.name is not None else {})} for f in config.agent_skill_folders ] ``` ## Steps to Reproduce **Include description override:** 1. Create a skill YAML: ```yaml name: local/my-skill description: "My skill" includes: - name: local/base-tools description: "Custom description for base tools in this context" ``` 2. Register: `agents skill add --config my-skill.yaml` 3. Inspect: `agents skill show local/my-skill` 4. Observe that the include description override is absent from the output. **Agent folder name override:** 1. Create a skill YAML: ```yaml name: local/my-skill description: "My skill" agent_skill_folders: - path: ./tools name: "My Custom Bundle Name" ``` 2. Register: `agents skill add --config my-skill.yaml` 3. Inspect: `agents skill show local/my-skill` 4. Observe that the bundle name override is absent from the output. ## Affected Files | File | Issue | |---|---| | `src/cleveragents/application/services/skill_service.py` | `_schema_to_skill_dict()` drops `description` from includes and `name` from agent folders | | `src/cleveragents/domain/models/core/skill.py` | `SkillInclude` missing `description: str \| None` field; `SkillAgentSource` missing `name: str \| None` field | | `src/cleveragents/skills/schema.py` | Correctly captures both fields — no change needed | | `docs/schema/skill.schema.yaml` | Authoritative spec — no change needed | ## Severity **Medium** — Both override fields are spec-defined, accepted by the schema validator without error, and then silently discarded during registration. This constitutes silent data loss and reduces user trust in the system. Users have no indication that their overrides are being ignored. ## Subtasks - [ ] Add `description: str | None` field to `SkillInclude` domain model in `src/cleveragents/domain/models/core/skill.py` - [ ] Add `name: str | None` field to `SkillAgentSource` domain model in `src/cleveragents/domain/models/core/skill.py` - [ ] Update `_schema_to_skill_dict()` in `src/cleveragents/application/services/skill_service.py` to forward `description` from `SkillIncludeSchema` into the includes dict - [ ] Update `_schema_to_skill_dict()` in `src/cleveragents/application/services/skill_service.py` to forward `name` from `SkillAgentFolderSchema` into the agent_skills dict - [ ] Write Behave unit tests covering include description override round-trip (schema → dict → domain model) - [ ] Write Behave unit tests covering agent folder name override round-trip (schema → dict → domain model) - [ ] Verify Pyright type-checks pass with no `# type: ignore` suppressions (`nox -e typecheck`) - [ ] Verify coverage remains ≥ 97% (`nox -e coverage_report`) ## Definition of Done - [ ] `SkillInclude` domain model carries a `description: str | None` field - [ ] `SkillAgentSource` domain model carries a `name: str | None` field - [ ] `_schema_to_skill_dict()` correctly forwards both override fields into the output dict - [ ] Registering a skill with an include description override preserves that override end-to-end - [ ] Registering a skill with an agent folder name override preserves that override end-to-end - [ ] All new behaviour is covered by Behave unit tests in `features/` - [ ] All nox stages pass - [ ] Coverage >= 97% --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-uat-tester
freemo added this to the v3.7.0 milestone 2026-04-05 02:48:08 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Medium (confirmed)
  • MoSCoW: Should Have — description override silently dropped

Valid UAT finding verified during batch triage.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified - **Priority**: Medium (confirmed) - **MoSCoW**: Should Have — description override silently dropped Valid UAT finding verified during batch triage. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
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.

Reference
cleveragents/cleveragents-core#2916
No description provided.