Skills
A skill is a Markdown-plus-metadata bundle that tells the Platform Agent how to accomplish a particular class of task. Skills follow the Claude skills format — a SKILL.md file with YAML frontmatter (name, description) followed by procedural guidance the model reads on demand.
The full skill catalog is on the Skill catalog page. This page covers how they work.
Where skills live
Section titled “Where skills live”agents/platform/skills/├── gke-cluster-creation/│ └── SKILL.md├── gke-multitenancy/│ └── SKILL.md├── submit-suggestion/│ ├── SKILL.md│ └── (supporting scripts)└── ... (32 more)Skills are placed by persona: fleet-wide, provisioning, and GitOps-write skills live in agents/platform/skills/ (the Platform Agent); the read-only, single-cluster runtime-debugging skills live in agents/cluster/skills/ and are scaffolded into every per-cluster Cluster Agent profile.
Some skills are pure Markdown; others carry supporting files (helper scripts, YAML templates) in the same directory. The Hermes runtime discovers SKILL.md files automatically at startup.
Frontmatter contract
Section titled “Frontmatter contract”---name: gke-multi-tenancydescription: Guidance on implementing multi-tenancy and governance in Google Kubernetes Engine (GKE) clusters.---name— the skill identifier. Snake/kebab case; matches the directory name.description— a one-sentence purpose. The agent uses this to decide whether to load the skill for a given task without reading the whole body.
Anything after the frontmatter is procedural instruction: workflows, SOPs, example manifests, safety red lines. The model reads it only when it decides the skill is relevant to the current turn.
Invocation
Section titled “Invocation”Two ways a skill enters the model’s context:
- On-demand. The agent notices from the user’s prompt (or a cron job’s prompt) that a particular skill’s
descriptionmatches. It loads the skill body and follows the procedure. - Explicit reference from a cron job.
cron/jobs.jsonentries can name skills in the"skills"field. Each fleet audit always loadsfleet-audit; the"skills"line of thecompliance-auditentry below is that reference.
{ "id": "compliance-audit", "name": "Security & RBAC Posture Audit", "schedule": { "kind": "cron", "expr": "20 6 * * *", "display": "20 6 * * *" }, "prompt": "Run the daily fleet security and RBAC posture audit. Read the SOP at '/opt/data/profiles/platform/governance/compliance_audit_sop.md' — all 443 lines of it, before you run anything. Its sixteen checks are section 2, lines 90-372, so a read that stops early skips almost the entire audit and reports a clean fleet it never looked at. Section 2 opens by running the collector (`/opt/data/profiles/platform/skills/fleet-audit/scripts/collect.py compliance-audit`) in the foreground with the terminal tool's timeout: 600 (the foreground maximum), --workspace set to the workspace start returned and --out /opt/data/scratch/manifest_compliance-audit.json: run it before evaluating any check by hand, read the manifest the way section 2 says, and pass the same file to finish as --manifest-file (if the collector wrote none, section 2 says what to pass instead). Then execute it exactly, using the fleet-audit skill to open and close the audit run.", "skills": [ "fleet-audit" ], "risk": "low", "enabled": true, "deliver": "chat"}This route is only open to jobs that run a model. A no_agent job such as github-repo-watcher runs a script instead of a turn, so skills has nothing to load into; when its script files a kanban card, the card body names the skill and the worker loads it on demand.
Skill structure conventions
Section titled “Skill structure conventions”Most shipping skills follow this shape:
- Overview — one paragraph explaining what the skill does and when the agent should use it.
- Workflows — numbered procedures for common tasks.
- Examples — YAML manifests, shell commands, or link templates the model can adapt.
- Safety red lines — explicit “don’t do X” rules (e.g. the
submit-suggestionskill lists commit-scope guardrails).
The gke-compute-classes skill is a good example — it explicitly delineates when the agent should not invoke it, guarding against over-eager use.
Adding a new skill
Section titled “Adding a new skill”- Create
agents/platform/skills/<your-skill>/SKILL.md— oragents/cluster/skills/<your-skill>/SKILL.mdif it is a read-only, single-cluster runtime-debugging procedure that belongs to the Cluster Agents. - Add frontmatter with
nameand a specificdescription— this is what routes the agent to the skill. - Write the procedure. Prefer concrete steps and example manifests over abstract descriptions. The image build passes each
bash,sh,shellandzshblock in the skill’sSKILL.md, whole, to the Tirith command scanner the agent itself runs under, and fails on any block holding a command it would refuse: call a program by its literal path, never through a shell variable. A block too long for the scanner to finish analysing fails the same way, so split a long block. It also fails on a shell block whose Markdown does not parse as one, such as a fence left unclosed inside a list item, since it cannot read that block. It reads every other Markdown file in the skill directory the same way, except underscripts/. Keep each of those files,SKILL.mdincluded, at most 40,000 characters: the agent opens them withskill_view, which returns a result over its own cap as a short preview and a file path instead. The 40,000 limit sits below that cap so each file comes back whole, andmake skills-checkfails a longer one. Put a long procedure’s detail inreferences/, one file per step, and say inSKILL.mdwhen to open each. - If the skill has safety-critical operations (destructive changes, wide-blast-radius commands), list explicit red lines the model must honor.
- Test locally: DM the agent in Chat with a prompt that should trigger the skill, and verify it loads and follows the procedure. (The DM lands at the Planning Agent front door; the skill itself loads in the delegated Platform Agent worker.)
- If the skill should also run on schedule, add an entry to
agents/platform/cron/jobs.json— see Adding a watchdog.
Importing external skills
Section titled “Importing external skills”The agent discovers skills from two locations at startup:
- Baked into the image —
deploy/docker/Dockerfilecopiesagents/platform/skills/to/opt/platform-template/skills/(andagents/cluster/skills/to/opt/cluster-template/skills/), which are overlaid into the matching profile’s home when the profile is created and then replaced from the template on every pod start. Skills are image-owned — nothing durable lives under them, and the agent’s own tools refuse to write it:skill_managerefuses a skill the image ships for its profile, and the file tools refuse any path under the profile’sskills/orscripts/(deploy/docker/patches/skill_manage_image_owned.py) — so an upgraded pod runs the image’s skills, not whichever version first created its volume, and a skill deleted from the image disappears. (One mode-gated overlay rides that replace — seea2a/persona/README.md.) The profile’s own runtime state (USER.md,memory/,sessions/,profile.yaml) is untouched. A Cluster Agent’s identity-stampedconfig.yamlis back-filled rather than replaced — see how config reaches each profile. - The profile’s runtime workspace at
$HERMES_HOME/profiles/<profile>/skills—HERMES_HOMEdefaults to/opt/data, so the Platform Agent’s is/opt/data/profiles/platform/skills. This path is backed by the agent’s persistent volume. Note it is not/opt/data/skills: that is thedefaultprofile’s home, which belongs to the Planning Agent, andagents/chat/config.yamldisables theskillstoolset there — a skill dropped in that directory is loaded by nothing.
That gives you two ways to bring in additional skills — for example from the upstream google/skills catalog.
Method 1 — bake into a custom image (production)
Section titled “Method 1 — bake into a custom image (production)”Reproducible and immutable: the skill ships inside the container.
-
Copy the skill directory into
agents/platform/skills/<skill>/(it must containSKILL.mdplus anyreferences/). -
Build and push the
platformimage stage:Terminal window docker build -f deploy/docker/Dockerfile --target platform \-t my-registry/kube-agents/platform-agent:v1.1.0 .docker push my-registry/kube-agents/platform-agent:v1.1.0The build fails if a shell command in any Markdown file of the copied skill, outside
scripts/, is one the agent’s command scanner would refuse, as in step 3 of Adding a new skill. -
Point the
PlatformAgentCR at the new image and apply it:apiVersion: kubeagents.x-k8s.io/v1alpha1kind: PlatformAgentmetadata:name: platform-agentnamespace: kubeagents-systemspec:deployment:image: my-registry/kube-agents/platform-agenttag: v1.1.0
The operator rolls the Deployment and the new skill loads on boot.
Method 2 — inject into the running pod (development)
Section titled “Method 2 — inject into the running pod (development)”Faster for iterating: drop the skill into the target profile’s persistent workspace without
rebuilding. Copy into the profile that should load the skill — profiles/platform/skills for the
Platform Agent, profiles/cluster-<name>/skills for one Cluster Agent.
# The agent pod carries the label app=platform-agent-gateway; the container is `platform-agent`.AGENT_POD=$(kubectl get pods -n kubeagents-system \ -l app=platform-agent-gateway -o jsonpath='{.items[0].metadata.name}')
kubectl cp <skill-dir>/ \ kubeagents-system/$AGENT_POD:/opt/data/profiles/platform/skills/<skill-dir> -c platform-agentVerify it landed:
kubectl exec -n kubeagents-system -it $AGENT_POD -c platform-agent -- \ ls -la /opt/data/profiles/platform/skills/<skill-dir>The runtime discovers the skill on its next relevant turn. It does not survive a pod restart: the entrypoint replaces each specialist profile’s skills/ from the baked template on every start, so an injected skill lasts only as long as the pod — and so does a skill the agent authors for itself through skill_manage, which is why a gap in a shipped skill is something the agent reports rather than patches. That is the point of Method 2 — it is an iteration loop, not a deployment mechanism. Bake the skill into the image (Method 1) to keep it.
Skill vs. governance SOP vs. cron job
Section titled “Skill vs. governance SOP vs. cron job”A few related concepts that are easy to confuse:
- Skill — a reusable capability the agent loads when relevant. Lives in
skills/. - Governance SOP — a fleet-wide operating procedure (e.g. “audit blueprints daily”). Lives in
governance/. Invoked by cron jobs. - Cron job — a scheduled prompt that fires an SOP or skill on a timer. Lives in
cron/jobs.json.
Skills are on-demand tools; SOPs are the codified playbooks; cron jobs are the schedules that fire them.
Where to go next
Section titled “Where to go next”- Skill catalog — every skill with description and source link.
- Governance SOPs — the fleet-wide playbooks.
- Autonomous watchdogs — the cron jobs that invoke them.