Publishing Guide
Publishing an Agent Workflow
A listing comes from a GitHub repository; a version comes from a GitHub Release of that repository. The marketplace stores each version's artifact, so installs never depend on GitHub.
1. Create a GitHub repository
At submit time, only programmatic.json in the repository root is checked. A SKILL.md is recommended: it is shown on the listing page.
- programmatic.json — Listing metadata (name, id, format, description, tags)
- SKILL.md — Documentation with YAML frontmatter (optional)
2. programmatic.json
{
"name": "My Agent",
"id": "my-agent",
"version": "2026-03-01",
"format": "robothor-native/v1",
"department": "email",
"description": "What this agent does",
"tags": ["email", "classification"]
}
The id is the listing's slug (lowercase letters, digits and inner hyphens, at most 64 characters); without one, the repository name is used. genus agent publish writes this file for you.
3. SKILL.md
Include YAML frontmatter at the top:
---
name: My Agent
version: "2026-03-01"
description: What this agent does
format: robothor-native/v1
department: email
---
# My Agent
Detailed documentation here...
4. Submit to the catalog
Via the web:
Sign in, go to /submit and enter your repository URL. You must belong to the repository's owner (your own GitHub account, or an organisation you are a member of). Only programmatic.json is checked at submit. Your agent is added as a private listing, visible only to that organisation; an admin of the owning organisation makes it public from the Dashboard.
To list a private repository, the owner must first install the marketplace's GitHub App; the submit page links to the App's install page once the marketplace's App is configured.
Via the CLI:
genus agent publish https://github.com/your-org/your-agent
5. Create a GitHub Release with the artifact
A version exists only when a GitHub Release carries the built artifact as an asset. A tag alone, or a release without the asset, creates no version.
Agent bundle: attach agent-<slug>-<version>.tar.gz, the file genus agent export writes. Its setup.yaml is validated inside the release tarball, and its agent_id must be the listing's slug.
genus agent export my-agent
gh release create v1.0.0 agent-my-agent-1.0.0.tar.gz --generate-notes
Plugin: attach a .whl whose distribution name normalises (PEP 503) to the slug and that contains exactly one genus-plugin.yaml.
The catalog picks up new release assets on its next sync (every 15 minutes, and once at submit). Each asset is validated and stored; versions are immutable, so a release that reuses a published version number with different bytes is refused, and the reason appears on your Dashboard.
6. Plugins
A listing whose programmatic.json format is genus-plugin/v1 is a plugin: a Python wheel declared by its genus-plugin.yaml. Plugins are always free, and are installed with genus plugin install from the marketplace's signed index, never from the bundle API.
Operators point Genus OS at the index and pin its signing key:
- ROBOTHOR_PLUGIN_INDEXES — the public index URL (
/index.json), or your organisation's private index URL, which an admin of the organisation issues from the Dashboard (it lists public listings plus the organisation's private ones) - ROBOTHOR_PLUGIN_INDEX_KEYS — a directory holding the marketplace's public key as
<key_id>.pem
export ROBOTHOR_PLUGIN_INDEXES=https://programmaticresources.io/index.json
export ROBOTHOR_PLUGIN_INDEX_KEYS=/etc/genus/index-keys
genus plugin install my-plugin
7. Paid listings
Only the marketplace owner (Ironsail) sells listings, and checkout is coming soon. Anything else that is shared publicly is free.