Grounds on (exists today):
src/gaia/agents/base/tools.py (@tool, _TOOL_REGISTRY) · src/gaia/agents/registry.py (KNOWN_TOOLS, namespaced_agent_id) · src/gaia/connectors/providers/base.py (ConnectorRequirement) · src/gaia/ui/routers/agents.py (/api/agents, the panel to mirror)Proposed runtime (not written yet): the gaia.skills loader, the gaia skill CLI, and the /api/skills router. Every such symbol is marked PROPOSED where it appears.Component: the
SKILL.md field grammar — the on-disk contract for GAIA’s skill ecosystem (issue #691).Module: gaia.skills — PROPOSED, greenfield. No loader, CLI, or registry code exists. The contract is grounded on the live tool registry in gaia.agents.base.tools.Status: Format = decided (this revision). Runtime = proposed. The companion Agent Skills spec owns the integration surface (discovery, scoping, progressive disclosure); this document is authoritative for the field grammar.Target consumers: #887 (skill auto-synthesis), #553 (self-improving agent), #1451 (tool-loader Part 3), #647 (skill marketplace), #648 (OEM bundling), #462 (Agent Manifest).Why this exists
A GAIA agent’s capabilities are compiled in. Tools arrive through hardcoded mixins (RAGToolsMixin, BrowserToolsMixin, … catalogued in KNOWN_TOOLS,
registry.py:38)
wired into the agent class and shipped inside the wheel. A user who wants a new
capability has no path short of forking the agent. Skills make a capability
portable: a folder with a SKILL.md an agent loads only when relevant.
The Agent Skills spec answers why skills, and how an agent
composes them. This document answers a narrower, higher-stakes question: what
exactly goes in the frontmatter. That matters because the frontmatter is a
contract, not a private detail — several landed and in-flight features read or
emit these fields:
- #887 (skill auto-synthesis) and
#553 (self-improving agent) will
emit
SKILL.mdfiles via skill extraction. The field names they write must be the field names this spec defines. - #1451 (tool-loader Part 3)
reads the
tools_requiredfield to union a recipe’s tools into per-turn tool selection — a hard cross-spec dependency already written down intool-loader.mdx. - #647 (marketplace) and #648 (OEM bundling) need a stable definition of “a skill” and its trust tiers to publish and pre-bundle.
Prior art (credit before contribution)
GAIA does not invent a skill format. It adopts one and extends the frontmatter. The base and the compatible formats:
GAIA’s contribution is the
metadata.gaia namespace: typed @tool
declarations, a <domain>:<level> permission grammar bridged to the connector
grant model, three install-time security tiers, and the tools_required recipe
contract — all expressed inside the standard’s metadata map, so a GAIA skill
remains a valid standard skill.
Decided design
The schema is the standard’s required base plus a single GAIA-owned namespace. A standard runtime reads the base and ignoresmetadata.gaia; GAIA reads both.
Adopted base (Agent Skills standard)
The metadata.gaia namespace
Everything GAIA-specific is nested here. Omit the whole block and the skill is a
valid instruction-only skill (see Off-states).
tools vs tools_required — never conflate them
These are two different fields with two different consumers, and collapsing them
breaks the recipe contract:
The field name
tools_required is locked as the cross-spec contract with
#887/#1451. A skill may have either, both, or neither.
Field reference
Naming
Skill names follow the Agent Skills rule:^[a-z0-9]+(-[a-z0-9]+)*$, ≤64 chars,
and must equal the skill’s directory name (so web-research/SKILL.md has
name: web-research). No leading, trailing, or consecutive hyphens. Names are
unique within a discovery root; precedence between roots is defined in
Agent Skills → Discovery.
Permission model
Permissions follow<domain>:<level> with an optional :scope qualifier. There
are no implicit grants — a skill declares every domain it touches.
Scopes narrow a grant:
filesystem:read:~/.gaia/data/**,
network:read:*.brave.com, shell:execute:git,npm. An unscoped grant covers
the whole domain.
Bridge to the connector grant model — no parallel ledger
Agent Skills already states that a skill carrying permissions is granted to an agent reusing the connectors per-agent grant model. This spec makes the mapping concrete rather than inventing a second grant system:network:*andmcp:connectresolve, at scope-time, to aConnectorRequirement(connector_id, scopes, reason)(connectors/providers/base.py:23) — the same frozen primitive agents already declare viaREQUIRED_CONNECTORS(agent.py:295). The skill’spermissionsbecome the agent’s connector requirements when the skill is scoped in.filesystem:*,shell:*,database:*,desktop:*,env:*are new local-capability domains with no connector equivalent. They are enforced by the skill sandbox (PROPOSED — see Phased build).
namespaced_agent_id keying
(builtin: / custom:sha256: / installed:,
registry.py:392)
that already isolates agent grants today.
Security tiers
Three tiers set the install-time permission ceiling and grant behavior.
Promotion path:
experimental → community → verified. A publisher signs to
reach community; an AMD audit request reaches verified. Re-audit on every
version bump.
Tiers are NOT the governance decision system. The governance layer’s
DecisionType = Literal["ALLOW", "REVIEW", "BLOCK"]
(governance/schemas.py:17)
is a run-time, per-action verdict. Security tiers are an install-time trust
ladder that sets the ceiling a skill’s permissions may reach. They are
complementary, not the same axis: a verified skill still has each action
adjudicated at run time by governance. This tier system is greenfield — it
does not exist in code yet.Tool registration
A skill’stools map onto the existing decorator and registry. On load
(PROPOSED), the runtime registers each @tool under a <skill-name>/<tool-name>
namespace into _TOOL_REGISTRY to prevent collisions when an agent composes
multiple skills — the same namespacing
Agent Skills describes. The skill’s
tools.py uses the standard @tool decorator unchanged:
tools entry has a matching @tool function,
parameter names/types match the signature, and the return is JSON-serializable —
failing loudly (no partial load) on mismatch, as
Agent Skills requires.
CLI
The acceptance-required trio plus the natural neighbors. All PROPOSED — nogaia skill subcommand exists in cli.py yet.
Agent UI dashboard support
Acceptance #4 requires a skills management panel. The proposed/api/skills
router mirrors the existing /api/agents router
(ui/routers/agents.py:
list :130, detail :174, export :184, import :222) — the same
list/detail/install/remove shape, so the panel reuses the agents-panel
conventions rather than inventing new ones.
/api/skills router today — the dashboard is greenfield and
degrades to empty until the loader lands (see Off-states).
Cross-format compatibility & migration
Three formats, one namespace pattern. GAIA reads the standard base directly and treats Hermes/OpenClaw as migration sources, not runtime targets.
A single tool —
gaia skill migrate --from {hermes,openclaw,auto} (auto-detect
keys on the metadata.<vendor> map) — reads the foreign namespace and writes a
metadata.gaia block. Every migrated skill lands experimental, re-earning
trust. Migration emits a report of fields needing manual review.
Relationship to neighbors
- Agent Skills — owns the architecture and integration surface (discovery roots, progressive disclosure, scoping, the skill/tool/agent distinction). This doc owns the field grammar. Where they overlap, that spec is canonical for the compatibility surface and this one for the schema; the two are reconciled (see Correcting the prior spec).
- Agent Manifest (#462) — a
gaia-agent.yamlreferences skills by name + version range;SKILL.mdis the skill-level complement. Theskills:block and its resolution live in Agent Skills → Agent Hub integration. - Agent bundles — skill packaging relates to the existing agent bundle format
(
.zip+bundle.json,BUNDLE_FORMAT_VERSION = 1,export_import.py:40). - Builder template — scaffolds
agent.pytoday (builder/template.py); emittingSKILL.mdis a future extension, not current behavior. - OEM bundling (#648) — needs a
stable definition of “a skill” to pre-configure hardware SKUs. A SKU pre-bundles
skills as
verified-tier entries in a discovery root; the directory anatomy and tier defaults this doc fixes are that definition.
Example skills
Six worked examples. The three for existing agents (acceptance #6) declare only tool names that exist in the current registry. All parse as YAML; tool skills round-trip against theirtools.py.
1. Minimal instruction-only skill (bare standard)
1. Minimal instruction-only skill (bare standard)
Proves a bare Agent Skills
SKILL.md loads with no GAIA fields — defaulting to
experimental, no tools, no permissions.2. Tool skill in the new shape (web-research)
2. Tool skill in the new shape (web-research)
The restructured schema: standard base +
metadata.gaia.3. Recipe skill with tools_required (the #887/#1451 contract)
3. Recipe skill with tools_required (the #887/#1451 contract)
A distilled procedure that consumes existing registry tools. Each
tools_required name resolves against a real registry tool (query_documents
from RAGToolsMixin, read_file from FileIOToolsMixin; remember from the
tool-loader CORE set).4a. rag-search (from RAGToolsMixin)
4a. rag-search (from RAGToolsMixin)
Acceptance #6 — a skill mapping the
rag mixin’s real tools.4b. web-research (from BrowserToolsMixin)
4b. web-research (from BrowserToolsMixin)
Acceptance #6 — the
browser mixin’s real tools (search_web, fetch_page,
download_file).4c. file-operations (from FileIOToolsMixin)
4c. file-operations (from FileIOToolsMixin)
Acceptance #6 — the
file_io mixin’s real tools.5. Hermes skill + its metadata.gaia migration
5. Hermes skill + its metadata.gaia migration
A Hermes skill (left) and what
gaia skill migrate --from hermes produces
(right) — the metadata.hermes fields become metadata.gaia, and the result
lands experimental.6. OpenClaw skill + its migration
6. OpenClaw skill + its migration
An OpenClaw skill and its migrated form.
metadata.openclaw requirements map to
metadata.gaia.requirements; trust resets to experimental.Off-states (safe floors)
Every degraded condition lands on a conservative, well-defined floor — nothing breaks because a GAIA feature is absent.
Future-gated phases are additive with precedence. The
tools_required
signal that #1451 consumes returns [] cleanly until #887 lands
(tool-loader.mdx),
so a recipe skill authored today is valid but inert until its consumer ships —
it never blocks or errors.
Correcting the prior spec
This document revises an earlier draft ofskill-format.mdx. The most
important correction:
The base standard is Agent Skills (agentskills.io),
not OpenClaw. The prior draft framed “OpenClaw / ClawHub” as the external
standard to be compatible with. In fact agentskills.io (as used by Claude Code)
is the base GAIA adopts; OpenClaw is just one of several compatible
third-party formats, alongside Hermes. This reconciles skill-format.mdx
with Agent Skills, which had already flagged
“OpenClaw/ClawHub” as a placeholder from an earlier draft.
The second structural correction: GAIA-specific fields move from the top level
into metadata.gaia. The prior draft put permissions / security_tier /
requirements / tools at the top level, which collides with the standard’s
namespace and breaks lossless cross-runtime parsing. Nesting them under
metadata.gaia mirrors the convergent prior art (Hermes metadata.hermes,
OpenClaw metadata.openclaw).
KPIs
A format contract is judged by conformance and losslessness, not runtime speed. The bar:Phased build
The format (Phase 0) is decided in this PR; the runtime is greenfield and ships in additive phases. Each phase holds the prior floor until it lands.Phase 0 — Format contract (this revision)
Success criteria:- Schema decided: adopted base +
metadata.gaia;toolsvstools_requiredseparated;compatibility/allowed-toolsexcluded. - Agent Skills reconciled — mapping table nests
metadata.gaia.*, the placeholder Note becomes a Division-of-authority Note, andallowed-tools/compatibilityare marked excluded. - All example skills parse; the three acceptance-#6 skills use only real registry tool names.
- Traceability covers 100% of #691 acceptance criteria.
Phase 1 — Loader, validator, CLI core (PROPOSED)
gaia.skills parses + validates metadata.gaia, registers tools under the
<skill>/<tool> namespace into _TOOL_REGISTRY, and ships
gaia skill list|install|remove. Discovery roots per
Agent Skills.
Success criteria:
- A tool skill loads and its tools register and call.
- A bare standard skill loads instruction-only.
- Validation fails loudly on a tools/
tools.pymismatch or a permission that exceeds the tier ceiling — no partial load.
Phase 2 — Permission enforcement + tier ceilings + connector bridge (PROPOSED)
<domain>:<level> enforced by the sandbox; network/mcp permissions resolve
to ConnectorRequirement at scope-time; tier ceiling enforced; experimental
sandbox.
Success criteria:
- A skill requesting a permission above its tier ceiling fails to load.
- A
network:*/mcp:connectpermission produces the matching connector grant requirement;filesystem/shell/database/desktoproute to the sandbox.
Phase 3 — Agent UI dashboard + migration (PROPOSED)
/api/skills mirroring /api/agents; the skills management panel; gaia skill migrate --from {hermes,openclaw,auto}.
Success criteria:
- The panel lists installed skills with tier + version and supports install/remove (acceptance #4).
migrateoutput validates and landsexperimentalfor Hermes and OpenClaw inputs.
Phase 4 — Marketplace + consumer wiring (PROPOSED; #647 / #887 / #1451)
Publish/registry REST; #887 emits conformantSKILL.md; #1451 unions
tools_required.
Success criteria:
- #887-synthesized files validate against this schema unchanged.
- #1451 unions a matched skill’s
tools_requiredahead of semantic results (the contract intool-loader.mdx).
Open questions
The five design forks (base standard,metadata.gaia nesting, top-level
version, migration-only v1, excluding compatibility/allowed-tools) are
locked by the maintainer and are recorded as settled above. What remains are
implementation-level questions for whoever builds the runtime:
tools_requiredvalidation timing. Fail-vs-skip is not open — GAIA’s fail-loudly policy settles it: a name unknown to the framework is a manifest defect and fails loudly; a name valid but inactive in the current agent’s registry is scoping (omitted + logged, not an error). The genuine open nuance is when the unknown-name check runs — at install against a static tool catalog, or deferred — since the active registry is assembled dynamically from mixins and other skills, so the full tool universe may not be known at install time. Affects #1451 robustness.- Skill→skill dependencies. The prior draft allowed a skill to depend on
other skills (
requirements.skills). Keep it undermetadata.gaia.requirements, or defer dependency resolution to the marketplace (#647)? /api/skillsinstall sources. Registry-only, or also local path / URL? The latter widens the install-time security surface.- Body-injection scanning. Static scanning of instruction bodies for
injection patterns at import — required for
community+, advisory forexperimental? (Also open in Agent Skills → Open questions; resolve in one place.) docs/spec/relocation. #691 acceptance says “documented indocs/spec/”; this doc stays indocs/plans/until the loader ships. Does the move todocs/spec/(and thedocs.jsonupdate) happen with Phase 1, or earlier?
Current state of the code
The format is grounded on real primitives; the skill runtime is entirely greenfield.Dependencies
Blocking: none. This is a foundational format contract; its design inputs are external standards plus the in-repo drafts. Design inputs: Agent Skills (base), Hermes (metadata.hermes), OpenClaw (metadata.openclaw), Claude Code (reference
impl); in-repo Agent Skills (architecture / compatibility
surface) and tool-loader.mdx Part 3 (the tools_required
contract).
Downstream consumers. The features whose contract this format must satisfy. A
closed tracking issue means that design is settled and already references this
format — not that the dependency is gone.