Skip to content

Manifesto de skill

Skills externas são executáveis subprocesso descritos por um arquivo skill.json colocado sob um dos diretórios allow-list do manager. O loader percorre esses diretórios no boot, parseia cada skill.json, e registra um SubprocessSkill no skill registry global. O LLM então vê a skill ao lado das tools built-in.

Fonte de verdade: internal/skill/loader.go.

Layout em disco

text
/etc/ongrid/skills/                  ← uma entrada em $ONGRID_SKILLS_EXTERNAL_DIRS
└── disk-cleaner/
    ├── skill.json
    └── run.sh                       ← o executável

Cada skill.json está no topo de seu próprio subdiretório. A árvore de diretórios é percorrida recursivamente; qualquer arquivo nomeado skill.json é tratado como um manifesto. Múltiplas skills podem viver sob o mesmo allow-list root.

Schema do manifesto

json
{
  "name": "disk_cleaner",
  "description": "Free up disk by clearing stale build caches and journals.",
  "schema": {
    "type": "object",
    "properties": {
      "path":   { "type": "string", "description": "Root path to clean." },
      "dry_run": { "type": "boolean", "default": true }
    },
    "required": ["path"]
  },
  "entry": "run.sh",
  "env_allow": ["PATH", "HOME"],
  "timeout_seconds": 60,
  "class": "mutating",
  "category": "ops"
}
CampoTipoObrigatórioDescrição
namestringsimChave de skill. Precisa ser lower_snake casando [a-z0-9_]+. Vira o nome de função voltado ao LLM.
descriptionstringsimMostrada a humanos (UI) e ao LLM (descrição de função).
schemaJSON SchemanãoJSON Schema cru para o objeto args. Faltante = schema de objeto vazio.
entrystringsimPath para o executável. Paths relativos resolvem contra o diretório contendo skill.json. Paths absolutos precisam estar sob um allow-list root.
env_allowstring[]nãoLista explícita de nomes de env-var encaminhadas ao child. Lista vazia = sem env nenhuma (nem PATH). Adicione "PATH" para opt-in ao PATH.
timeout_secondsintnãoTimeout do subprocesso. Zero cai para DefaultSubprocessTimeout (30s).
classenumnãosafe (padrão), mutating, dangerous. Veja taxonomia de class.
categorystringnãoLabel de grupo free-form. Default para external. UI agrupa skills subprocess por isso.

Protocolo wire

O subprocesso é invocado com stdin = objeto JSON de args, stdout = objeto JSON de result, stderr = linhas de log para o manager.

text
$ cat /tmp/args.json
{"path": "/var/cache", "dry_run": true}

$ run.sh < /tmp/args.json
{"freed_bytes": 1048576, "files_deleted": 17}

Exit code não-zero é tratado como falha. Stderr é capturado na timeline de event de tool-call para que o LLM possa ler progresso parcial.

O objeto de result é retornado verbatim ao LLM. O agent kernel o formata como a response da chamada de tool; o LLM é esperado raciocinar sobre o formato JSON.

Taxonomia de class

A mesma taxonomia {safe, mutating, dangerous} aplica a skills nativas e skills subprocess.

ClassO que pode fazerPermissão de persona requerida
safeRead-only — sem efeitos colaterais no host ou em qualquer sistema.read-only (qualquer persona)
mutatingCria / atualiza estado. Reversível.mutating-with-confirm ou dual-sign-required
dangerousIrreversível (deleta, reinicia, exec-arbitrário).dual-sign-required (SOP)

O campo permission_mode da persona gateia quais classes podem rodar sem confirmação. Veja Formato de persona de agent.

Regras de allow-list

Operadores configuram diretórios allow-list via ONGRID_SKILLS_EXTERNAL_DIRS (paths absolutos separados por dois-pontos ou vírgula). O loader os impõe estritamente:

  • Cada diretório precisa ser um path absoluto. Paths relativos são pulados com linha de log.
  • Paths não-existentes são pulados (para que uma instalação fresca sem /etc/ongrid/skills boote bem).
  • O entry de cada manifesto é canonicalizado com filepath.EvalSymlinks e checado para viver sob o allow-list root. Um symlink que aponta fora do root é rejeitado (entry %s escapes allowlist root %s).

Sandboxing além disso é responsabilidade do subprocesso. Se a skill precisa ser apertadamente contida, rode sob um wrapper (bwrap, firejail, nsenter) referenciado como o entry.

Comportamento do loader

text
LoadDirs(cfg)
  for each dir in cfg.Dirs:
    filepath.Walk(dir)
      for each skill.json found:
        parseManifest(path)
        buildSubprocessSkill(manifest, path, root)
        if skill already registered: skip (log line)
        else Register(skill)
  • Falhas de validação por-manifesto são logadas e puladas. Um pack quebrado não deve bloquear boot.
  • Nomes duplicados são pulados em vez de errar (para que um redeploy que coloque um manifesto novo antes de remover o antigo não crashe o manager).
  • Loader retorna a contagem de skills registradas com sucesso. Startup do manager é não-blocante no loader de skill: um dir externo vazio é um no-op.

Log no startup

O manager loga uma linha por manifesto:

text
skill loader: registered subprocess skill "disk_cleaner" from /etc/ongrid/skills/disk-cleaner/skill.json
skill loader: skill "broken_one" already registered, skipping /etc/ongrid/skills/broken-one/skill.json
skill loader: parse /etc/ongrid/skills/typo/skill.json: invalid character ',' looking for beginning of object key
skill loader: build "bad_path": entry /tmp/escape.sh escapes allowlist root /etc/ongrid/skills

Faça tail em journalctl -u docker-compose@ongrid ou docker compose logs ongrid para confirmar o que foi pego.

Veja também

Metadados de skill nativa (frontmatter SKILL.md)

Skills built-in distribuídas sob ./skills/ usam um formato SKILL.md mais rico com YAML-frontmatter que interopera com os ecossistemas de skill openclaw / claude-code. O schema está definido em internal/manager/biz/aiops/chatruntime/types.go:

yaml
---
name: query_promql
description: Run a PromQL query and return the result matrix.
when_to_use: When the user asks for current or recent metric values.
activation:
  mode: always
metadata:
  os: [linux, darwin]
  requires:
    bins: []
    config: []
  ongrid:
    scope: manager
    activation:
      mode: always
tools:
  - name: query_promql
    impl: builtin:prom.QueryPromQL
    class: read
    description: Execute a PromQL query and return the matrix.
---

# query_promql

PromQL query tool ...

Para skills subprocess escritas por terceiros, prefira o formato skill.json mais simples acima. SKILL.md é para skills que compilam no binário do manager.