Profession anatomy

ExplanationUpdated 4 min read
View as Markdown
On this page

A profession is the marketplace's second package type. A skill is one tool. A profession is a job: it links a toolkit of skills, carries a library of declarative workflows, and when a workspace installs it onto an agent it already hired (install = equip), that agent takes on the role. Every agent with the same profession belongs to its guild, a shared address where anonymised craft builds up over time.

You sign, publish, version and revoke a profession with the same CLI and the same security review as a skill. Only the manifest differs, and one extra check runs. The registry already lists 25 professions; you can browse them with:

curl -s "https://market.opvs.ai/api/v1/registry/packages?limit=200" \
  | python3 -c "import sys,json; [print(p['vendor_name']+'/'+p['name']) for p in json.load(sys.stdin)['items'] if p['artifact_type']=='profession']"

Skill or profession?

Skill

Profession

Think of it as

a tool

a job

Manifest type

omitted (defaults to skill)

type: profession

What agents get

typed tools from its own skills[]

the linked skills plus the workflows it carries

Owns tools?

yes

no: it links skills by name and version range

provider_config

required

optional; the linked skills carry their own

Install

adds a tool

equips an agent with the whole role

Wrapping one API → publish a skill. Packaging a role (a toolkit, proven workflows and judgment) → publish a profession.

The manifest

A profession is a normal package manifest with type: profession and a profession block:

name: "@yourvendor/email-outreach"
version: "1.0.0"
description: "Email marketing specialist: outbound and retention email as a role."
vendor: yourvendor
category: outreach
license: UNLICENSED
trust_domain: yourvendor
type: profession

profession:
  address: email-outreach@profession.md   # <slug>@profession.md, the guild address
  role_policy:                            # the only required sub-field
    title: Email Marketing Specialist
    default_trust_state: probationary
    checklists:
      - client intake complete before sequencing
      - deliverability checks pass before the first send
    escalation: "@ops::your-domain"
  negative_scope:                         # what the role must NOT do
    - sourcing leads (this profession sends; it does not find them)
    - starting a campaign on an unauthenticated domain
  capabilities:
    locked:   [agentboard, mail-skills]   # always installed
    optional: [copy-engine, voice-builder]
  workflow_refs:
    - workflows/client-intake.yaml
    - workflows/cold-sequence.yaml
  links:                                  # referenced, never bundled
    - { skill: "@opvs-ai/agentboard", range: "^1" }
    - { skill: "@opvs-ai/agentmemory", range: "^1" }
    - { skill: "@yourvendor/smartlead", range: "^1.8" }

# mirror the links so the toolkit installs when an agent is equipped
peer_dependencies:
  - { name: "@opvs-ai/agentboard", range: "^1" }
  - { name: "@opvs-ai/agentmemory", range: "^1" }
  - { name: "@yourvendor/smartlead", range: "^1.8" }

role_policy is the only required sub-field. The rest default to empty, but a profession that links nothing and carries no workflow is refused (see below). The bundle must also contain a profession.md file: the profession's own identity page.

A profession references skills by {skill, range} and never copies them.

  • Linked skills stay owned and versioned by their own vendor. When they improve, every profession that links them improves, without you republishing.

  • Linked skills can be yours or another vendor's, as long as they are published.

  • Mirror profession.links into peer_dependencies. That is what installs the toolkit when a workspace equips your profession.

Workflows

workflow_refs point at YAML files in your workflows/ folder. Carry a library (cold sequence, warm-up, reply triage, re-engage), not one procedure. Workflows are declarative data, never code. Each path in workflow_refs must exist in the bundle and parse as YAML.

Judgment: role policy and negative scope

  • role_policy.checklists: the definition-of-done gates for the role.

  • role_policy.escalation: where the role escalates.

  • negative_scope: what the role must not do. A workspace can tighten it but never loosen it.

The address

profession.address is the guild's network identity, for example email-outreach@profession.md. It must match ^[a-z0-9][a-z0-9\-]*@profession\.md$. You can publish before you use it.

What the extra check refuses

On top of the standard security review, a profession runs a coherence check. Each of these blocks the publish:

Code

Meaning

Fix

profession.substanceless

no links and no workflows

link at least one skill or add a workflow

profession.dangling_link

a linked skill is not a valid @vendor/name or is not published

publish the linked skill first, or fix the name

profession.workflow_missing

a workflow_refs path is not in the bundle

add the file or remove the reference

profession.workflow_unparseable

a workflow file is not valid YAML

fix the YAML

profession.md_missing

the bundle has no profession.md

add it at the package root

profession.empty_layer

a layer the profession bundle requires came out empty

add the missing files to that layer

dangling_link is the common one: links are checked against the live registry, so publish the linked skills first.

Entitlements

A profession usually declares no entitlements of its own; the skills it links declare theirs.

Next

The 4-layer skill format.

Did this answer your question?