Inspect and edit the per-workspace tool-policy overlay (.lha/policies.jsonl) that gates destructive or sensitive tool calls.
npx skills add https://github.com/google/adk-samples --skill policy
The policies_guard callback consults a JSONL policy file on every tool
call. Policies live in two layers:
horizon/guardrails/default_policies.jsonl (read-only,ships with the agent). Provides baseline blocks for catastrophic operations
(literal dd if=/dev/zero, mkfs, fork bombs, >/dev/sd*, nc -l/ncat -l/socat
bind listeners) and credential reads (cat ~/.ssh/id_rsa, cat ~/.aws/credentials).
The seed no longer carries brittle substring/regex rules for rm -rf or
chmod -R — those are now classified by an argv-structural parser
(horizon/guardrails/command_safety.py) that lexes the command into tokens and
inspects structure instead of pattern-matching raw strings.
.lha/policies.jsonl under the workspaceroot. This is the file you edit. The overlay is appended to
the seed — new rules add restrictions on top of the defaults.
Mtime-cached, so edits take effect on the next tool call.
earlier — you cannot remove seed rules; only the overlay can be
edited.
If the user is asking about a *one-time* approval for a blocked
call, they want policy_grant, not this skill.
One JSON object per line. Blank lines and # comments are skipped.
Every rule must include canonical_tool_name; that field gates which
tool the rule applies to.
A rule may carry one or more of these fields. They are evaluated
independently — set as many as you need on a single rule.
| Field | Type | Effect |
|---|---|---|
| destructive | true | Always block the tool. |
| destructive_commands | {arg: [substring, ...]} | Block when the string arg contains any substring (case-insensitive). |
| destructive_commands_regex | {arg: [regex, ...]} | Block when any regex matches the string arg (case-insensitive). Use when substrings are too blunt. Tenant-authored regexes (overlay + grant rules) are validated for length and nested-quantifier patterns before compilation; malformed regexes are skipped with a warning. |
| destructive_paths | [prefix, ...] | Block when a path-shaped arg (path, file_path, target_path) starts with any prefix. |
| destructive_path_patterns | [fnmatch-glob, ...] | Block when a path-shaped arg matches any fnmatch glob. Use for per-user paths like */.ssh/*. |
Before the overlay/seed rules run, command_safety.py lexes shell commands
into argv tokens (quote- and operator-aware via stdlib shlex) and inspects
structure. It returns a verdict: "deny" (catastrophic, always blocks),
"ask" (risky, blocks children/headless, prompts the root agent via an
interactive approval card), or None (no opinion). Examples:
rm -rf /, rm -rf /etc, rm -rf $HOME, rm -rf /*, etc.(recursive force-delete of system/home roots or their subdirectories).
find . -delete, git push --force, chmod -R 777 .,sudo apt install ..., curl <url> | bash.
On an "ask" verdict, the root agent sees an interactive four-button
approval card; the child/headless chain treats it as a hard deny (no
regression in unattended contexts). This replaces the fragile substring/regex
rules that shipped in older seeds — the new seed (default_policies.jsonl)
only carries literal catastrophic commands + credential reads.
The root agent's interactive approval can be set to auto-approve
demotable-ask verdicts (ONLY) via /yolo (toggles between default and yolo
modes). YOLO mode auto-approves the Layer-D interactive ask; it does not
bypass the exfil guard or Layer-C hard-deny rules (catastrophic
+ credential reads + seed overlays). Use it when you trust the session and want
fewer prompts for risky-but-non-catastrophic operations. Approval mode is
per-session state, not persisted.
Permission rules in .lha/permissions.jsonl or granted via the interactive
approval card may include a commandPrefix, commandRegex, or argsPattern
to narrow blanket allow rules. Overlay and grant rules (source =
"overlay" or "grant") that target terminal or process but carry no
such narrowing field are rejected at load time — you cannot grant a blanket
"always allow terminal" from the overlay or a session approval; only the
default seed may carry that. This prevents accidental over-granting.
A policy block returns {"error": ..., "confirmation_required": True}. The
agent should either narrow the call, ask the user, or — if the user explicitly
approves — record a session grant via policy_grant.
To force a *prompt* (not a hard block) or block a specific command for the
user, use the permission layer instead: add an ask_user or deny rule to
.lha/permissions.jsonl (see docs/permission-model.md). This overlay is
hard-block only.
read_file(".lha/policies.jsonl")
If the file does not exist, the user has no overlay rules yet — only
the seed is active. To see the seed too:
read_file("horizon/guardrails/default_policies.jsonl")
Read the existing overlay, append the new JSON object as one line,
write the whole file back. Always end the file with a trailing
newline.
existing = read_file(".lha/policies.jsonl") # may be missing → treat as ""
new_rule = {"canonical_tool_name": "terminal",
"destructive_commands": {"command": ["rm -rf node_modules"]}}
body = (existing.rstrip("\n") + "\n" if existing else "") + json.dumps(new_rule) + "\n"
write_file(".lha/policies.jsonl", body)
If the parent .lha/ directory does not exist, write_file will
create it.
Read the overlay, drop the targeted line (0-based index into the
overlay, ignoring blank/comment lines), write back. Confirm the
target with the user before removing — overlay rules typically exist
because the user (or you on the user's behalf) added them to plug a
gap.
lines = [l for l in read_file(".lha/policies.jsonl").splitlines()
if l.strip() and not l.lstrip().startswith("#")]
removed = lines.pop(target_index)
write_file(".lha/policies.jsonl", "\n".join(lines) + ("\n" if lines else ""))
User: "Block npm publish from the terminal."
.lha/policies.jsonl (returns "" if missing). {"canonical_tool_name": "terminal", "destructive_commands": {"command": ["npm publish"]}}
npm publish fromterminal. The next attempt will be blocked until the rule is
removed."
horizon/guardrails/default_policies.jsonl — it's theshipped seed and is read-only from the agent's perspective.
skipped with a warning) — but always double-check your rule
parses by reading the file back after writing.
Integration with protocols.io API for managing scientific protocols. This skill should be used when working with protocols.io to search, create, update, or publish protocols; manage protocol steps and materials; handle discussions and comments; organize workspaces; upload and manage files; or integrate protocols.io functionality into workflows. Applicable for protocol discovery, collaborative protocol development, experiment tracking, lab protocol management, and scientific documentation.
Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances
Generate Excalidraw diagrams from natural language descriptions. Use when asked to "create a diagram", "make a flowchart", "visualize a process", "draw a system architecture", "create a mind map", or "generate an Excalidraw file". Supports flowcharts, relationship diagrams, mind maps, and system architecture diagrams. Outputs .excalidraw JSON files that can be opened directly in Excalidraw.
Build and distribute Expo development clients locally or via TestFlight
Use when you have a written implementation plan to execute in a separate session with review checkpoints
Data structure for annotated matrices in single-cell analysis. Use when working with .h5ad files or integrating with the scverse ecosystem. This is the data format skill—for analysis workflows use scanpy; for probabilistic models use scvi-tools; for population-scale queries use cellxgene-census.
Benchling R&D platform integration. Access registry (DNA, proteins), inventory, ELN entries, workflows via API, build Benchling Apps, query Data Warehouse, for lab data management automation.
Comprehensive molecular biology toolkit. Use for sequence manipulation, file parsing (FASTA/GenBank/PDB), phylogenetics, and programmatic NCBI/PubMed access (Bio.Entrez). Best for batch processing, custom bioinformatics pipelines, BLAST automation. For quick lookups use gget; for multi-service integration use bioservices.
Take google/policy from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.