The task: block
A skill becomes a task when it declares the task: block in the SKILL.md
frontmatter. Make a task only of what someone needs to trigger: a step
reusable by other skills is a helper, and a good task is usually the
orchestration of several helpers.
---
name: task-meu-processo
description: What the skill does, in one line (used in search)
user-invocable: true
task:
label: "Meu Processo"
description: "The agent's introduction text to the user."
workspace: Financeiro
activity: Baixa de Recebimentos
model: tier-3
parameters_schema: null
parameters_sensitive: false
accepts_input_files: false
generates_output_files: false
systems:
- Kobana
features:
- What the task covers
required_secrets:
- KOBANA_ACCESS_TOKEN
endpoint: # optional
enabled: true
auth: bearer
schedules: # optional: one schedule per environment
- environment: Produção
cron: "0 9 * * 1-5"
timezone: America/Sao_Paulo
executor: # optional: executor and model override, or `inherit`
cli: claude_code
model: claude-opus-4-8
metadata: # optional: free-form object
dono: financeiro
dependencies: # optional
apt: [ffmpeg]
services: [postgres]
---
Field by field​
| Field | Type | Effect |
|---|---|---|
label | string | Name in the console. Without it, the task is created with the skill_slug as its name. |
description | string | The agent's introduction text on the task screen. |
workspace | string | Workspace name when the sync creates it. The task always stays in the plugin's workspace. See the name trap. |
activity | string | Required for the task to be created. Grouping within the workspace, matched by exact name. |
model | string | Slug of a tier (tier-3), not of an AI model. The tier defines price, executor and model. |
parameters_schema | JSON Schema or null | Validates the parameters before creating the execution. It is not decorative. |
parameters_sensitive | boolean | true encrypts the stored parameters and hides them in the interface. Use it when the run carries personal data. |
accepts_input_files | boolean | true accepts attachments at run time; the paths arrive in $INPUT_FILES. |
generates_output_files | boolean | true publishes everything the skill saves in $OUTPUT_FILES_DIR. |
systems | list of strings | Display only: the external systems the task touches. |
features | list of strings | Display only: what the task delivers. |
required_secrets | list of strings | Allowlist: only what is here reaches the execution. See Secrets. |
endpoint | { enabled, auth } | Trigger through POST /run-task/{task_id}. See Schedule, endpoint and executor. |
schedules | list | The task's schedules, one per environment. |
executor | inherit or { cli, model } | Executor and model override on top of the tier. |
metadata | object | Stored whole in the task's custom_metadata (appears in the API and in webhooks). |
conversational | boolean | true lets the person request changes after the execution finishes, in a new turn that continues the previous one. Works on both executors. See Conversational tasks. |
dependencies | { apt, services } | System packages and databases Kadu installs before the execution. Names from Kadu's list only. See dependencies. |
:::danger A wrong type is silently discarded
The sync only accepts a string where it expects a string, a boolean where it
expects a boolean and a list of strings in the lists. parameters_sensitive: "true"
(with quotes) becomes "not declared", with no error anywhere. And "not
declared", on a task that already exists, means "do not touch": the field
keeps the old value and the change does not take effect. Check "Tasks
updated" after the merge.
:::
model: the slug of a tier, not of a model​
task.model points to a tier registered in Kadu. The tier carries the
price, the executor and the AI model. Tiers in the initial registry:
| Tier | Executor | AI model |
|---|---|---|
tier-1 | goose | openrouter/openai/gpt-4.1-mini |
tier-2 | goose | openrouter/google/gemini-3.5-flash |
tier-3 | claude_code | claude-sonnet-4-6 |
tier-4 | claude_code | claude-opus-4-8 |
tier-5 | claude_code | claude-fable-5 |
Tiers may change. Confirm with Kobana before choosing a new tier.
Writing a model id (claude-sonnet-4-6) does not break the sync, but it is
not applied: a new task is created in the lowest-order tier, an existing one
stays as it is, and the result warns model "…" não é um tier ativo. Without
model, the effect is the same, with no warning.
Choose by the work: reading code, planning and review call for tier-4;
orchestration with decisions calls for tier-3. tier-1 and tier-2 switch
the executor to Goose: use them only with a skill tested on it, because
Goose's helpers and wrapper are different.
parameters_schema: actually validated​
The schema is compiled with Ajv (strict: false, with ajv-formats) and runs
against the parameters before creating the execution. A well-written schema
rejects a wrong run without spending an execution. The console also builds the
run form from it.
parameters_schema:
type: object
additionalProperties: false # rejects a parameter you did not anticipate
required:
- repo_url
properties:
repo_url:
type: string
minLength: 3
description: "owner/repo or full URL"
priority:
type: integer
enum: [0, 1, 2, 3, 4]
default: 0
additionalProperties: falseturns a typo into a run error, instead of an ignored parameter.requiredonly for what actually blocks the execution.defaultis documentation for whoever triggers the run: it does not fill in the value. Apply the default in the skill body (jq -r '.priority // 0').nullwhen the task takes no parameters at all.
dependencies: packages and databases for the execution​
The agent runs without administrator rights. A task that needs a system package or a database declares it, and Kadu installs it before the execution starts:
dependencies:
apt: [ffmpeg, poppler-utils]
services: [postgres]
Names from the list maintained by Kobana only: PDF, OCR, documents,
spreadsheets, images, audio and video, files, database clients and the
postgres, mysql, mariadb, redis and valkey services. The full list,
the rules and what to do when something is missing are in
Dependencies.
The workspace and activity name trap​
Matching is by exact name: Desenvolvimento, desenvolvimento and
Desenvolvimento (with a trailing space) are three different names.
| Effect on the sync | |
|---|---|
workspace | decides nothing for an existing task: the workspace is the plugin's. The name only names the workspace the first time it is created. |
activity | matched by exact name within the plugin's workspace. A name that does not exist creates a new activity and moves the task to it. |
A typo in activity: does not fail: an activity "Baixa de recebimentos"
appears next to "Baixa de Recebimentos", with the task inside the new one. The
sync only creates activities, never renames or deletes them, so the duplicate
stays until someone removes it.
Copy the name of the activity that already exists instead of typing it from memory. To rename an activity, rename it in Kadu first and then in the frontmatter of every skill that uses it. In the reverse order, the sync creates the new one and the tasks scatter between the two.
Real example​
The smoke task in Kobana's repository declares parameters, input and output files, a secret and the endpoint:
task:
label: "Testar orquestração"
description: "I am the platform's test task. I go through each tab of the execution and read what you attach at run time."
workspace: Kadu
activity: Teste
model: tier-3
parameters_schema:
type: object
additionalProperties: false
properties:
eco:
type: string
maxLength: 200
description: "Text returned in the Result — proves the parameter reached the execution"
falhar:
type: boolean
default: false
description: "true ends at step 6 with an error, to exercise the failure path"
parameters_sensitive: false
accepts_input_files: true
generates_output_files: true
systems:
- Kadu
features:
- "Timeline: one event at each level — thinking, info, success, warning and error"
- "Pending: creates two, with payload"
required_secrets:
- KADU_SMOKE_SECRET
endpoint:
enabled: true
auth: bearer