agentleFS
metratonmetraton/gaia/skills/gaia-patterns/SKILL.md

gaia-patterns

Skill4 starsChanged 4 months agoMITView on GitHub

Use when building or modifying Gaia components -- agents, skills, hooks, CLI tools, or routing config

The file

We split this skill into the rules it gives an agent

5 rules. About 0 are common, 1 is distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    To add a new module: Write module in modules/<package>/, import and call it from the relevant adapter method.

    line 72
  2. Very specific:

    To add a new hook entry point: Create hooks/<event_name>.py, register it in build/<plugin>.manifest.json, add matchers.

    line 74
  3. Very specific:

    To add a surface: Add a routing: block to the owning agent's frontmatter, register the agent in build/gaia.manifest.json, run gaia update, …

    line 105
  4. Very specific:

    To add a signal: Add command/artifact patterns to the owning agent's routing: block.

    line 106
  5. Distinctive:

    When adding or modifying files in agents/, skills/, hooks/, config/, bin/, tests/, build/ or the repo root, load Skill('technical-writing') …

    line 122

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Gaia Code Patterns

Construction patterns for building Gaia components. Every component type follows a discoverable pattern -- read 2-3 existing examples before creating a new one. For the full component inventory, see reference.md.

Prompt -> Result Flow

1. User sends prompt
   |
2. Orchestrator routes to agent (DB-backed surface_routing table --
   the routing is the ORCHESTRATOR's reasoning; it is never injected
   into the subagent)
   |
3. Pre-Tool Hook (pre_tool_use.py)
   +-- Validate the Task/Agent dispatch (agent exists, T3 scan of the
       prompt via TaskValidator) -- no frontmatter read, no skill load
   +-- Birth the agent_contract_handoffs row (identity, kernel data,
       dispatch_project resolved from cwd)
   |
   (for a dispatched SUBAGENT only: the HOST -- Claude Code, not this
   hook or any other Gaia hook -- separately reads the target agent's
   `.md` frontmatter and preloads its `skills:` list before the first
   turn. `hooks/hooks.json` has no PreToolUse `Skill` matcher; its
   PostToolUse `Skill` matcher only records loads: every load becomes a
   `skill.loaded` harness event naming the skill, agent, role and
   session (`hooks/modules/events/capability_usage.py`), and a
   main-session `Skill('memory')` load also becomes `memory.skill_loaded`
   for the orchestrator's memory-write guard
   (`hooks/modules/security/memory_skill_guard.py`) -- see
   `artifact_skill_reminder.py`. A preloaded skill never passes through
   the `Skill` tool, so it records nothing. The primary agent has no equivalent:
   Claude Code's own docs list only "system prompt, tool restrictions,
   and model" as inherited on the main thread, which is why
   `gaia-orchestrator.md`'s frontmatter carries no `skills:` field.)
   |
4. SubagentStart hook claims the born row and injects the KERNEL:
   "# Your Contract" (incl. project, its declared workflow when
   there is one, can_read/can_write menu), "# Scope memory",
   "# Project context", "# Standing notes", "# Environment", "# Your CLI".
   "# Project context" carries the dispatch project's can_read sections: whole
   when they fit, else pointer lines, else one line; the verbs for the rest
   are in agent-protocol/read-map.md.
   |
5. Agent checkpoints/finalizes its agent_contract_handoffs row via
   `gaia contract`; the final message carries no envelope
   |
6. Post-Tool Hook -> audit + metrics
   |
7. Orchestrator processes agent_state; only COMPLETE is terminal

Hook Patterns

Entry points (hooks/*.py) are stdin/stdout glue only. All logic lives in the adapter layer.

hooks/pre_tool_use.py          -- reads stdin, calls adapter, writes stdout
  -> adapters/claude_code.py   -- parses event, formats the host response
                                  (adapters/opencode.py is OpenCode's)
    -> adapters/tool_policy.py -- the shared tool policy both adapters call
    -> gaia/approvals/core.py  -- the host-neutral approval core
    -> modules/security/*      -- blocked_commands, mutative_verbs
    -> modules/context/*       -- contracts_loader, kernel_builder
    -> modules/agents/*        -- dispatch_binding, artifact_skill_map

To add a new module: Write module in modules/<package>/, import and call it from the relevant adapter method. Modules receive parsed context and return results; they never read stdin or write stdout.

To add a new hook entry point: Create hooks/<event_name>.py, register it in build/<plugin>.manifest.json, add matchers. The entry point reads stdin JSON, calls the adapter, and prints the response.

Agent Patterns

---
name: agent-name
description: Routing label -- triggers when orchestrator sees matching intent
tools: Read, Edit, Write, Glob, Grep, Bash  # restrict per domain
model: inherit
permissionMode: acceptEdits  # required for most agents; omit only for orchestrator and read-only agents
skills:
  - agent-protocol        # always first
  - security-tiers        # always second
  - command-execution     # if agent runs commands
  - domain-skill          # agent's domain patterns
cli:
  - "gaia <domain-verb> ..."   # optional; appends a line to "# Your CLI"
---

Identity (1-2 paragraphs): domain, output format. Scope: CAN DO / CANNOT DO -> DELEGATE table. Domain Errors: agent-specific errors only.

skills: and cli: are read by two different parties, not one -- this is why the example shows both. skills: is preloaded by the HOST (Claude Code), not by any Gaia hook, and only for a dispatched SUBAGENT: the primary agent (gaia-orchestrator.md) carries no skills: field, because Claude Code's own docs list only "system prompt, tool restrictions, and model" as inherited on the main thread. cli: is the one frontmatter field Gaia itself reads, at subagent birth (context/kernel_builder.py::_agent_cli_extras): its lines are appended verbatim to the "# Your CLI" kernel block. It is optional and no shipped agent declares it yet -- shown here so the two fields' different owners (host vs. Gaia) are visible side by side, not to imply it is required.

A dispatched SUBAGENT is instantiated as: identity (.md) + skills (preloaded by the host from frontmatter) + dispatch kernel (# Your Contract / # Scope memory / # Project context / # Standing notes / # Environment / # Your CLI, rendered from the born row) + orchestrator request. The primary agent skips the skills step entirely. Project context arrives as the kernel's # Project context block, built from the can_read sections (from agent_contract_permissions) of project_context_contracts; a section the block only points at is pulled on demand -- the verb that reaches it, and the same-named sibling that does not, are in agent-protocol/read-map.md.

Routing Patterns

The DB-backed surface_routing table maps user intent to agents. The source of truth is each agent's routing: frontmatter block (agents/*.md): surface, adjacent_surfaces, signals (commands/artifacts), required_checks, optional sub_surfaces. Keywords were retired as a signal source -- the matcher (tools/context/surface_router.py::_score_surface) scores commands and artifacts only; a legacy keywords key in a signals block is ignored by scoring. The surface's intent is the agent's description; contract_sections derives from project_context_contracts.read. tools/scan/seed_surface_routing.py seeds the table at install time (mirror of seed_contract_permissions.py); tools/context/surface_router.py reads it via tools/context/surface_router.py::load_surface_routing_config.

To add a surface: Add a routing: block to the owning agent's frontmatter, register the agent in build/gaia.manifest.json, run gaia update, and update the surface-router tests. To add a signal: Add command/artifact patterns to the owning agent's routing: block.

CLI Tool Patterns

CLI tools live in bin/ and are registered in package.json bin field. Pattern: parse args, resolve paths (follow symlinks to source), run checks, exit with code. gaia doctor is the diagnostic model -- read it first.

Documentation Drift Awareness

When you modify any Gaia component (hook, skill, agent definition, routing config, security rule), check if existing reference docs describe that component's behavior. If drift exists, report it via cross_layer_impacts in your contract row. The orchestrator then decides whether to dispatch a documentation update task.

Do NOT update docs yourself -- your job is to flag the drift and let the orchestrator choose the next action.

Examples of drift to flag:

  • Changed hooks/modules/security/protected_paths.py::is_protected_hook_path paths → check security-tiers/SKILL.md for path documentation
  • Added a new agent definition → check gaia-patterns/reference.md for agents table
  • Modified hook enforcement logic → check security-tiers and agent-protocol references
  • When adding or modifying files in agents/, skills/, hooks/, config/, bin/, tests/, build/ or the repo root, load Skill('technical-writing') (door: README) to update the relevant README.md

Format: In cross_layer_impacts, list the doc file and the behavior change, e.g.:

"cross_layer_impacts": [
  "security-tiers/SKILL.md: _is_protected() now excludes .claude/settings.local.json"
]

Key Principles

  • Skills teach process. Agents teach identity. Runtime enforces contracts. Never duplicate across these layers.
  • Coordination before execution. The orchestrator cannot edit code or run general commands. Its guarded Gaia CLI lane reads coordination state and persists only decisions it owns; domain evidence and execution still belong to specialists.
  • The CLI teaches its own use. Every help carries invariant, failure semantics and composition; a not-found answer says what the word IS (a workspace, a group, a project, a slug, a memory key) and the verb that reaches it; a map row fires on an observable event, never on a self-evaluation.
  • Consolidation loop. For multi-surface work, the orchestrator may dispatch multiple agent rounds, stopping when gaps are no longer actionable.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.