Competency Authoring
What you'll accomplish: Create a custom competency package with a COMPETENCY.md payload, system prompt, and test it locally.
Package structure
my-competency/
├── MANIFEST.toml # Package identity (name, title, version, type)
├── README.md # Human documentation
└── payload/
└── COMPETENCY.md # YAML frontmatter + system prompt body
A competency payload is a single COMPETENCY.md file — YAML frontmatter carries structured metadata, and the markdown body IS the system prompt. Identity (name) lives in the sibling MANIFEST.toml, not in COMPETENCY.md frontmatter.
Minimal example
MANIFEST.toml:
[package]
type = "competency"
name = "policy-lookup"
title = "Policy Lookup"
version = "0.1.0"
description = "Retrieves and summarizes insurance policy details"
license = "Apache-2.0"
min_platform_version = "0.5.0"
payload/COMPETENCY.md:
---
description: "Retrieves and summarizes insurance policy details"
skills:
- claims-core-lookup
---
You are a policy lookup specialist. When asked about a policy:
1. Query the database for the policy by number or customer name
2. Summarize coverage, limits, deductibles, and renewal date
3. Flag any gaps in coverage
Full example
payload/COMPETENCY.md (see MANIFEST.toml schema for the sibling manifest):
---
description: "First Notice of Loss processing for property and auto claims"
skills:
- document-ocr
- claims-core-lookup
- email-skill
schedule: "0 */6 * * *"
schedule_action: "Check for new loss reports and process any unhandled intake items."
integrations:
- guidewire-claimcenter
- lexisnexis-clue
inputs:
- name: loss_description
type: string
required: true
- name: severity
type: integer
range: [1, 5]
outputs:
- name: claim_number
type: string
- name: coverage_confirmed
type: boolean
settings:
- key: auto_escalate_threshold
label: Auto-Escalate Severity
description: "Claims at or above this severity auto-escalate to supervisor"
type: Select
default: "4"
values:
- "3"
- "4"
- "5"
---
You are a claims intake specialist for an insurance company.
Your responsibilities:
1. Collect loss details (date, location, description, parties involved)
2. Verify policy coverage for the reported loss type
3. Create a claim record in ClaimCenter
4. Run a CLUE report for prior claims history
5. Assign initial severity and route to appropriate adjuster queue
Guidelines:
- Always verify the policyholder's identity before proceeding
- Document all collected information in the claim record
- For severity 4-5 claims, escalate immediately to a supervisor queue
- Never approve or deny coverage — only intake and route
COMPETENCY.md field reference
Frontmatter field ordering
Fields should follow this ordering convention:
- Identity —
description - Dependencies —
skills,tools,contracts,integrations - Operational —
schedule,schedule_action - Data contract —
inputs,outputs - Configuration —
settings
There is no category or permissions field on COMPETENCY.md frontmatter — the struct is deny_unknown_fields, so either would cause the manifest to fail to parse. Categorization happens via MANIFEST.toml's [package.metadata] categories; tool access is scoped on the agent side via AGENT.md's allow_skill_tools/allow_integration_tools (ADR-052), not declared by the competency itself.
Frontmatter fields
| Field | Type | Required | Description |
|---|---|---|---|
description | string | Yes | What this competency does |
skills | string[] | No | Skill packages this competency depends on (kebab-case) |
tools | string[] | No | Individual tool names this competency depends on |
contracts | string[] | No | Integration contract names this competency depends on (ADR-051) |
integrations | string[] | No | Integration packages this competency depends on |
inputs | array | No | Data contract — what the competency expects (see below) |
outputs | array | No | Data contract — what the competency produces (see below) |
settings | array | No | Operator-configurable settings (see below) |
schedule | string | No | Cron expression |
schedule_action | string | No | Message sent when cron fires (required if schedule is set) |
Package identity (name) is not a frontmatter field for any package type — it lives solely in the sibling MANIFEST.toml's [package] name. Classification/discovery tags live in MANIFEST.toml's [package.metadata] categories, not in COMPETENCY.md. The frontmatter struct is deny_unknown_fields: an id/name/category/permissions key (or any other field not listed above) causes the manifest to fail to parse.
Markdown body (system prompt)
The markdown body after the closing --- IS the system prompt. It is injected verbatim into the agent's context when the competency is equipped. Must be non-empty.
inputs / outputs (optional)
Define the data contract — what the competency expects to receive and what it produces.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Parameter identifier |
type | string | Yes | Data type (string, integer, boolean, etc.) |
required | boolean | No | Whether the input is mandatory |
range | array | No | Valid value range (for numeric types) |
settings (optional)
| Field | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Setting identifier |
label | string | No | Human-readable label |
description | string | No | What this controls |
type | enum | Yes | Select, Text, Toggle, or Number |
default | string | Yes | Default value |
values | string[] | No | For Select: list of valid option values |
Tool access is scoped on the agent, not the competency
A competency does not declare permissions or a trust/access policy — there's no such field on COMPETENCY.md. Two separate, agent-side mechanisms control what a competency's declared skills/tools/integrations can actually do once attached:
- Tool visibility (ADR-052). The agent's
AGENT.mdfrontmatter carriesallow_skill_tools/allow_integration_tools— an allowlist of tool names the agent is permitted to invoke, regardless of which competencies expose them. A competency can declare a dependency on a skill/integration; if the agent's allowlist doesn't include its tools, the agent still can't call them. - PII policy. What data a tool call is allowed to see or emit is governed entirely by the operator-owned
carrier-pii-policy.toml(ADR-049) — not by anything the competency or agent declares.
See Using competencies and RBAC for the full access-control picture.
System prompt best practices
Do
- Be specific about the domain and task boundaries
- Include explicit safety rails ("Never approve or deny coverage")
- Reference tools/skills available ("Use the postgresql.query tool to...")
- Define escalation criteria clearly
- Keep under 2000 tokens
Don't
- Include credentials or connection strings
- Repeat what tools already enforce (permission checks, PII filtering)
- Include instructions that conflict with platform safety
- Assume you're the only competency — write prompts that compose well
Multi-competency considerations
Since agents can equip multiple competencies, system prompts are concatenated in position order. Keep these guidelines in mind:
- Avoid contradictory instructions (e.g., "Always respond in JSON" in one competency vs. prose in another)
- Don't redefine the agent's identity — describe the role, not "you are the only thing this agent does"
- Use clear section headers in your prompt so operators can identify which competency contributed what
Testing locally
# 1. Lint the package
hoziron-cli package lint ./my-competency/
# 2. Install the competency definition
hoziron-cli competency install ./my-competency/payload/
# 3. Check skill dependencies
hoziron-cli competency check-deps claims-intake
There is no runtime equip command (see Using competencies — competency attachment is definition-driven). To actually exercise the competency against an agent, add it to a test agent-template's AGENT.md:
---
description: "Test harness for my-competency"
competencies:
- claims-intake
---
Then install (or reinstall, if iterating) the agent package and message it:
hoziron-cli package build ./my-test-agent/
hoziron-cli catalog install my-test-agent --activate
hoziron-cli agent list # find the new agent's ID
hoziron-cli agent chat <agent-id>
# Test: process a new auto claim for policy #POL-2024-100
Adjust settings on that agent's binding via the agent-scoped config endpoint:
curl -X PUT http://localhost:4200/agents/{agent-id}/competencies/claims-intake/config \
-H "Content-Type: application/json" \
-H "Authorization: Bearer hzk_..." \
-d '{"auto_escalate_threshold": "3"}'
Next steps
Related: