Skip to content
Development
Skill

/security-tiers

Use when classifying any operation before executing it, or deciding whether user approval is required

From plugin
gaia
443 skills9 agents12 hooks

Claude Code

$ npx -y skills add metraton/gaia --skill security-tiers --agent claude-code

SKILL.md

security-tiers.SKILL.md
name: security-tiers
description: Use when classifying any operation before executing it, or deciding whether user approval is required

Security Tiers

COMMAND_SET boundary

Classification applies to each exact atomic command. After read-only investigation, one or more predictable T3 commands may be requested plan-first with `gaia approvals request-set` -- a single predictable T3 command uses the same verb proactively, not only after the pre-execution policy gate returns `[T3_BLOCKED]`. Never discover a set by attempting a compound shell command. `subagent-request-approval` owns request construction and grouping; this skill owns the classification and no-elusion decision that routes work there.

security-tiers classifies every operation into four tiers so an agent knows whether it can run freely or must request the user's consent.

The validator model: a simple first line, walls behind it

The Bash classifier is the first line, and it is kept simple on purpose: the target walls below stand behind it, so a command it misreads still meets a wall at the thing that matters. It applies five rules; the sections after this one detail each lane.

1. **A closed change-verb lexicon.** A word changes state only when it is in `hooks/modules/security/verb_lexicon.py::CHANGE_VERB_CLASSES` -- five classes, `create`, `update`, `delete`, `publish` and `exec` -- whose union is `hooks/modules/security/mutative_verbs.py::MUTATIVE_VERBS`. A word outside it is not a change verb, so `add`, `commit` and `stash` are free by elimination. The ambiguous words `set`, `copy`, `start`, `tag`, `label` and `annotate` (`verb_lexicon.py::AMBIGUOUS_VERBS`) are relieved only on a family proven local, `LOCAL_FAMILIES` (docker), through `verb_lexicon.py::ambiguous_verb_relieved`; an unmodelled CLI (`rclone copy`) is not proven local and signs. Inside the execution scan (rule 3) a lexicon verb counts only on a remote family (`hooks/modules/security/execution_scan.py::REMOTE_FAMILIES`: k8s, iac, git, cloud, workspace, package, system). 2. **A closed exception table.** The verb yields to the effect only in the shapes `verb_lexicon.py::EFFECT_OVER_VERB_EXCEPTIONS` lists, each naming the symbol that decides it: a push of one's own non-default branch and a `--ff-only` merge in a managed worktree (`mutative_verbs.py::_check_git_publish_relief`), a local `git merge` (`mutative_verbs.py::_git_merge_is_local`), a `--ff-only` merge to the branch's own remote ref (`mutative_verbs.py::_git_local_sync`), opening or editing a change request (`verb_lexicon.py::CHANGE_REQUEST_OWN_WORK`), and `gaia approvals revoke|reject|reject-all|clean` (`mutative_verbs.py::CONSENT_REDUCING_SUBCOMMAND_EXCEPTIONS`). Opening a change request is free on any repository; a local merge is free with only the plain flags `mutative_verbs.py::_GIT_LOCAL_MERGE_FLAGS` lists (plus `-m <msg>`, or a bare `--abort`, `--continue`, `--quit`), while a strategy option (`-s`, `-X`) or an operand the shell computes (`git merge $BRANCH`) signs; `pr merge` signs for every binary, and so does a change-request edit on another repository or with a retarget flag. "What reaches the remote" below gives each shape in full. 3. **The word that decides what runs is literal.** When the program word, or the verb word of a CLI that picks its action by word, is a shell expansion, the command asks as `unknown.dynamic-span` (verb `dynamic-program` or `dynamic-verb`; Step 0-dynamic in `mutative_verbs.py::_detect_mutative_command`, reading `_literal_words` and `_dynamic_verb_span_word`). 4. **One short execution scan, depth 1.** `execution_scan.py::scan_execution` reads an execution's entry -- a script file, inline `-c`/`-e` code, a heredoc program, a package script with its `pre`/`post` scripts, a `make` target or `just` recipe with its direct prerequisites, `go run`, `cargo run` -- and the literal local files it names, once each and never their own callees (at most `MAX_CALLEES`, 32, each up to `MAX_BYTES`, 512 KiB). `execution_scan.py::_signal` looks for six signals: a change verb on a remote family (`remote-change-verb`, `sign.lands`); a write -- never a read -- onto a system, account or harness path (`system-path`, `sign.system-path` or `sign.lands-on-protected`); a download piped into an interpreter (`download-and-run`, `sign.foreign-code`); code built at runtime, such as `eval` of a variable or an `import` whose specifier is computed (`runtime-code`, `sign.foreign-code`); a recursive delete or truncate outside the project or Gaia scratch (`destroys-outside`, `sign.destroys`, measured against `execution_scan.py::_kept_roots`; a permanently blocked disk or delete command reports as `floor` under the same rule); data sent over the network (`network-send`, `sign.speaks`). The scan only adds asks (`mutative_verbs.py::_check_execution_scan`, run right after `_detect_mutative_command`): a verdict the older lanes already made mutative is kept unless its verb is one of `mutative_verbs.py::_NO_MODEL_VERBS` -- an unresolved `npm`/`bun`/`pnpm`/`yarn` run, an unresolved frozen install, an unreadable script file -- and only such an ask is freed when the scan reads the entry with no signal, never one whose entry is inline code. A file read only in part (over the size cap or not UTF-8) asks as `partial-read` (`unknown.dynamic-span`), and an entry that runs a local path the scan cannot read keeps the older verdict. 5. **Reads are free, except secrets and the store.** What changes nothing is free by elimination (`hooks/modules/security/tiers.py::_classify_command_tier_cached`). Reading where secrets live is refused (`hooks/modules/security/sensitive_read_guard.py::check`), and so is any `sqlite3` read of Gaia's store or Python that reaches it in-process (`hooks/modules/security/gaia_db_write_guard.py::check`, which calls `hooks/modules/security/store_code_guard.py::check`); `gaia context query` opens the store read-only.

The target walls behind those rules:

  • **Running as another user signs
Read more
@metraton
Ships withgaia

Generative AI Interface for Agents. Specialist agents for Claude Code and OpenCode, with a memory that outlives the session and a consent gate on everything that changes state.

443 skills9 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
4
Star history of metraton/gaia on GitHub, a chart by star-history.com

Other skills on gaia.

agent-creation

agent-creation

Use when creating a new specialist agent for Gaia, or reviewing whether an existing agent follows the correct structure, tone,…

@metraton@metratonInstall Skill
agent-response

agent-response

Use when the orchestrator must read, reconcile, route, and present an agent_contract_handoff

@metraton@metratonInstall Skill
blog-writing

blog-writing

Use when writing, drafting, or publishing a blog article for metraton.github.io -- "escribe un post para el blog", "publica un…

@metraton@metratonInstall Skill
brief-spec

brief-spec

Use when the user wants to capture a feature as a brief or spec before planning it -- "arma un brief para esto", "necesito un…

@metraton@metratonInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about security-tiers.

Which coding agents can use security-tiers?
security-tiers installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.