Files
DBAdmin/inbox/skill_doc.md
T
2026-05-18 06:40:19 +00:00

883 lines
41 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Pewnie — poniżej masz **dwie gotowe, “produkcyjne” wersje SKILL.md dopasowane pod OpenClaw runtime**:
1. **LLMonly** (bez narzędzi)
2. **Toolfirst** (narzędzia jako domyślny silnik, LLM tylko do planu/formatowania)
Dodatkowo dorzucam **gating (load-time)**, **slash-command**, oraz przykładowe **wpisy do `~/.openclaw/openclaw.json`** + rekomendowane **polityki narzędzi (`tools.profile/allow/deny`)**. Wszystko zgodne z tym, jak OpenClaw ładuje i filtruje skille. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/creating-skills), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools)
***
# 0) Kontekst OpenClaw (ważne, bo wpływa na projekt)
* Skill w OpenClaw to **katalog z plikiem `SKILL.md`** (YAML frontmatter + instrukcje w Markdown). [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/creating-skills), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
* Skille są ładowane m.in. z **`<workspace>/skills`** oraz **`~/.openclaw/skills`**; a gdy nazwy się pokrywają, **workspace wygrywa** nad lokalnym i bundlowanym. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
* OpenClaw potrafi **filtrować skille przy ładowaniu** na podstawie `metadata.openclaw.requires` (np. wymagane binarki/env/config). [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
* Frontmatter ma ograniczenia: parser wspiera **jednolinijkowe klucze**, a `metadata` powinno być **jednolinijkowym JSON**. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
* Dostępność i bezpieczeństwo narzędzi kontrolujesz w `openclaw.json` przez `tools.profile`, `tools.allow`, `tools.deny` i grupy `group:*`. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools)
***
# 1) Struktura katalogu (dla obu wariantów)
> Minimalnie:
<workspace>/skills/my-custom-skill-llm-only/SKILL.md
<workspace>/skills/my-custom-skill-tool-first/SKILL.md
OpenClaw odkryje te katalogi i zindeksuje `SKILL.md` (po restarcie gateway albo “refresh skills”). [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/creating-skills), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
***
# 2) Wersja A — **LLMonly** (zero narzędzi, maksymalna przewidywalność)
### Kiedy to ma sens?
* gdy chcesz **czystą logikę/pisanie/transformację tekstu**
* gdy chcesz **zero sideeffectów** i brak ryzyka toolabuse
* gdy wolisz “prompt jako skill” + ustandaryzowany output
### `SKILL.md` (LLMonly)
```markdown
---
name: my-custom-skill-llm-only
description: Deterministic LLM-only skill. No tools. Produces structured output for [topic].
user-invocable: true
disable-model-invocation: false
metadata: {"openclaw":{"emoji":"🧠","os":["darwin","linux","win32"],"always":true}}
---
# My Custom Skill (LLM-only)
## Purpose (single responsibility)
Zamień nieuporządkowaną prośbę użytkownika na **ustrukturyzowaną odpowiedź** dla: **[topic]**.
## Hard rules (MUST)
- **NIE używaj żadnych narzędzi** (read/write/exec/web_* / browser / nodes / cron).
- Jeśli brakuje danych: **zadaj maksymalnie 3 pytania doprecyzowujące**.
- Brak zgadywania faktów. Brak “dopowiadania” danych wejściowych.
- Zachowaj deterministyczny format wyjścia (poniżej).
## When to use
Użyj tylko gdy:
- użytkownik chce: analizę/plan/porównanie/rewriting/checklistę/specyfikację dla **[topic]**
Nie używaj gdy:
- potrzebne jest pobranie danych z pliku/WWW/systemu albo jakiekolwiek działanie w środowisku.
## Output format (strict)
Zwróć odpowiedź zawsze w tym układzie:
### TL;DR
- ...
### Inputs (what I used)
- ...
### Result
- ...
### Assumptions
- ...
### Next actions (max 5)
1. ...
2. ...
## Quality checklist (internal)
- Czy output ma TL;DR + Inputs + Result + Assumptions + Next actions?
- Czy nie ma w nim “narzędzi” ani sugestii wykonania poleceń?
- Czy nie ma halucynacji faktów?
```
**Dlaczego te pola?**
* `user-invocable` / `disable-model-invocation` to opcjonalne klucze frontmatter (OpenClaw) — przydatne do ekspozycji jako slash command albo ukrycia przed automatycznym doborem. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
* `metadata` jako jednolinijkowy JSON i `always`/`os` są zgodne z mechanizmem gatingu. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
***
## Zalecana polityka narzędzi (żeby LLMonly był naprawdę “no-tools”)
W `~/.openclaw/openclaw.json` ustaw np. profil minimalny (albo jawne deny):
```json5
{
"tools": {
"profile": "minimal",
"deny": ["group:fs", "group:runtime", "group:web", "group:ui", "group:nodes", "group:automation"]
}
}
```
* `tools.profile` i grupy `group:*` są wspierane i opisane w dokumentacji narzędzi. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools)
> Jeśli chcesz, możesz to ograniczyć per-agent (np. tylko dla “writer” agenta), ale powyższe jest najprostsze.
***
# 3) Wersja B — **Toolfirst** (narzędzia domyślnie, LLM tylko do planu + interpretacji)
### Kiedy to ma sens?
* gdy skill ma **pobierać dane** (pliki/WWW), **uruchamiać komendy**, **zapisywać artefakty**
* gdy chcesz przewidywalny pipeline: preflight → gather → execute → output
* gdy chcesz *mniej halucynacji*, bo fakty biorą się z tool outputów
***
## `SKILL.md` (Toolfirst)
> Uwaga: nazwy narzędzi i grupy są zgodne z listą OpenClaw tools (np. `read`, `write`, `exec`, `web_fetch`, `web_search`). [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/web)
```markdown
---
name: my-custom-skill-tool-first
description: Tool-first skill for [topic]. Fetches/reads inputs, executes deterministic steps, writes auditable artifacts.
user-invocable: true
metadata: {"openclaw":{"emoji":"🛠️","requires":{"config":["tools.web.fetch.enabled"],"env":["MY_SKILL_API_KEY"],"bins":["jq"]},"primaryEnv":"MY_SKILL_API_KEY"}}
---
# My Custom Skill (Tool-first)
## Purpose (single responsibility)
Wykonaj workflow dla **[topic]** w sposób audytowalny:
1) zbierz dane → 2) przetwórz → 3) zapisz wynik.
## Load-time gates (runtime safety)
Ten skill ma być aktywny tylko gdy:
- `MY_SKILL_API_KEY` jest dostępny (env lub skills.entries.*.apiKey),
- `tools.web.fetch.enabled` jest włączone,
- binarka `jq` istnieje na PATH.
(Jeśli w sandboxie — binarka musi istnieć także w kontenerze.)
## Tools allowed (prefer)
- `read` / `write` (artefakty)
- `web_fetch` (zawartość stron)
- `web_search` (tylko jeśli user nie podał URL)
- `exec` (tylko deterministyczne polecenia, bez wstrzykiwania parametrów od usera)
## Guardrails (MUST)
- Nie uruchamiaj `exec` z argumentami sklejanymi z surowego inputu użytkownika (ryzyko injection).
- Zanim użyjesz narzędzi: wykonaj Pre-flight.
- Zawsze zapisuj artefakty w `{baseDir}/runs/<timestamp>/...` (bezpieczny scope).
- Jeśli jakikolwiek krok nie ma danych → przerwij i poproś o doprecyzowanie.
---
## Execution (deterministic)
### Step 0 — Pre-flight (fail-fast)
1. Waliduj input (topic, opcje).
2. Sprawdź dostępność narzędzi wymaganych w `requires`.
3. Ustaw `runId = YYYYMMDD-HHMMSS` i katalog:
`{baseDir}/runs/{runId}/`
### Step 1 — Gather (minimum necessary)
- Jeśli user podał URL → `web_fetch(url=...)`
- Jeśli nie podał URL → `web_search(query=...)` → wybierz 13 wyniki → `web_fetch(...)`
- Jeśli user podał plik ścieżką → `read(path=...)`
Zapisz:
- `{baseDir}/runs/{runId}/inputs.json`
- `{baseDir}/runs/{runId}/sources.md`
### Step 2 — Transform (tool-first)
- Preferuj deterministyczne przetwarzanie:
- proste ekstrakcje i walidacje przez `exec` (np. `jq`) tylko na danych z własnych plików w katalogu run.
- LLM używaj tylko do:
- ułożenia planu
- formatowania końcowego raportu
Zapisz:
- `{baseDir}/runs/{runId}/result.raw`
### Step 3 — Output (auditable)
Wygeneruj raport w Markdown:
- `{baseDir}/runs/{runId}/report.md`
Raport MA zawierać:
- TL;DR
- Źródła (linki/fragmenty)
- Kroki wykonania (logicznie, bez sekretów)
- Artefakty (ścieżki)
Na końcu zwróć użytkownikowi:
- krótką odpowiedź + link/ścieżkę do report.md
```
### Dlaczego takie `metadata.openclaw.requires`?
* `requires.bins/env/config` to dokładnie ten mechanizm, którym OpenClaw filtruje skille przy ładowaniu. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
* `primaryEnv` wiąże się z wygodnym `skills.entries.<name>.apiKey` w configu. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
* `{baseDir}` to wspierany placeholder do referencji folderu skilla. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
***
## Zalecana konfiguracja `skills.entries` (openclaw\.json)
```json5
{
"skills": {
"entries": {
"my-custom-skill-tool-first": {
"enabled": true,
"apiKey": { "source": "env", "provider": "default", "id": "MY_SKILL_API_KEY" },
"env": {
"MY_SKILL_API_KEY": "REDACTED"
},
"config": {
"maxRetries": 2,
"maxSources": 3
}
}
}
}
}
```
* `skills.entries.*.env`, `skills.entries.*.apiKey` i `skills.entries.*.config` są wspierane jako override per-skill. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
***
## Zalecana polityka narzędzi dla Toolfirst (żeby działał i był bezpieczny)
```json5
{
"tools": {
"profile": "coding",
"allow": ["group:fs", "group:web", "group:runtime"],
"deny": ["browser", "canvas", "nodes", "cron"]
}
}
```
* Profile (`coding`) i grupy (`group:fs`, `group:web`, `group:runtime`) są częścią mechanizmu policy w OpenClaw. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools)
* `web_fetch` i `web_search` to wbudowane web narzędzia (bez JS; do JSheavy stron jest `browser`). [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/web), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools)
***
# 4) Bonus: “hybryda” sterowana komendą (szybki slash → tool dispatch)
Jeśli chcesz, żeby komenda **omijała model** i wywoływała bezpośrednio narzędzie (np. do “/my-skill fetch …”), możesz użyć `command-dispatch: tool` + `command-tool`.
To jest super do operacji typu “zrób X jednym toolcall”. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
***
# 5) Dwa krótkie wybory architektoniczne (żebyś nie wpadł w typowe pułapki)
### LLMonly
✅ przewidywalne, zero sideeffectów, tanie w utrzymaniu
❌ nie pobierze danych z zewnątrz, nie zapisze plików (chyba że pozwolisz narzędzia)
### Toolfirst
✅ minimalizuje halucynacje, audytowalne artefakty, pipeline “jak w produkcji”
❌ wymaga dobrych guardrails i policy (szczególnie dla `exec`) [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools)
***
## Pytanie, które pozwoli mi dopiąć to “na gotowo” (bez długiej wymiany)
Jaki jest **konkretny cel** Twojego skilla w praktyce?
Daj 1 zdanie w stylu:
* “Zbiera dane z URL + robi raport”
* “Czyta logi / pliki i generuje podsumowanie”
* “Uruchamia komendy diagnostyczne (DB/Splunk/SQL) i zapisuje wynik”
…i wtedy dopasuję Ci:
* dokładne `requires.config` pod Twoje narzędzia,
* strukturę artefaktów,
* i bezpieczne allowlisty dla `exec` (jeśli w ogóle ma być).
Jasne — poniżej masz **wersję hybrydową SKILL.md dla OpenClaw**, która łączy:
1. **tryb “agentowy” (LLM + toolfirst)** w normalnej rozmowie
2. **tryb “komendowy” (/… → direct tool dispatch)** dla deterministycznych akcji ze slash command
To jest zgodne z tym, jak OpenClaw ładuje skille z katalogu z `SKILL.md` (YAML frontmatter + Markdown) i jak działa gating (`metadata.openclaw.requires`) oraz obsługa slash commands (`user-invocable`, `command-dispatch`, `command-tool`, `command-arg-mode`). [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/creating-skills), [\[moely.ai\]](https://www.moely.ai/resources/openclaw-skills-extension-design)
> **Uwaga praktyczna:** Direct tool dispatch wymaga, żeby wskazany tool akceptował parametry przekazywane przez dispatcher (`{ command, commandName, skillName }`). OpenClaw opisuje to wprost.
> Jeśli Twoja instalacja ma **ściśle walidowane schematy narzędzi** i wywali się na “nadmiarowych polach”, daję też wariant “bez bypassu” (slash dalej wybiera skill, ale przez LLM) w sekcji **Plan B**. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[moely.ai\]](https://www.moely.ai/resources/openclaw-skills-extension-design)
***
## ✅ 1) Hybrydowy `SKILL.md` (Toolfirst + Slash direct-dispatch)
Wklej jako:
`<workspace>/skills/my-custom-skill-hybrid/SKILL.md`
(Workspace ma najwyższy priorytet ładowania względem `~/.openclaw/skills` i bundli). [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/creating-skills)
```markdown
---
name: my-custom-skill-hybrid
description: Hybrid skill: tool-first in chat, optional deterministic slash dispatch (bypass model) for quick actions.
user-invocable: true
disable-model-invocation: false
command-dispatch: tool
command-tool: exec
command-arg-mode: raw
metadata: {"openclaw":{"emoji":"🧩","os":["darwin","linux","win32"],"requires":{"config":["tools.exec.enabled"],"bins":["jq"]}}}
---
# My Custom Skill (HYBRID)
Ten skill ma **dwa tryby pracy**:
## Mode A — Chat / Agent mode (default)
Gdy użytkownik opisuje problem normalnie, skill działa **tool-first**:
- zbierz dane (read/web_fetch/web_search)
- przetwórz deterministycznie (preferuj narzędzia)
- dopiero na końcu użyj LLM do formatowania raportu
## Mode B — Slash / Deterministic mode (bypass model)
Gdy użytkownik użyje komendy slash dla tego skilla, OpenClaw ma **ominiąć model**
i wywołać wskazane narzędzie bezpośrednio (command-dispatch: tool).
W tym trybie parametr `args` trafia jako `command` do toola.
> Komenda jest przekazywana jako:
> { command: "<raw args>", commandName: "<slash>", skillName: "<skill>" }.
---
## Safety & Guardrails (MANDATORY)
- Nigdy nie wykonuj poleceń destrukcyjnych (rm -rf, format, wipe, itp.).
- Nie uruchamiaj poleceń z sekretami w treści.
- Jeśli w Mode A potrzebujesz `exec`, to:
- używaj allowlisty komend,
- nie sklejaj argumentów z “surowego” inputu użytkownika.
- Artefakty zapisuj wyłącznie w `{baseDir}/runs/<runId>/`.
---
## When to Use
Użyj, gdy użytkownik chce:
- zebrać dane z pliku/URL i zrobić raport / analizę dla [topic]
- albo wykonać szybkie, deterministyczne akcje komendą (Mode B)
Nie używaj, gdy:
- zadanie wymaga browser logowania/JS-heavy — wtedy preferuj browser tool (poza tym skillem).
---
## Execution (Mode A — tool-first)
### Step 0: Pre-flight
1) Ustal `runId = YYYYMMDD-HHMMSS`.
2) Sprawdź, czy masz minimalne dane wejściowe (topic / źródło / zakres).
3) Jeśli braki → max 3 pytania doprecyzowujące.
### Step 1: Gather
- Jeśli user podał plik → `read`
- Jeśli podał URL → `web_fetch`
- Jeśli nie podał źródła → `web_search` (max 3 wyniki) → `web_fetch`
Zapisz:
- `{baseDir}/runs/{runId}/inputs.json`
- `{baseDir}/runs/{runId}/sources.md`
### Step 2: Transform
- Preferuj narzędzia i deterministykę.
- Jeśli musisz, użyj `exec` tylko dla bezpiecznych transformacji na plikach z katalogu run.
- LLM wyłącznie do: streszczenia, formatowania, wyjaśnienia.
Zapisz:
- `{baseDir}/runs/{runId}/result.raw`
### Step 3: Output
Wygeneruj `{baseDir}/runs/{runId}/report.md` zawierający:
- TL;DR
- Źródła i cytowane fragmenty
- Kroki wykonania (bez sekretów)
- Artefakty (ścieżki)
---
## Slash usage (Mode B — bypass model)
### /my-custom-skill-hybrid <raw>
Przykłady (bezpieczne, read-only):
- `/my-custom-skill-hybrid echo "hello"`
- `/my-custom-skill-hybrid jq --version`
Zasady:
- traktuj to jako tryb “operator executes a command”
- jeśli komenda wygląda na destrukcyjną → przerwij i poproś o potwierdzenie poza trybem bypass
```
### Dlaczego to jest “OpenClawnative”?
* Skill jako katalog z `SKILL.md` + frontmatter jest standardem OpenClaw. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/creating-skills), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
* `metadata.openclaw.requires` (bins/config/os) to mechanizm **loadtime gating**. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[moely.ai\]](https://www.moely.ai/resources/openclaw-skills-extension-design)
* `user-invocable`, `command-dispatch: tool`, `command-tool`, `command-arg-mode` to oficjalnie opisane pola dla komend i bypassu. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[moely.ai\]](https://www.moely.ai/resources/openclaw-skills-extension-design)
* `exec` jest narzędziem do uruchamiania komend, kontrolowanym politykami narzędzi. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools)
***
## ✅ 2) Konfiguracja `openclaw.json` (narzędzia + skill entry)
### a) Bezpieczna polityka narzędzi (dla hybrydy)
Poniżej ustawiasz profil i allow/deny (OpenClaw wspiera `tools.profile`, `tools.allow`, `tools.deny` i grupy). [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools)
```json5
{
"tools": {
"profile": "coding",
"allow": ["group:fs", "group:web", "group:runtime"],
"deny": ["browser", "canvas", "nodes", "cron"]
},
"skills": {
"entries": {
"my-custom-skill-hybrid": {
"enabled": true,
"config": {
"maxSources": 3,
"maxRetries": 2
}
}
}
}
}
```
***
# 🔧 Plan B (jeśli direct-dispatch nie działa w Twojej instalacji)
W części wdrożeń bywa, że komendy skillowe (w tym `command-dispatch: tool`) nie odpalają się jak trzeba zależnie od wersji/konfiguracji (widziano przypadek zależności od aliasów modeli). [\[github.com\]](https://github.com/openclaw/openclaw/issues/25239)
**Wtedy zrób hybrydę bez bypassu:**
* Usuń z frontmatter:
* `command-dispatch`, `command-tool`, `command-arg-mode`
* Zostaw `user-invocable: true`
* A w treści skilla dodaj regułę:
* “Jeśli użytkownik wywoła skill ze slash command i poda argumenty, traktuj je jako tryb komendowy, ale nadal przejdź przez Pre-flight i guardrails.”
To nadal daje **dwa tryby**, tylko Mode B idzie przez LLM (mniej deterministycznie, ale bardziej kompatybilnie). [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools)
***
# Następny krok (żeby to było “idealnie pod Ciebie”)
W tej chwili hybryda ma Mode B ustawiony na `exec` (bo to najprostszy “tool dispatch”).
Powiedz mi w 1 zdaniu: **co Mode B ma robić w Twoim realnym use-case?** [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
Przykłady:
* “/skill diag” → zebrać statusy i zapisać report
* “/skill fetch <url>” → pobrać stronę i znormalizować do markdown
* “/skill sqlcheck” → odpalić kilka read-only poleceń diagnostycznych
A ja dopasuję:
* bezpieczną allowlistę komend (albo całkiem wyeliminuję `exec`),
* parametry “raw args” i format,
* oraz gating (`requires.config/env/bins`) pod Twoje runtime. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools)
Pewnie — pokażę Ci **jak wygląda rozbicie na “skill (orchestrator) + subskille” w OpenClaw** oraz dorzucę **allowlistę komend** (dla `exec`) tak, żeby dało się to utrzymać i nie otworzyć sobie drzwi na commandinjection. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model), [\[deepwiki.com\]](https://deepwiki.com/openclaw/openclaw/6.4-skills-system)
> **Ważna uwaga o architekturze w OpenClaw:** “subskille” to po prostu **osobne skille** (oddzielne katalogi z `SKILL.md`), które agent wybiera zależnie od intencji. Orchestrator nie “wywołuje” ich jak funkcji w kodzie, ale **kieruje agentem** (instrukcjami) żeby użył właściwego sub-skilla dla danego kroku. OpenClaw ładuje i filtruje skille (gating), a potem wstrzykuje ich opis do promptu, na podstawie którego model decyduje, którego użyć. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[deepwiki.com\]](https://deepwiki.com/openclaw/openclaw/6.4-skills-system)
***
## 1) Jak to będzie wyglądać — struktura katalogów (suite: skill + subskille)
Skille w OpenClaw to **katalog + `SKILL.md`**; najlepiej trzymać to w `<workspace>/skills`, bo ma najwyższy priorytet nad `~/.openclaw/skills` i bundlami. [\[deepwiki.com\]](https://deepwiki.com/openclaw/openclaw/6.4-skills-system), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
Przykładowa “paczka” (suite):
<workspace>/skills/
my-suite-orchestrator/
SKILL.md
my-suite-gather-web/
SKILL.md
my-suite-gather-files/
SKILL.md
my-suite-transform/
SKILL.md
my-suite-report/
SKILL.md
my-suite-quickfetch/ # opcjonalny "hybrydowy" slash bypass (bezpieczny)
SKILL.md
* **orchestrator**: routuje do sub-skilli + trzyma wspólne guardrails i spójny format artefaktów. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
* **gather-\***: izolują pobieranie danych (WWW / pliki). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model), [\[deepwiki.com\]](https://deepwiki.com/miaoxworld/OpenClawInstaller/5.3-creating-custom-skills)
* **transform**: deterministyczne przetwarzanie + allowlista `exec`. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
* **report**: format i finalny raport. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
* **quickfetch**: jeśli chcesz **prawdziwy “hybrydowy” bypass** bez ryzyka (dispatch do `web_fetch`, a nie do `exec`). `web_fetch` jest z natury “bezpieczniejszy” niż `exec`, bo nie uruchamia poleceń, tylko pobiera URL i ekstrahuje treść. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model), [\[deepwiki.com\]](https://deepwiki.com/miaoxworld/OpenClawInstaller/5.3-creating-custom-skills)
***
## 2) Skill #1 — Orchestrator (główny “suite skill”)
**Cel:** jeden skill, który:
* wybiera odpowiedni sub-skill,
* pilnuje spójnej struktury `runs/<runId>/`,
* pilnuje zasad bezpieczeństwa i “kiedy exec jest w ogóle dozwolony”. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
`<workspace>/skills/my-suite-orchestrator/SKILL.md`
```markdown
---
name: my-suite-orchestrator
description: Orchestrates the suite: routes to sub-skills, enforces guardrails, and produces auditable outputs.
user-invocable: true
metadata: {"openclaw":{"emoji":"🧭","always":true}}
---
# My Suite — Orchestrator
## Responsibility (single)
Zarządzaj wykonaniem zadania: wybierz właściwy sub-skill, utrzymaj porządek artefaktów i guardrails.
## Routing rules (deterministic)
- Jeśli źródło to URL / WWW → użyj **my-suite-gather-web**
- Jeśli źródło to plik/ścieżka → użyj **my-suite-gather-files**
- Jeśli trzeba przetworzyć/oczyścić dane → użyj **my-suite-transform**
- Jeśli trzeba złożyć wynik w raport → użyj **my-suite-report**
## Global guardrails (MUST)
- Preferuj narzędzia “read-only” i web tools (web_fetch/web_search) nad exec.
- `exec` tylko gdy:
1) to konieczne,
2) pasuje do allowlisty z my-suite-transform,
3) dotyczy wyłącznie plików w `{baseDir}/runs/<runId>/`.
- Artefakty zapisuj w `{baseDir}/runs/<runId>/...`
- Jeśli brakuje danych → max 3 pytania doprecyzowujące, potem stop.
## Output contract
Zawsze zwróć:
- TL;DR
- Co było wejściem
- Co powstało (artefakty i ścieżki)
- Następne kroki
```
**Dlaczego tak?** Orchestrator wykorzystuje fakt, że OpenClaw “podaje” modelowi listę dostępnych skilli i narzędzi, więc routing robimy instrukcjami (deterministycznie). [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## 3) Sub-skill: Gather Web (web\_search + web\_fetch)
`<workspace>/skills/my-suite-gather-web/SKILL.md`
```markdown
---
name: my-suite-gather-web
description: Fetches sources from the web. Uses web_search when needed, then web_fetch for extraction.
user-invocable: false
metadata: {"openclaw":{"emoji":"🌐","requires":{"config":["tools.web.fetch.enabled"]}}}
---
# Gather Web
## When to use
- Użytkownik podał URL lub trzeba znaleźć źródła w WWW.
## Steps
1) Jeśli jest URL → `web_fetch(url=..., extractMode="markdown")`
2) Jeśli brak URL → `web_search(query=..., count=3)` → wybierz 13 wyniki → `web_fetch(...)`
## Artifacts
Zapisz do:
- `{baseDir}/runs/<runId>/sources.md` (linki + krótkie ekstrakty)
- `{baseDir}/runs/<runId>/inputs.json` (metadane wejścia)
```
`web_search` i `web_fetch` są oficjalnymi web toolami w OpenClaw (wyszukiwanie + fetch bez JS). [\[deepwiki.com\]](https://deepwiki.com/miaoxworld/OpenClawInstaller/5.3-creating-custom-skills), [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## 4) Sub-skill: Gather Files (read)
`<workspace>/skills/my-suite-gather-files/SKILL.md`
```markdown
---
name: my-suite-gather-files
description: Loads input from local files safely and stores normalized copies in the run folder.
user-invocable: false
metadata: {"openclaw":{"emoji":"📁","requires":{"config":["group:fs"]}}}
---
# Gather Files
## When to use
- Użytkownik wskazuje plik/ścieżkę lub potrzebujesz odczytać artefakt z wcześniejszego run.
## Steps
1) Użyj `read(path=...)` na wejściu.
2) Skopiuj/znormalizuj treść do `{baseDir}/runs/<runId>/input.txt` (bez modyfikowania oryginału).
## Artifacts
- `{baseDir}/runs/<runId>/input.txt`
- `{baseDir}/runs/<runId>/inputs.json`
```
Narzędzia plikowe (`read/write/edit/...`) są grupowane i kontrolowane politykami tooli w OpenClaw (`group:fs`). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## 5) Sub-skill: Transform (TU dodajemy allowlistę komend)
To jest miejsce, gdzie robisz “bezpieczny runtime” dla `exec`. `exec` w OpenClaw to narzędzie do uruchamiania komend w workspace (z parametrami m.in. `command`, `timeout`, `security`). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
`<workspace>/skills/my-suite-transform/SKILL.md`
```markdown
---
name: my-suite-transform
description: Deterministic transformations with a strict command allowlist (exec is optional and constrained).
user-invocable: false
metadata: {"openclaw":{"emoji":"🧪","requires":{"config":["group:runtime"],"bins":["jq"]}}}
---
# Transform (Allowlisted exec)
## Golden rule
Preferuj transformacje bez `exec`. Jeśli `exec` jest potrzebny → tylko allowlista poniżej.
## Command allowlist (STRICT)
Dozwolone są WYŁĄCZNIE te komendy (dokładne wzorce):
1) `jq --version`
2) `jq -c . <INPUT >OUTPUT`
3) `jq -r . <INPUT >OUTPUT`
4) `head -n <N> <INPUT`
5) `tail -n <N> <INPUT`
6) `wc -l <INPUT`
7) `grep -n "<literal>" <INPUT`
8) `sed -n '<start>,<end>p' <INPUT`
### Constraints (MUST)
- `<INPUT>` i `<OUTPUT>` MUSZĄ być ścieżkami pod `{baseDir}/runs/<runId>/`
- `<N>` to liczba 1..500
- `"<literal>"` nie może zawierać znaków: `; | & $ \` ( ) { }`
- Zakaz: `rm`, `mv`, `cp` poza run, `curl`, `wget`, `ssh`, `sudo`, `chmod`, `chown`, `dd`, `mkfs`, `> /dev/*` itd.
## Execution steps
1) Waliduj, czy polecenie pasuje do allowlisty i constraintów.
2) Jeśli nie pasuje → przerwij i zaproponuj alternatywę bez exec.
3) Jeśli pasuje → uruchom `exec` tylko na plikach w katalogu run.
4) Wynik zapisz do:
- `{baseDir}/runs/<runId>/transform.log`
- `{baseDir}/runs/<runId>/<output files>`
## Why this exists
Zapobiega command injection i ogranicza skutki błędów do sandboxowego katalogu run.
```
### Dlaczego allowlista w SKILL.md ma sens?
Bo w OpenClaw to model wybiera i parametryzuje toolcall (np. `exec(command=...)`), a Ty chcesz mu **zawęzić przestrzeń decyzji** do znanych, bezpiecznych wzorców. Narzędzie `exec` jest potężne, więc guardrails muszą być twarde. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## 6) Sub-skill: Report (formatowanie i final)
`<workspace>/skills/my-suite-report/SKILL.md`
```markdown
---
name: my-suite-report
description: Produces the final report.md from gathered/transformed artifacts. No exec.
user-invocable: false
metadata: {"openclaw":{"emoji":"📝","always":true}}
---
# Report
## Inputs
- `{baseDir}/runs/<runId>/sources.md` i/lub `input.txt`
- `{baseDir}/runs/<runId>/result.raw` (jeśli istnieje)
- `transform.log` (opcjonalnie)
## Output
Zapisz:
- `{baseDir}/runs/<runId>/report.md`
Format report.md:
- TL;DR
- Evidence (źródła, linki, fragmenty)
- Steps taken (bez sekretów)
- Artifacts (ścieżki)
- Next actions (max 5)
```
***
## 7) Hybryda: “quick” slash bypass (bezpieczny) — opcjonalnie 📦
Jeśli nadal chcesz “hybrydę” w sensie **slash command → direct tool dispatch**, to **nie dispatchuj do `exec`** (bo omijasz model, więc omijasz allowlistę!). Zamiast tego zrób osobny “quickfetch” dispatchujący do `web_fetch`. Mechanizm `command-dispatch: tool` + `command-tool` jest wspierany. [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
`<workspace>/skills/my-suite-quickfetch/SKILL.md`
```markdown
---
name: my-suite-quickfetch
description: Slash-safe quick fetch: bypass model and run web_fetch directly on provided URL.
user-invocable: true
command-dispatch: tool
command-tool: web_fetch
command-arg-mode: raw
metadata: {"openclaw":{"emoji":"⚡","requires":{"config":["tools.web.fetch.enabled"]}}}
---
# QuickFetch (slash)
Usage:
- `/my-suite-quickfetch https://example.com`
Notes:
- This bypasses the model and dispatches to web_fetch.
- Provide a single URL as the raw args string.
```
`web_fetch` jest narzędziem do pobrania i ekstrakcji treści (bez JS), więc jako bypass jest dużo mniej ryzykowne niż `exec`. [\[deepwiki.com\]](https://deepwiki.com/miaoxworld/OpenClawInstaller/5.3-creating-custom-skills), [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
# 8) Konfiguracja narzędzi (tools policy) — minimalny “safe” zestaw
OpenClaw pozwala ustawić bazową politykę przez `tools.profile` oraz `tools.allow/deny` i grupy (`group:fs`, `group:web`, `group:runtime`). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
Przykład “suite-friendly” (umożliwia pliki+web+exec, ale blokuje UI/nodes/cron):
```json5
{
"tools": {
"profile": "coding",
"allow": ["group:fs", "group:web", "group:runtime"],
"deny": ["browser", "canvas", "nodes", "cron"]
}
}
```
***
# 9) Co dostajesz dzięki takiemu rozbiciu?
**Mniej halucynacji** (gather i transform to narzędzia, a nie “zgadywanie”).
**Mniejszy prompt** per skill (subskille są węższe i prostsze).
**Łatwiejszy audyt** (artefakty w jednym run folderze).
**Bezpieczniejsze `exec`** dzięki allowliście + constraintom na ścieżki.
**“Hybryda”**: szybki slash do bezpiecznego toola (`web_fetch`) + pełny agentowy pipeline w rozmowie. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model), [\[deepwiki.com\]](https://deepwiki.com/miaoxworld/OpenClawInstaller/5.3-creating-custom-skills) [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills) [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model) [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model) [\[deepwiki.com\]](https://deepwiki.com/miaoxworld/OpenClawInstaller/5.3-creating-custom-skills), [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## Szybkie doprecyzowanie (jedno zdanie wystarczy)
Chcesz allowlistę komend pod **jakie realne zadania**? (np. parsowanie JSON logów, wyciąganie fragmentów tekstu, walidacja plików, itd.)
Jeśli powiesz “do czego”, dopasuję allowlistę tak, żeby:
* była **minimalna** (im mniej, tym lepiej),
* nie była “zbyt ogólna” (np. nie dam `python -c` bo to prawie jak pełny shell),
* i żeby nie blokowała Twojego flow.
Poniżej masz **praktyczne ograniczenia i “pułapki” używania `exec` w OpenClaw** czyli co realnie ogranicza to narzędzie, jak działa w sandboxie/na hoście, jakie ma limity i jakie mechanizmy bezpieczeństwa wpływają na to, czy komenda w ogóle się wykona. Wszystko w oparciu o oficjalny opis narzędzi OpenClaw. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## 1) `exec` działa w określonym “kontekście uruchomienia” (workspace / sandbox / node)
* Domyślnie `exec` uruchamia komendy **w workspace** (w praktyce: w katalogu roboczym sesji/agenta). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
* `exec` ma parametr `host`, który determinuje **gdzie** wykonać polecenie: `sandbox | gateway | node`. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
* W trybie sandbox (kontener) to, co działa na hoście, **nie musi działać w sandboxie** (brak binarek, brak sieci, inny filesystem). OpenClaw wprost zaznacza, że przy sandboxie binarki wymagane przez skill muszą istnieć również w kontenerze, a instalacje w kontenerze wymagają m.in. egressu sieci, zapisywalnego FS i uprawnień (root). [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills), [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
**Wniosek:** jeśli Twoja komenda “działa u Ciebie w terminalu”, to nadal może nie działać w sandboxie agenta (inne środowisko). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model), [\[docs.openclaw.ai\]](https://docs.openclaw.ai/tools/skills)
***
## 2) Narzędzie może być całkowicie niedostępne przez polityki narzędzi (`tools.profile/allow/deny`)
* OpenClaw ma globalne polityki narzędzi: `tools.profile`, `tools.allow`, `tools.deny` (deny wygrywa) i wspiera grupy typu `group:runtime` (gdzie jest m.in. `exec`). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
* Jeśli `exec` (albo `group:runtime`) jest zablokowany w polityce, to model **nie dostanie** schematu narzędzia, a więc nie będzie mógł go wywołać. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
**Wniosek:** “skill mówi żeby użyć exec” ≠ “agent może użyć exec”. O tym decyduje policy. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## 3) `exec` ma wbudowane limity czasu i tryby pracy (sync vs background)
* Kluczowe parametry `exec` to m.in.: `yieldMs` (domyślnie 10000), `background`, `timeout` (sekundy; domyślnie 1800), `pty`, `host`, `security`, `ask`. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
* Jeśli proces przekroczy `yieldMs`, OpenClaw może go **zabackgroundować** i zwrócić status `running` z `sessionId`. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
* Do obsługi procesów w tle służy narzędzie `process` (list/poll/log/write/kill/clear/remove). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
* Jeżeli `process` jest zablokowane, OpenClaw zaznacza, że `exec` działa wtedy **synchronicznie** i ignoruje `yieldMs/background` (czyli tracisz wygodny mechanizm longrunning jobów). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
**Wniosek:** długie komendy bez `process` mogą “nie mieć gdzie żyć” albo będą ucinane/timeoutowane, albo zablokują przebieg. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## 4) Ograniczenia bezpieczeństwa: `security` + “exec approvals” + `ask`
OpenClaw przewiduje kilka warstw kontroli:
* `exec` ma parametr `security` (np. `deny | allowlist | full`) i parametr `ask` (`off | on-miss | always`) do sterowania zgodami/warunkami uruchomienia. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
* Dodatkowo, OpenClaw ma osobny mechanizm “Exec approvals” (zatwierdzanie/ograniczanie uruchamiania komend) dokumentacja `exec` odwołuje się do tego wprost. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
* W praktyce oznacza to, że nawet jeśli agent potrafi złożyć komendę, może zostać zatrzymany przez politykę “approval/allowlist” (zależnie od konfiguracji). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
**Wniosek:** w produkcyjnych setupach `exec` często jest “supervised”: albo wymaga potwierdzeń, albo działa tylko na allowliście, albo jest wyłączony. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## 5) `elevated` (uruchomienie na hoście) ma dodatkowe bramki
* `elevated` to alias zachowania “uruchom na gateway host z pełnymi uprawnieniami”, ale **działa sensownie głównie wtedy, gdy sesja jest sandboxowana** (w przeciwnym razie bywa noop). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
* Jest to dodatkowo “gated” przez `tools.elevated` i ewentualne override per-agent oba muszą pozwalać. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
**Wniosek:** jeśli liczysz na “wyjście z sandboxa” przez `elevated`, to musisz to mieć jawnie włączone; w wielu środowiskach będzie to celowo zablokowane. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## 6) `exec` nie daje prawdziwego TTY bez `pty: true` (a i tak bywa ograniczone)
* Dokumentacja wskazuje: “Need a real TTY? Set `pty: true`.” [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
* To rozwiązuje część problemów z programami interaktywnymi, ale w praktyce nadal możesz wpadać na ograniczenia sandboxa / braku urządzeń / braku UI. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
**Wniosek:** `exec` nie jest idealne do narzędzi wymagających pełnej interakcji terminalowej, jeśli środowisko nie jest do tego przygotowane. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## 7) `exec` może być “ucinane” przez loopdetection (gdy agent zapętla toolcalls)
* OpenClaw ma mechanizm loopdetection, który może ostrzegać/blokować powtarzalne wywołania narzędzi bez postępu (można włączyć i konfigurować progi). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
**Wniosek:** jeśli agent wpada w pętlę `exec → poll → exec → poll`, system może to wykryć i zablokować. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## 8) Kluczowe “praktyczne” ograniczenie: ryzyko injection i brak automatycznej sanityzacji
To nie jest pojedyncza flaga, tylko fakt wynikający z charakteru `exec`:
* `exec` uruchamia **shell commands**, więc jeśli sklejasz komendę z surowego inputu usera, otwierasz się na injection. Dokumentacja narzędzi podkreśla, że `exec` to narzędzie w grupie “runtime” i wymaga świadomej polityki bezpieczeństwa (deny/allowlist/approvals). [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
* W docs “Creating Skills” jest ostrzeżenie: jeśli skill używa “bash/exec”, trzeba uważać na **arbitrary command injection** z niezaufanego inputu. [\[deepwiki.com\]](https://deepwiki.com/openclaw/openclaw/6.4-skills-system)
**Wniosek:** najtwardszym ograniczeniem “w praktyce” jest to, że w dobrym projekcie `exec` **musi** być ograniczone allowlistą + kontrolą parametrów. [\[deepwiki.com\]](https://deepwiki.com/openclaw/openclaw/6.4-skills-system), [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
# Rekomendacja (krótko, produkcyjnie)
Jeśli chcesz używać `exec` w skillach “na serio”, to zwykle wygląda to tak:
1. `tools.profile` + `tools.allow/deny` ogranicza dostęp do `exec` tylko tam, gdzie naprawdę trzeba. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
2. Skill ma **allowlistę komend** + walidację argumentów + ograniczenie ścieżek do runfolderu. (To jest najlepsza praktyka wynikająca z ryzyk `exec` i ostrzeżeń dot. injection). [\[deepwiki.com\]](https://deepwiki.com/openclaw/openclaw/6.4-skills-system), [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
3. Długie komendy → `process` musi być dostępny, inaczej longrunning flow się posypie. [\[blog.laozhang.ai\]](https://blog.laozhang.ai/en/posts/openclaw-custom-model)
***
## Dopytam jedno (żeby odpowiedzieć “pod Twoją konfigurację”, nie ogólnie)
U Ciebie `exec` ma działać **w sandboxie** czy **na hoście**? (I czy włączone jest `process`?)
Na tej podstawie mogę zaproponować konkretny, bezpieczny zestaw: policy + allowlista + wzorce komend pod Twój usecase.