Skill manifest
외부 skill 은 매니저의 허용 목록 디렉터리 중 하나에 떨어뜨린 skill.json 파일로 기술되는 subprocess 실행 파일입니다. 로더는 부팅 시 해당 디렉터리들을 순회하면서 각 skill.json 을 파싱하고, 글로벌 skill 레지스트리에 SubprocessSkill 을 등록합니다. 그러면 LLM 은 그 skill 을 빌트인 도구와 나란히 보게 됩니다.
소스 오브 트루스: internal/skill/loader.go.
디스크 레이아웃
/etc/ongrid/skills/ ← one entry in $ONGRID_SKILLS_EXTERNAL_DIRS
└── disk-cleaner/
├── skill.json
└── run.sh ← the executable각 skill.json 은 자신의 서브디렉터리 최상위에 있습니다. 디렉터리 트리는 재귀적으로 순회되며, skill.json 이라는 이름의 파일은 모두 매니페스트로 취급됩니다. 같은 허용 목록 루트 아래에 여러 skill 이 살 수 있습니다.
매니페스트 스키마
{
"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"
}| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
name | string | 예 | skill 키. [a-z0-9_]+ 에 매치되는 lower_snake. LLM 노출 함수 이름이 됨. |
description | string | 예 | 사람 (UI) 과 LLM (함수 description) 에 표시. |
schema | JSON Schema | 아니오 | args 객체의 raw JSON Schema. 없으면 빈 객체 스키마. |
entry | string | 예 | 실행 파일 경로. 상대 경로는 skill.json 이 있는 디렉터리 기준. 절대 경로는 허용 목록 루트 아래에 있어야 함. |
env_allow | string[] | 아니오 | 자식에게 전달되는 env 변수 이름의 명시적 리스트. 빈 리스트 = env 가 전혀 없음 (PATH 조차도 아님). PATH 를 opt-in 하려면 "PATH" 를 추가. |
timeout_seconds | int | 아니오 | subprocess 타임아웃. 0 이면 DefaultSubprocessTimeout (30s) 으로 폴백. |
class | enum | 아니오 | safe (기본), mutating, dangerous. class 분류 참고. |
category | string | 아니오 | 자유 형식 그룹 라벨. 기본 external. UI 가 subprocess skill 을 이걸로 그룹핑. |
와이어 프로토콜
subprocess 는 stdin = JSON args 객체, stdout = JSON 결과 객체, stderr = 매니저용 로그 라인 으로 호출됩니다.
$ cat /tmp/args.json
{"path": "/var/cache", "dry_run": true}
$ run.sh < /tmp/args.json
{"freed_bytes": 1048576, "files_deleted": 17}0 이 아닌 exit 코드는 실패로 취급됩니다. stderr 은 LLM 이 부분 진행 상황을 읽을 수 있도록 도구 호출 이벤트 타임라인에 캡처됩니다.
결과 객체는 LLM 에 그대로 반환됩니다. 에이전트 커널은 그것을 도구 호출의 응답으로 포맷하며, LLM 은 JSON 모양 위에서 추론할 것을 기대받습니다.
Class 분류
같은 {safe, mutating, dangerous} 분류가 네이티브 skill 과 subprocess skill 모두에 적용됩니다.
| Class | 할 수 있는 것 | 필요한 persona 권한 |
|---|---|---|
safe | 읽기 전용 — 호스트나 어떤 시스템에도 부작용 없음. | read-only (어떤 persona 든) |
mutating | 상태 생성 / 수정. 가역. | mutating-with-confirm 또는 dual-sign-required |
dangerous | 불가역 (삭제, 재시작, exec-arbitrary). | dual-sign-required (SOP) |
persona 의 permission_mode 필드가 확인 없이 실행 가능한 클래스를 게이팅합니다. 에이전트 persona 포맷 참고.
허용 목록 규칙
운영자는 ONGRID_SKILLS_EXTERNAL_DIRS (콜론 또는 콤마 구분 절대 경로) 로 허용 목록 디렉터리를 구성합니다. 로더는 이를 엄격히 강제합니다:
- 각 디렉터리는 절대 경로여야 합니다. 상대 경로는 로그 라인과 함께 건너뜁니다.
- 존재하지 않는 경로는 건너뜁니다 (그래서
/etc/ongrid/skills가 없는 신규 설치도 잘 부팅됩니다). - 각 매니페스트의
entry는filepath.EvalSymlinks로 정규화되며 허용 목록 루트 아래에 사는지 검사됩니다. 루트 바깥을 가리키는 symlink 는 거절됩니다 (entry %s escapes allowlist root %s).
그 이상의 샌드박싱은 subprocess 의 책임입니다. skill 이 엄격히 격리되어야 한다면 wrapper (bwrap, firejail, nsenter) 를 entry 로 참조해 그 아래에서 실행하세요.
로더 동작
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)- 매니페스트별 검증 실패는 로깅 후 건너뜀. 깨진 pack 하나가 부팅을 막지 않습니다.
- 중복 이름은 에러를 내지 않고 건너뜁니다 (그래서 이전 매니페스트를 제거하기 전에 새 매니페스트를 떨어뜨리는 재배포가 매니저를 깨뜨리지 않습니다).
- 로더는 성공적으로 등록된 skill 의 개수를 반환합니다. skill 로더에 대해 매니저 기동은 non-blocking 입니다 — 비어 있는 외부 디렉터리는 no-op.
기동 시 로깅
매니저는 매니페스트당 한 줄을 로깅합니다:
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무엇이 픽업되었는지 확인하려면 journalctl -u docker-compose@ongrid 또는 docker compose logs ongrid 를 tail 하세요.
함께 보기
- Capabilities → Skills — 빌트인 skill 카탈로그.
- 에이전트 persona 포맷 — persona 가 어떤 skill 을 호출할 수 있는지 고르는 방식.
- Marketplace — skill pack 을 단위로 설치.
- REST API →
/v1/skills— 조회 및 직접 실행.
네이티브 skill 메타데이터 (SKILL.md frontmatter)
./skills/ 아래에 배포되는 빌트인 skill 들은 openclaw / claude-code skill 생태계와 상호운용되는 풍부한 YAML frontmatter 형식의 SKILL.md 를 사용합니다. 스키마는 internal/manager/biz/aiops/chatruntime/types.go 에 정의되어 있습니다:
---
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 ...제3자가 작성하는 subprocess skill 에는 위의 더 단순한 skill.json 포맷을 선호하세요. SKILL.md 는 매니저 바이너리에 컴파일되는 skill 용입니다.