Best practices
A skill's value lies in what it knows and a model would not guess: the right endpoint, the field that comes back null, the business rule that is written nowhere. The practices below come from the skills Kobana runs in production.
When writing a skill​
Verify before asserting. Run the command, call the API, read the file. Every field table, enum and error message in a skill body should have come from a real run, not from memory. When a check contradicts what you were about to write, the finding is the check.
Name the concrete case. "Kobana's MCP responds 401 to a personal token
with REST API usage: KOBANA_MCP_TOKEN must be a token with MCP
usage" is worth more than "check the token". The agent follows an example
better than a general rule.
Explain the why of every prohibition. A guardrails table with the reason next to each rule. A rule without a reason is ignored in the first rush, by the agent and by whoever edits the skill later.
| Don't | Why |
|---|---|
| Ask the user during the execution | there is no user: the execution hangs until the 60-minute limit |
Call log_http_call on every request of a scanner | thousands of lines drown the Logs tab and hide the integration calls |
Read configuration with ${VAR:-default} outside required_secrets | the default always applies, and nobody can change the value through Kadu |
Write for both modes. A skill that is useful in Claude Code runs in
local (with a person answering) and in task (in Kadu, with nobody). In
task, do not ask: record a pending item and move on. Detect the mode with
GITHUB_ACTIONS (The task body).
End with a common errors table: symptom → cause → where the solution is. It is the part that saves the most time for whoever diagnoses.
A declared parameter must be read and used. A parameter in
parameters_schema that no step consults is a bug, not documentation.
A task orchestrates; helpers do. Separate access to each external system
into small helper skills (fintera-listar-contas-a-receber,
nfeio-buscar-nota-fiscal) and let the task decide the order and what to do
with each result. The helpers are reused by other tasks and tested on their
own in Claude Code.
When changing a skill that is already a task​
- Change the frontmatter, never the folder name. Renaming creates another task.
- Update the repository documentation in the same commit: the workspace's
task table in
README.mdand the task count. An outdated README is the first place the next person gets lost. - Check the sync warnings after the merge, through the Sync button. An invalid item (cron, environment name) discards the whole list, and only the warning says so.
- Task configuration changes in the repository, not in the console.
Schedules, endpoint, executor and
metadatadeclared in thetask:block, and environments inkadu.yaml, revert to what was declared on every push.
When maintaining the Playbook​
mainis production. Work on a branch, validate in the CI sandbox and treat the merge as a deploy (Sync).- Add files by explicit path.
git add -Apicks up the.execution-result.jsonthat a local run leaves at the root and the test.env. Keep both in.gitignore. - Keep a
CLAUDE.mdat the root with the repository's rules: how skills are written, what cannot go into git, the order for provisioning a secret. It is what Claude Code reads before editing.
Language​
Write the skills, events and result in the language of whoever will read them.
An execution's events and result should follow $LOCALE, the language of
whoever triggered the run.