Competency Authoring
What you'll accomplish: Create a custom competency with a COMPETENCY.toml manifest, system prompt, and test it locally.
Directory structure
my-competency/
└── COMPETENCY.toml
A competency is a directory containing a single COMPETENCY.toml file — the complete definition.
Minimal example
id = "policy-lookup"
name = "Policy Lookup"
description = "Retrieves and summarizes insurance policy details"
category = "Insurance"
skills = ["postgresql-connector"]
system_prompt = """
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
id = "claims-intake"
name = "Claims Intake"
description = "First Notice of Loss processing for property and auto claims"
category = "Insurance"
system_prompt = """
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
"""
skills = ["document-ocr", "postgresql-connector", "email-skill"]
permissions = ["NetworkConnect:*"]
schedule = "0 */6 * * *"
integrations = ["guidewire-claimcenter", "lexisnexis-clue"]
[[inputs]]
name = "loss_description"
type = "string"
required = true
[[inputs]]
name = "severity"
type = "integer"
range = [1, 5]
[[outputs]]
name = "claim_number"
type = "string"
[[outputs]]
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"
setting_type = "Select"
default = "4"
[[settings.options]]
value = "3"
label = "3 (Moderate)"
[[settings.options]]
value = "4"
label = "4 (High)"
[[settings.options]]
value = "5"
label = "5 (Critical only)"
COMPETENCY.toml field reference
Field ordering
Fields should follow this ordering convention:
- Identity —
id,name,description,category - Operational —
system_prompt,skills,permissions,settings,schedule - Data contract —
integrations,inputs,outputs
Top-level fields
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier (kebab-case) |
name | string | Yes | Human-readable display name |
description | string | Yes | What this competency does |
category | enum | Yes | Classification (see below) |
system_prompt | string | Yes | The system prompt injected into the agent |
skills | string[] | Yes | Skills needed (at least 1) |
permissions | string[] | No | Permissions the competency requires from the agent |
schedule | string | No | Cron expression |
integrations | string[] | No | External integrations used |
Valid categories
Insurance, Security, Productivity, Development, Communication, Data, Finance, Research, Operations, Other
[[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 | Yes | Human-readable label |
description | string | Yes | What this controls |
setting_type | enum | Yes | Select, Text, or Toggle |
default | string | Yes | Default value |
options | array | No | For Select: [{value, label}] |
Permissions
The permissions field declares what the competency requires from the agent it's equipped to. When an operator equips the competency, the agent must already hold those permissions — otherwise equip is rejected.
This is a demand, not a grant. The competency says "I need NetworkConnect to do my job." The agent either has it or it doesn't.
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. Validate the manifest
hoziron competency install ./my-competency/
# 2. Check skill dependencies
hoziron competency check-deps claims-intake
# 3. Install missing skills
hoziron competency install-deps claims-intake
# 4. Equip to an agent and test
hoziron competency equip claims-intake --agent my-agent
hoziron message my-agent "Test: process a new auto claim for policy #POL-2024-100"
# 5. Adjust settings
hoziron competency config claims-intake --set auto_escalate_threshold=3
Next steps
Related: