Skill Format Reference

Every skill is a directory under /sdcard/atak/custos/skills/<group>.<name>/ containing a SKILL.md file with YAML frontmatter and one or more .lua script files.

File structure

custos.markers/
  SKILL.md
  place_marker.lua
  find_items.lua
  delete_markers.lua

The directory name must match <group>.<name> from the frontmatter.

SKILL.md frontmatter

---
group: custos
name: markers
description: Place, find, and delete map markers
script_paths:
  - custos.markers/place_marker.lua
  - custos.markers/find_items.lua
  - custos.markers/delete_markers.lua
  - custos.tactical_picture/get_self_position.lua
tags:
  - markers
  - map
  - navigation
scope: all
examples:
  - "place a marker at 38.9, -77.0"
  - "drop a hostile marker"
  - "find all friendly markers"
  - "mark this position"
---
Field Type Required Meaning
group string yes First half of the skill ID (typically custos)
name string yes Second half of the skill ID
description string yes One-line description shown in the agent's system prompt
script_paths list[string] yes Paths to Lua files (full paths from the skills root directory)
tags list[string] no Keywords used by the skill selector for matching
scope string no all (default) or orchestrator
examples list[string] no Representative user queries for this skill (improves retrieval accuracy)
template string no Extra block injected into the system prompt when this skill is selected

Script paths

script_paths are paths from /sdcard/atak/custos/skills/, not from the current directory. This lets a skill reference scripts that live in another skill:

script_paths:
  - custos.markers/place_marker.lua          # script in this skill
  - custos.tactical_picture/get_self_position.lua  # script from another skill

If you delete a skill whose scripts are referenced by other skills, those dependent skills will fail to load.

Markdown body

Everything after the YAML frontmatter is markdown. The agent sees this text when the skill is selected, so use it to:

  • Explain when the skill should be used
  • Document rules or assumptions
  • Show examples
  • Warn about pitfalls
# Markers

Tools for placing, finding, deleting, and querying markers and map items
on the ATAK map.

## Rules
- Always confirm with the operator before deleting more than 5 markers.
- Use the CoT type a-h-G for hostile, a-f-G for friendly, a-n-G for neutral.

Scopes

scope: orchestrator

Skills with scope: orchestrator are only available to the top-level agent, not to specialist sub-agents. This prevents sub-agents from recursively delegating. Default is scope: all.

Examples

examples:
  - "place a marker at 38.9, -77.0"
  - "drop a hostile marker"
  - "find all friendly markers"
  - "mark this position"

Example queries improve skill selection accuracy by matching how operators actually phrase requests. Write 3-5 examples per skill covering varied phrasing -- include the way a soldier would say it on comms, not just formal descriptions.

Template

template: |
  When responding about marker operations, always:
  - Confirm coordinates in DD format
  - Reference markers by callsign, never by UID

The template block is inserted into the system prompt when this skill is selected. Useful for skill-specific style guidance, required output formats, or domain conventions.

LDoc annotations on Lua scripts

Inside each .lua file, functions with a @tool annotation become callable agent tools. The annotation block lives in a Lua comment directly above the function:

--- One-line summary
-- @tool tool_name
-- @description Longer description used by the LLM to decide when to call this
-- @tparam string param_name What this parameter is for
-- @tparam number [optional_param=42] Optional with default value
-- @tparam string [type=a-f-G] Optional with default
-- @impact PROCEDURAL
function tool_name(params)
    -- params.param_name and params.optional_param available
    return { status = "success" }
end

Annotations

Annotation Meaning
@tool <name> Registers this function as an agent tool. Must match the function name.
@description <text> One-sentence description shown to the LLM
@tparam <type> <name> <text> Required parameter
@tparam <type> [<name>=<default>] <text> Optional parameter with default
@impact <level> One of READ_ONLY, INFORMATIONAL, PROCEDURAL, SIGNIFICANT, STRATEGIC, LETHAL

Functions without a @tool annotation are still callable from other Lua functions in the same skill, but the agent never sees them. Use this for helper functions.

Parameter types are documentation for the LLM -- they are not enforced at runtime.

Impact levels

Level Meaning Approval gate
READ_ONLY Query, no side effects No
INFORMATIONAL Logging or memory writes No
PROCEDURAL Single user-visible action No (by default)
SIGNIFICANT Multi-step or harder-to-reverse action Yes
STRATEGIC Coarse / high-impact actions like package distribution, comms broadcasts, or beacon activation Yes
LETHAL Reserved for actions with irreversible kinetic consequences Yes

Unrecognized values fall back to PROCEDURAL with a warning in logcat — match one of the six names exactly.

Tool result format

Return a Lua table from the tool function. It is serialized to JSON and fed back to the agent:

return {
    status = "success",      -- or "error" or "partial"
    result = ...,            -- the actual payload
}

If the tool throws an error, the runtime automatically returns { status = "error", error = <message> }.

See also