Skip to content

Latest commit

 

History

History
478 lines (346 loc) · 32 KB

File metadata and controls

478 lines (346 loc) · 32 KB

Contributing to Skillware

Welcome to Skillware. We are building an open registry of modular, deterministic agent capabilities—skills that any compatible runtime can load. Most contributors add or improve skills, but documentation, framework fixes, tests, and good first issues are equally welcome.

This document is the single entry point for how to contribute. If you are an AI agent working on this repository, read Agent Contribution Workflow first. Human operators may use the same guide to supervise agent work.


Navigation

Section Description
Ways to contribute Choose your contribution type
Getting started Fork, branch, install, open issues
Universal expectations Standards that apply to every PR
Pull request process From issue to merge
Skill Package Standard Required layout for registry skills
Skill categories Folder taxonomy under skills/
What to avoid Anti-patterns
Safety and security High-risk skills
Related documents Code of conduct, testing, templates

Ways to contribute

Pick the path that matches your issue. Only the skill row requires the full bundle under Skill Package Standard.

Type What you change Typical issue label Before coding Verify locally
New skill skills/<category>/<name>/, docs/skills/, templates skill request, enhancement New Skill Proposal or approved issue Bundle test + pytest tests/test_skill_issuer.py (see TESTING.md)
Skill upgrade Existing bundle under skills/ skill upgrade, enhancement Skill Upgrade issue Bundle test + catalog/docs as needed
Documentation docs/, README.md, CONTRIBUTING.md documentation Documentation Fix issue Links valid; tone consistent
Core framework skillware/core/, framework tests/ core framework, enhancement Framework Feature issue pytest tests/; update usage docs if API changes
CLI skillware/cli.py, docs/usage/cli.md cli CLI issue pytest tests/test_cli.py when relevant (list, doctor, test, paths, examples, menu); pytest tests/test_config.py when config paths or .skillware.yaml persistence changes
Examples examples/*.py, agent loops, examples index examples Examples issue Script runs; pytest tests/test_registry_docs.py when index changes
Packaging pyproject.toml, MANIFEST.in, wheel packaging Packaging issue scripts/wheel_smoke_test.py after wheel build (see TESTING.md)
Bug fix Paths named in issue bug Bug Report Reproduction or failing test
Good first issue Usually docs, tests, or small fixes good first issue Read acceptance criteria literally Checklist for underlying type above
RFC / large change Architecture, manifest contract discussion, core framework RFC issue Per RFC scope

Skills remain the primary contribution we expect, but every type above should follow Getting started, Universal expectations, and Pull request process.


Getting started

1. Find or open an issue

Check existing issues before starting work.

Intent Issue template
New capability in the registry New Skill Proposal
Upgrade an existing skill Skill Upgrade
Loader, adapters, base_skill Framework Feature
CLI (list, test, doctor, examples, menu) CLI
Runnable examples / agent loops Examples
PyPI wheel / install packaging Packaging
Docs only Documentation Fix
Incorrect behavior Bug Report
Large or breaking design RFC

Issue chooser links: CONTRIBUTING, good first issues, Skill Library. Labels are defined in .github/labels.json and synced automatically on merge to main (see sync-labels workflow).

Label taxonomy: Repo-wide labels describe contribution type or area (bug, cli, security, …). Registry category labels use the cat: prefix (cat: office, cat: security, …) so they never collide with repo-wide names — for example security is for vulnerabilities and trust-model work, while cat: security filters issues about skills under skills/security/. All cat: labels share one pastel color (#E6D9F5). Maintainers may add a cat: label when triaging skill issues and PRs.

Wait for maintainer feedback on non-trivial work before investing in a large PR.

2. Fork and clone

Fork ARPAHLS/skillware to your GitHub account, then clone your fork:

git clone https://github.com/<your-username>/skillware.git
cd skillware
git remote add upstream https://github.com/ARPAHLS/skillware.git

3. Sync and branch

git fetch upstream
git checkout main
git pull upstream main
git checkout -b feat/issue-<number>-short-description

4. Install dependencies

pip install -e ".[dev,all]"

For documentation-only PRs, pip install -e ".[dev]" is sufficient. For skill or framework work, use [dev,all] to match CI (optional [agents] for SDK examples — see Install extras).

See TESTING.md for the bundle / framework / maintainer / example model and pytest usage.

5. Implement and verify

Follow the table in Ways to contribute, then Pull request process.


Universal expectations

These apply to all contributions, regardless of type.

Code of conduct

Follow the Agent Code of Conduct: deterministic skill outputs, documented dependencies, no malicious or deceptive code.

Style

  • No emojis in source code, documentation, commit messages, or PR titles.
  • Use Black for formatting (CI runs black --check) and Flake8 for linting (see TESTING.md).
  • Match existing naming, structure, and documentation tone in the files you touch.

Scope

  • Change only what the issue requires. Avoid unrelated refactors or drive-by edits.
  • Do not bump the package version in pyproject.toml (or CITATION.cff version / date-released) unless the issue or a maintainer explicitly requests it (skill-only PRs typically do not version the framework). See Maintainer: cutting a framework release.
  • When a PR changes user-visible behavior (framework features, new or changed skills, breaking fixes, CLI or documentation users rely on), add entries under [Unreleased] in CHANGELOG.md in the same PR (Keep a Changelog sections: Added / Changed / Fixed / Removed). Do not add version headers or publish releases; maintainers cut releases.
  • Skill-only PRs that will not ship in the next PyPI release may omit a CHANGELOG entry; ask on the issue or use maintainer judgment.

Tests and CI

  • Add or update tests in the correct layer when behavior changes (see TESTING.md).

  • Skill bundle testskills/<category>/<name>/test_skill.py (required for new skills; ships in the wheel; runs in CI via pytest skills/).

  • Framework testtests/test_*.py at repo root (loader, CLI, issuer rules, doc-drift guards).

  • Maintainer skill test — optional tests/skills/<category>/test_<name>.py for extra loader or edge-case coverage.

  • Usage examplesexamples/*.py are not tests and are not run in CI.

  • GitHub Actions runs two jobs on every PR (see .github/workflows/ci.yml):

    • build — editable install pip install -e ".[dev,all]", then python -m black --check ., flake8 ., pytest skills/ (bundle tests), pytest tests/ (framework + maintainer tests).
    • wheel-smoke — builds a wheel, installs it in a fresh venv (base deps only), runs scripts/wheel_smoke_test.py to verify every bundled registry skill ships correctly. See Packaging smoke test.
  • Do not add per-skill pip lines or hardcoded skill paths to .github/workflows/ci.yml.

  • Run locally before opening a PR:

    python -m black --check .
    python -m flake8 .
    python -m pytest skills/
    python -m pytest tests/

    Bundle tests can also be run with skillware test (see CLI reference); requires [dev] or [dev,all].

    For a single skill:

    python -m pytest skills/<category>/<skill_name>/test_skill.py

    Or: skillware test <category>/<skill_name>.

  • Install packages from that skill's manifest.yaml requirements when they are not covered by [all]. After adding a skill with new third-party deps, run python scripts/sync_extras.py (see Install extras).

  • Wait for GitHub Actions CI to pass before requesting review.

Pull request template

Use the pull request template. Complete the New or updated skill section only when this PR adds or changes files under skills/.

Before requesting review, verify your PR template checklist:

  • Select the correct change type (skill, documentation, framework, bug fix).
  • Confirm local flake8, black and pytest pass (both pytest skills/ and pytest tests/).
  • Add a CHANGELOG entry under [Unreleased] when the change is user-visible.
  • Fill only the checkboxes that truthfully apply; do not leave unchecked defaults.

AI agents and operators

Agents must follow Agent Contribution Workflow. Human operators: approve the agent's plan before implementation, verify tests, and own the fork, commit, and PR. The operator remains responsible for the merged diff.


Pull request process

  1. Link an issue — Reference it in the PR description (Fixes #123 or Refs #123).

  2. Fork and branch — Work on a feature branch, not main of the upstream repo.

  3. Implement — Use the checklist for your contribution type (Ways to contribute).

  4. Verify locally:

    python -m black --check .
    python -m flake8 .
    pytest skills/
    pytest tests/

    Or skillware test for bundle tests (see CLI reference).

    For skill work, also run:

    pytest skills/<category>/<skill_name>/test_skill.py
    pytest tests/test_skill_issuer.py

    Or skillware test <category>/<skill_name> for the bundle test only.

  5. Commit — Clear imperative message, no emojis; include issue reference when appropriate. Do not add AI tools in Co-authored-by: trailers (see Agent Code of Conduct).

  6. Changelog — If the PR is user-visible, add lines under [Unreleased] in CHANGELOG.md before opening the PR.

  7. Push to your fork and open a PR into ARPAHLS/skillware main.

  8. CI — Ensure checks pass; address review feedback on the same branch.

Skill-specific steps (in addition to the above)

  1. Copy or align with templates/python_skill/.
  2. Create skills/<category>/<skill_name>/ with the full bundle (see Skill Package Standard).
  3. Add docs/skills/<skill_name>.md and a row in docs/skills/README.md.
  4. When adding or renaming a runnable script under examples/, update examples/README.md in the same PR.
  5. Confirm SkillLoader.load_skill("<category>/<skill_name>") works or document required packages and environment variables.

Skill Package Standard

Skills you submit are reviewed for origin and quality, not sandboxed at runtime — operators run them in their own process. Understand the skill trust model before designing a skill's behavior.

Every registry skill lives in skills/<category>/<skill_name>/ and must include the files below. This is the detailed standard for the skill contribution type.

Skill anatomy (vocabulary)

Checklists below use file names; each file implements a role. The README Mission summarizes the core roles; full reference: docs/introduction.md — Skill anatomy.

Role v0 file(s) Required
Contract manifest.yaml Yes
Effect skill.py (+ effect modules in the same folder) Yes
Directive instructions.md Yes
Assurance test_skill.py Yes (registry)
Presentation card.json Recommended
Corpus kb/, data/, bundled knowledge files Optional
Reference schemas/, maps, in-bundle spec fixtures Optional
Interface skillware/core/loader.py adapters Framework (not in bundle)

Effect modules (for example workflow.py, budget.py) are imported by skill.py—implementation detail, not a separate required file. Corpus tooling (for example maintenance/) refreshes Corpus offline and is not loaded by execute().

1. manifest.yaml (Contract)

Defines the tool interface, safety constitution, dependencies, and issuer attribution.

Required fields and sections:

  • name — registry skill ID in category/skill_name form; must match the folder path under skills/ (same string as SkillLoader.load_skill(...) and the CLI ID column). Do not use a short name alone (for example pdf_form_filler without the office/ prefix). The loader emits SkillwareIdentityWarning when a registry-layout skill (<skill_root>/<category>/<skill_name>/) has a missing or mismatched name (warn-only in v1; may become an error later). Flat private layouts (<skill_root>/<skill_name>/) skip this check. Enforced in CI via tests/test_registry_identity.py — mismatched or duplicate manifest.name blocks merge (#280).
  • version, description
  • issuer — see Issuer attribution; name and email required, github and org optional
  • short_description — optional one-line summary (~80 chars) shown in skillware list when present
  • parameters — valid JSON Schema for LLM tool calling
  • constitution — safety boundaries enforced at the prompt level
  • requirements — when external packages are needed (for example requests, pandas). Use PEP 508 strings; add version specifiers (for example web3>=6.0.0) when the skill depends on a minimum package version — SkillLoader.load_skill() validates pins at load time (see Install extras).

Optional but common:

  • env_vars — API keys and configuration (never hardcode secrets in skill.py); document the same names on the skill catalog page and link to API keys for skills
  • category, outputs, presentation — when they clarify the skill contract. Use outputs: with named keys (never legacy singular output:).

Example:

name: category/generic_hello
version: 1.0.0
description: A friendly greeting skill.
issuer:
  name: Your Name
  email: you@example.com
  github: your_github_username
  org: YOUR ORG
parameters:
  type: object
  properties:
    name:
      type: string
  required:
    - name
constitution: |
  1. Do not greet offensive names.
  2. Always maintain a polite tone.
requirements:
  - requests

2. skill.py (Effect)

  • Define exactly one concrete subclass of BaseSkill per skill file. SkillLoader.load_skill() discovers it automatically as bundle["class"] (see SkillLoader.get_skill_class()).
  • Implement deterministic Python logic; inherit from BaseSkill.
  • Accept a dictionary of inputs; return a JSON-serializable dictionary.
  • Catch internal errors and return a structured error report; do not crash the host agent.
  • Do not print to stdout or stderr for normal operation.
  • Do not embed open-ended LLM code generation as the skill implementation.
  • When you change the JSON shape returned by execute(), update card.json output fields (if present) and the matching fixture under tests/fixtures/card_ui_schema/ in the same PR.

3. instructions.md (Directive)

The primary guide for the host LLM. Skill instructions should be a concise, append-only block focusing on this skill's context rather than assigning an overarching persona (host agents and LLMs already have their own system prompts).

  • Prefer skill context: Open with what the skill does, its registry ID (category/skill_name), deterministic behavior, and key limits.
  • When to invoke / when not to invoke: Clearly explain primary use cases and anti-patterns.
  • Outputs and errors: Detail how to interpret returned fields (image_base64, paths, structured dicts) and handle error states.
  • Avoid persona starters: Avoid opening with "You are an agent equipped with...", "You are an expert...", or narrative personality instructions that can conflict when multiple skills are appended to context.
  • Keep prompts and persona here, not in skill.py.

4. card.json (Presentation)

  • Recommended for every registry skill; all bundled skills under skills/ ship one.
  • Describes UI presentation (name, description, icon, ui_schema, and similar).
  • When present, include an issuer object that matches manifest.yaml (name and email at minimum; copy github and org when used).
  • For output cards (ui_schema.type = card), each ui_schema.fields[].key must be a dot path into the JSON returned by execute() (for example metadata.wallet_address, preview.you_pay). Update card.json in the same PR when you change the output shape.
  • Add or refresh a representative output fixture at tests/fixtures/card_ui_schema/<category>__<skill_name>.json (one object or a {"samples": [...]} list when multiple execute paths surface different fields). CI validates keys via tests/test_card_ui_schema.py (#199).

5. test_skill.py (Assurance)

  • 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 or skillware test <category>/<skill_name>
  • Optional extra depth for maintainers: tests/skills/<category>/test_<skill_name>.py — see TESTING.md.
  • Mock network calls and first-run model downloads in bundle tests.

Optional bundle assets

Not required for every skill. When present, document them on the catalog page under Bundle layout (see skill usage template).

  • Corpuskb/, data/, or other versioned knowledge files the Effect reads at runtime.
  • Referenceschemas/, terminology maps, or in-bundle fixtures that define the public contract or demos.
  • Effect modules — additional .py files imported only by skill.py (not separate registry roles).
  • Corpus tooling — offline maintenance scripts (not loaded by execute()); keep out of the Effect import path unless intentional.

Packaging (PyPI and pip install)

Registry skills are shipped inside the skillware wheel. Per-skill layout uses manifest.yaml and packaging hooks below — not per-skill edits to CI.

  • Add an empty __init__.py in skills/<category>/ when you introduce a new category, and in skills/<category>/<skill_name>/ for each new skill directory (enforced by tests/test_skill_issuer.py).
  • Non-Python files (manifest.yaml, instructions.md, card.json, data files) are included automatically via MANIFEST.in and [tool.setuptools.package-data] (skills = ["**/*"]).
  • Confirm SkillLoader.load_skill("<category>/<skill_name>") works from the repo root. CI wheel-smoke verifies every bundled skill from a clean pip install of the built wheel; run scripts/wheel_smoke_test.py locally when changing packaging, MANIFEST.in, or skill bundle layout (see TESTING.md).

Manifest requirements and optional extras

  • List runtime packages in the skill's manifest.yaml requirements (source of truth for loaders and docs).
  • Unpinned entries (for example requests) — loader checks the importable module exists.
  • Pinned entries (for example rembg>=2.0.0) — loader also verifies the installed distribution satisfies the specifier before skill.py runs. Pin when API or behavior breaks across versions; unpinned is fine for stable deps.
  • Run python scripts/sync_extras.py after changing manifests — it regenerates category, per-skill, and [all] rows in pyproject.toml (see Install extras).
  • Core already includes requests, pyyaml, and beautifulsoup4 (manifests may say bs4); the sync script omits core packages from extras automatically.
  • Hand-maintained extras (dev, gemini, claude, openai, agents) stay above the generated block in pyproject.toml.
  • Contributors and CI install skill runtime deps with pip install -e ".[dev,all]"; add [agents] when running SDK examples locally.

6. docs/skills/<skill_name>.md (catalog page)

  • Human-readable documentation linked from the Skill Library.
  • Include ID, Issuer, Version (from manifest.yaml), and Recommended install (pip install "skillware[<category>_<skill>]" — see install_extras.md) near the top.
  • Describe capabilities, prerequisites, arguments, and limitations.
  • If the skill calls external services, list its environment variables in a short table and link to API keys for skills. Do not duplicate the full setup guide on the skill page.
  • Add a Usage Examples section with runnable snippets for Gemini, Claude, OpenAI, DeepSeek, and Ollama (prompt mode). Follow skill usage example template and link to usage guides and agent loops.
  • Add a Skill history section before the enterprise disclaimer: a table of notable commits that touched the skill bundle or catalog page. Link each commit SHA and list contributors as linked GitHub usernames ([@username](https://github.com/username)). Append a row when you ship a skill update in the same PR.

7. Registry index row

  • Add or update the skill table in docs/skills/README.md (Skill, ID, Version, Issuer, Description). Set Version to `x.y.z` (DD Mon YYYY) from the manifest and the release/merge date.

Issuer attribution

The manifest is the source of truth for issuer data. Use real contact details in everything under skills/—not template placeholders (Your Name, you@example.com, YOUR ORG, and similar).

Field Required Notes
issuer.name Yes Display name of the contributor or maintainer
issuer.email Yes Contact email for the skill author
issuer.github No GitHub username without @
issuer.org No Optional affiliation / design-ownership org (see Issuer org)

Registry-wide issuer rules are enforced in tests/test_skill_issuer.py (skills under skills/ only; templates are excluded).

Issuer org

issuer.org is an optional single string for affiliation or design ownership — not necessarily who wrote every line of code. Individual credit stays in issuer.name, email, and github. Omit org when no org applies. Use comma-separated values when multiple orgs apply (for example ARPAHLS, AO).

Situation issuer.org Catalog Issuer line
ARPA-maintainer / ARPA-audited skill ARPAHLS [@author](…) ([@ARPAHLS](…))
Third-party–driven skill contributor org or omit [@author](…) ([AO](https://github.com/0x-AO-Protocol)) or author only
Co-affiliation (e.g. ARPAHLS + AO) ARPAHLS, AO [@author](…) ([@ARPAHLS](…), [AO](https://github.com/0x-AO-Protocol))

Separate multiple orgs with a comma in the single org string (for example org: ARPAHLS, AO). Match the catalog Issuer line to the manifest value.


Skill categories

Place each skill under one top-level directory under skills/. Use an existing category when it fits.

Category Purpose Examples in registry
creative Image processing, media editing, and creative utilities bg_remover
compliance Privacy, policy, regulatory guardrails pii_masker, mica_module, tos_evaluator
data_engineering Datasets, generation, ETL-style tooling synthetic_generator, novelty_extractor
defi On-chain trading and agent wallet execution evm_tx_handler
dev_tools Developer workflows, issue resolution, repo tooling issue_resolver
finance Blockchain, risk, financial analysis wallet_screening, uk_companies_house_handler
office Documents, productivity, email pdf_form_filler, gmail_handler
optimization Middleware, compression, efficiency prompt_rewriter
monitoring Agent loop observability, budget gates, task control token_limiter
security Offline, local-first defenses for untrusted input reaching agents prompt_injection_firewall, deceptive_ui_guard
wellness Coaching guardrails, mental health support mental_coach

Choosing a category

The table above is illustrative, not a closed list. When contributing a new skill, pick the category whose purpose best matches the skill's primary function.

Registry IDs are always category/skill_name from the folder path and must match the name field in manifest.yaml (same string as SkillLoader.load_skill(...) and the CLI ID column). For the live registry, see Skill Library.

New top-level category? Open an issue and discuss with maintainers before adding a folder — do not create skills/<new_category>/ in a pull request without that agreement.

When a new top-level category lands under skills/, update this table and the category dropdown in .github/ISSUE_TEMPLATE/01_skill_proposal.yml in the same PR. Add a matching cat: <category> entry to .github/labels.json (same pastel color as other cat: labels; never use the bare folder name as a repo-wide label). Update REGISTRY_CATEGORIES in tests/test_github_labels.py in the same PR. Labels sync via CI on merge to main.


What to avoid

  • God skills — One skill that does everything; split into focused capabilities.
  • Hardcoded models — Do not hide prompts in skill.py; use instructions.md.
  • Vendor lock-in — Prefer standard Python over framework-specific wrappers in skill logic.
  • Environment leaks — No API keys in source; document env_vars in the manifest.
  • Placeholder issuers — No template names or emails in committed registry skills.
  • Unrequested version bumps — Do not change pyproject.toml version in routine skill PRs.

Safety and security

  • Skills that touch real-world assets (wallets, email, production APIs) should support a dry run or read-only mode when feasible. High-risk skills (on-chain transfers, wallet operations) should use preview and confirmation flows before sending transactions; read each skill's instructions before enabling live keys.
  • Sanitize inputs in skill.py before external calls.
  • Respect the skill constitution in both code and documentation.
  • Malicious or deceptive contributions may be rejected and blocked from the project.
  • Registry review is not runtime isolation. Passing maintainer review means a skill's origin is trusted; it does not sandbox the skill. All skills run in the host process regardless of tier. See the skill trust model.

Related documents

Document Purpose
API keys for skills Configuring credentials for skills that call external services
Agent Contribution Workflow Workflow written for contributing agents; operators supervise
TESTING.md Black, Flake8, Pytest, local CI parity
Agent Code of Conduct Behavioral expectations for humans and agents
docs/introduction.md Skill anatomy: Contract / Effect / Directive (+ Assurance, Corpus, Interface)
docs/vision.md Project story, roadmap, and agent discoverability
docs/skills/README.md Published skill catalog
templates/python_skill/ Boilerplate for new skills
Pull request template PR checklist
Issue templates Bug, docs, skills, CLI, examples, RFC chooser
.github/labels.json Repo-wide and cat: <category> label taxonomy (synced via CI)
CHANGELOG.md Release history; contributors add under [Unreleased]
CITATION.cff Preferred software citation (Zenodo concept DOI 10.5281/zenodo.21552745)
Security policy Reporting vulnerabilities

Maintainer: cutting a framework release

Routine contributor PRs must not bump the package version. Maintainers cut releases (chore / release PR or direct maintainer commit) and should keep version surfaces in sync:

Touch Every framework release? Notes
pyproject.toml[project].version Yes Source of truth for PyPI / importlib.metadata / skillware --version
CHANGELOG.md Yes Move [Unreleased] into ## [X.Y.Z] - YYYY-MM-DD; leave a fresh empty [Unreleased]
CITATION.cffversion, date-released Yes Match the release tag/date. Keep the Zenodo concept DOI in identifiers stable — do not swap it for a version DOI
GitHub Release + tag (vX.Y.Z) Yes Triggers Zenodo archive when GitHub–Zenodo is linked (#269). Paste release notes from CHANGELOG.md in the GitHub Releases UI — do not commit maintainer draft files such as .github/RELEASE_*.md to the public tree.
PyPI upload Yes After tag / CI as usual
README.md Citing example version Optional Only if an example pin (e.g. 0.4.7) is present; otherwise “record the version you used” is enough
skillware/version_policy.py + SECURITY.md Only when support windows change Not every release
CLI / loader code Usually no Version is read from installed package metadata
Skill manifest.yaml version No (unless that skill changed) Skill versions are independent of the framework version
docs/contributing/ai_native_workflow.md / CODE_OF_CONDUCT.md No Not version bump surfaces

README Citing badge and pyproject.toml [project.urls] DOI already point at the concept DOI. Do not add .zenodo.json unless a Zenodo-only field is required (it would override CFF).


Thank you for helping make agent capabilities portable, safe, and reusable.