Skip to content

Skill-манифест

Внешние скиллы — это subprocess-исполняемые файлы, описанные файлом skill.json, помещённым в одну из allow-list директорий manager'а. Loader обходит эти директории при boot, парсит каждый skill.json и регистрирует SubprocessSkill в глобальном реестре скиллов. LLM затем видит скилл наряду со встроенными tools.

Источник истины: internal/skill/loader.go.

Layout на диске

text
/etc/ongrid/skills/                  ← one entry in $ONGRID_SKILLS_EXTERNAL_DIRS
└── disk-cleaner/
    ├── skill.json
    └── run.sh                       ← the executable

Каждый skill.json находится в вершине своей подпапки. Дерево директорий обходится рекурсивно; любой файл с именем skill.json трактуется как манифест. Несколько скиллов могут жить под одним allow-list корнем.

Схема манифеста

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"
}
ПолеТипОбязательноОписание
namestringдаSkill-ключ. Должен быть lower_snake, соответствующим [a-z0-9_]+. Становится LLM-facing именем функции.
descriptionstringдаПоказывается людям (UI) и LLM (описание функции).
schemaJSON SchemaнетСырая JSON Schema для объекта аргументов. Отсутствие = схема пустого объекта.
entrystringдаПуть к исполняемому файлу. Относительные пути резолвятся относительно директории, содержащей skill.json. Абсолютные пути должны находиться под allow-list корнем.
env_allowstring[]нетЯвный список имён env-переменных, форвардящихся ребёнку. Пустой список = никакого env (даже PATH). Добавьте "PATH" для opt-in PATH.
timeout_secondsintнетТаймаут subprocess'а. Ноль откатывается на DefaultSubprocessTimeout (30s).
classenumнетsafe (по умолчанию), mutating, dangerous. См. таксономию классов.
categorystringнетСвободная group-label. По умолчанию external. UI группирует subprocess-скиллы по этому.

Wire-протокол

Subprocess вызывается с stdin = JSON-объект аргументов, stdout = JSON-объект результата, stderr = строки логов для manager'а.

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

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

Non-zero exit-код трактуется как failure. Stderr захватывается в таймлайн событий tool-call'а, так что LLM может прочитать частичный прогресс.

Объект результата возвращается дословно LLM. Agent-ядро форматирует его как ответ tool-call'а; ожидается, что LLM рассуждает над JSON-формой.

Таксономия классов

Та же таксономия {safe, mutating, dangerous} применяется и к нативным, и к subprocess-скиллам.

КлассЧто он можетТребуемое permission persona
safeRead-only — никаких side-эффектов на хост или любую систему.read-only (любая persona)
mutatingСоздаёт / обновляет состояние. Обратимо.mutating-with-confirm или dual-sign-required
dangerousНеобратимо (удаления, рестарты, exec-arbitrary).dual-sign-required (SOP)

Поле permission_mode у persona гейтит, какие классы могут работать без подтверждения. См. формат persona агента.

Правила allow-list

Операторы конфигурируют allow-list директории через ONGRID_SKILLS_EXTERNAL_DIRS (colon- или comma-separated абсолютные пути). Loader enforce'ит их строго:

  • Каждая директория должна быть абсолютным путём. Относительные пути пропускаются с лог-строкой.
  • Несуществующие пути пропускаются (так что свежая установка без /etc/ongrid/skills boot'ит нормально).
  • entry каждого манифеста канонизируется через filepath.EvalSymlinks и проверяется, что лежит под allow-list корнем. Symlink, указывающий за пределы корня, отвергается (entry %s escapes allowlist root %s).

Sandboxing сверх этого — ответственность subprocess'а. Если скилл должен быть жёстко изолирован, запускайте его под wrapper'ом (bwrap, firejail, nsenter), указанным как entry.

Поведение 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)
  • Per-manifest валидационные сбои логируются и пропускаются. Один сломанный пак не должен блокировать boot.
  • Дублирующиеся имена пропускаются, а не ошибаются (так что redeploy, который кладёт новый манифест перед удалением старого, не крашит manager).
  • Loader возвращает количество успешно зарегистрированных скиллов. Старт manager'а non-blocking на skill-loader'е: пустая внешняя директория — это no-op.

Логирование при старте

Manager логирует одну строку на манифест:

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

Tail journalctl -u docker-compose@ongrid или docker compose logs ongrid для подтверждения, что было подхвачено.

См. также

Метаданные нативного скилла (frontmatter SKILL.md)

Встроенные скиллы, поставляемые под ./skills/, используют более богатый формат SKILL.md с YAML-frontmatter, который совместим со skill-экосистемами openclaw / claude-code. Схема определена в 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 ...

Для subprocess-скиллов, написанных третьими сторонами, предпочитайте более простой формат skill.json выше. SKILL.md — для скиллов, которые компилируются в бинарь manager'а.