Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ Contributors add user-facing entries under `[Unreleased]` in the same PR. Mainta

## [Unreleased]

### Documentation
### Changed

- Clarified that bundle tests must mock network calls and model downloads in CI.
- **Tests**: `tests/test_skill_issuer.py` now requires `test_skill.py` for every registry skill under `skills/` (#160).
- **Documentation**: Clarified that bundle tests must mock network calls and model downloads in CI (#170).

## [0.3.7] - 2026-06-22

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ The primary guide for the host LLM.

### 5. `test_skill.py` (bundle test)

- **Required** for every new registry skill (template: `templates/python_skill/test_skill.py`).
- **Required** for every new registry skill (template: `templates/python_skill/test_skill.py`; enforced by `tests/test_skill_issuer.py`).
- Unit tests for schema compliance and deterministic execution paths (offline; mock externals).
- Ships inside the skill bundle via `pip install skillware`.
- Run: `pytest skills/<category>/<skill_name>/test_skill.py`
Expand Down
1 change: 1 addition & 0 deletions docs/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pip install -r requirements.txt
### Framework test

- Core engine health: loader, CLI, issuer rules, version policy.
- `tests/test_skill_issuer.py` also enforces registry packaging (`__init__.py`), issuer metadata, and presence of `test_skill.py` in every skill bundle.
- Lives at the **root of `tests/`** only (`tests/test_loader.py`, `tests/test_cli.py`, …).
- Clone-repo only; runs in CI via `pytest tests/` together with maintainer tests below.

Expand Down
2 changes: 1 addition & 1 deletion templates/python_skill/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Starter bundle under `skills/<category>/<skill_name>/`. Copy this template from
4. **`skill.py`**: Implement deterministic logic; no LLM-generated code in the skill body.
5. **`instructions.md`**: Tell the agent when and how to use the tool.
6. **`card.json`**: Mirror `issuer` from the manifest; customize UI fields.
7. **`test_skill.py`**: Bundle test (required); offline, mock external services, including HTTP clients, LLM APIs, embedding/model loaders, and any first-run model downloads; run `pytest skills/<category>/<skill_name>/test_skill.py`. See [TESTING.md](../../docs/TESTING.md).
7. **`test_skill.py`**: Bundle test (required; enforced by `tests/test_skill_issuer.py`); offline, mock external services, including HTTP clients, LLM APIs, embedding/model loaders, and any first-run model downloads; run `pytest skills/<category>/<skill_name>/test_skill.py`. See [TESTING.md](../../docs/TESTING.md).
8. **`docs/skills/<skill_name>.md`**: Catalog page with **ID**, **Issuer**, and **Usage Examples** (all providers; see `docs/usage/skill_usage_template.md`).
9. **`docs/skills/README.md`**: Add a row to the skill library table.

Expand Down
11 changes: 11 additions & 0 deletions tests/test_skill_issuer.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ def test_registry_skills_declare_issuer():
_assert_real_issuer(manifest.get("issuer"), f"{rel} manifest.yaml")


def test_registry_skills_have_bundle_test():
"""Every registry skill must ship a co-located bundle test (RFC #156)."""
for skill_dir in _discover_skill_dirs():
rel = skill_dir.relative_to(REPO_ROOT).as_posix()
assert (
skill_dir / "test_skill.py"
).is_file(), (
f"{rel}: add test_skill.py (bundle test required for every registry skill)"
)


def test_registry_skills_have_packaging_init_files():
"""Each registry skill must be importable under the skills package for pip wheels."""
assert (
Expand Down
Loading