Architecture Overview
CUST/OS is an ATAK plugin that loads Lua skills from the device and makes their tools available to an AI agent. This page describes the main subsystems and how they connect.
The big picture
ATAK (host process)
┌────────────────────────────────────┐
│ CUST/OS plugin │
│ │
│ UI (NavBar + panels) │
│ │ │
│ ▼ │
│ Agent runtime (ReAct loop) │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ Skill Inference Security │
│ runtime router (hooks, gates) │
│ │
│ Memory · Voice · Automation · IPC │
└────────────────────────────────────┘
│
▼
/sdcard/atak/custos/
├── config/custos.yaml
├── skills/... (operator-authored)
├── automations/... (operator-authored)
└── models/... (on-device weights)
Skills are installed separately from the APK. The operator can inspect and edit their files on disk; the runtime reloads them when they change.
Lifecycle
The plugin boots in ordered phases:
- Configuration -- read the operator's config file
- Security -- initialize the audit log and skill verification
- Memory -- open the conversation store, mark any incomplete chains from a prior crash
- Inference -- connect to configured LLM, embedding, vision, and voice providers
- Agent -- initialize the script sandbox
- Skills -- scan the skills directory, parse metadata, start the file watcher for hot reload
- Voice -- initialize push-to-talk, speech-to-text, and text-to-speech routing
- IPC -- register the cross-device delegation listener
- Scheduling -- start the automation scheduler
- UI -- created lazily when the operator opens the panel
The first three phases are fatal -- if any fails, the plugin enters a degraded state and reports the error. The remaining phases tolerate failures and continue with reduced capability.
On-device models start asynchronously so the UI does not wait for model loading to finish.
Agent runtime
The agent uses a ReAct loop -- a published reasoning pattern where the model plans, acts, observes, and repeats:
- Build context: assemble the system prompt, selected skills, and conversation history.
- Call the LLM and stream tokens to the operator in real time.
- If the response includes tool calls, evaluate security rules, gate on impact level, execute the tools, and append results.
- Loop back to step 2 with updated context.
- Stop when the model responds with text only (no tool calls) or the iteration limit is reached.
The operator can interrupt or redirect the agent mid-loop. Only one reasoning loop runs at a time. See The ReAct loop.
Inference layer
The inference router is a per-task failover system. Each task -- chat, embedding, transcription, text-to-speech, vision -- has its own list of providers sorted by priority. On every call the router walks the list, skips unhealthy or blocked providers, and tries the next one.
Providers are grouped by tier (handheld, pack, mobile, mounted, command-post, cloud). Security modes filter these tiers: standalone allows handheld providers, and EMCON allows handheld and wired pack providers. These settings control inference routing, not the device's radios. Health checks let the router skip unavailable providers. See Inference routing and Tiers and priority.
Script runtime
Skills are sandboxed scripts that run inside a controlled environment with:
- A restricted set of device APIs the script can access
- A blocklist of dangerous operations (process execution, file deletion, network sockets)
- Filesystem access limited to the CUST/OS data directory
- Per-execution instruction limits to prevent runaway scripts
- Concurrency limits to prevent resource exhaustion
Scripts interact with ATAK through injected bindings: functions for querying the map, placing markers, accessing other plugins, and scheduling automations. The operator's configuration controls which bindings are available. See How skills are loaded and shared.
Memory
Each conversation maintains its own message history. When the conversation grows long, CUST/OS summarizes older messages to preserve important tactical information (coordinates, callsigns, decisions, tool results) while staying within the model's context window. The operator can have multiple parallel conversations for different tasks.
A separate persistent memory layer stores key-value facts (callsigns, objective locations, standing orders) that survive across conversations and are automatically included in the agent's context every turn. See Memory and context.
Voice pipeline
Push-to-talk voice interaction:
- The operator long-presses the PTT button and speaks.
- Audio is captured and sent to a speech-to-text provider.
- The transcript is fed to the agent as a normal message.
- The agent's final response is sent to a text-to-speech provider and played through the speakers.
If no speech-to-text provider is available, the PTT button is disabled and the operator uses text input. Voice providers follow the same tier and failover rules as all other providers.
Automation
Three trigger types let CUST/OS act without operator input. The trigger shape is auto-detected from the expression — there's no @type annotation to pick:
- Scheduled — cron expressions or one-shot timers (
0 6 * * *,in 20m) - Monitors — duration-based intervals (
15s,30m,2h); optional ALL_CLEAR convention surfaces status in the UI - Events — ATAK broadcast actions, with filter logic implemented as a guard clause inside the Lua body
When an automation fires, its run(ctx) function executes as Lua. A routine check can run without invoking a model. To request model reasoning, the script explicitly calls tools.call("delegate", {agent_name = "...", task = "..."}), which starts an agent turn with the named specialist. See The automation model.
Security
CUST/OS checks tool execution and provider selection through these controls:
- Sandboxing -- skills run in restricted environments with controlled API access
- Approval gates -- high-impact actions require operator confirmation
- Pre/post hooks -- configurable rules that allow, deny, or require approval for specific tools
- Local audit log -- records model requests, tool execution, approvals, and security events; SQLite triggers block updates and deletes through ordinary application access
- Classification filtering -- the router excludes providers below the configured classification level
- Skill trust levels (WIP) -- skills carry a trust level (verified vs community). The signature verification path exists in code but is not yet called from the skill loader;
security.requirePkiis a declared intent, not enforced behavior in this release.
See Trust and classification for the checks at each stage and their current limits.
Cross-device delegation (WIP)
The cross-device delegation transport is designed to send a task to a specialist on a remote CUST/OS node over the TAK mesh. The request travels as a CoT broadcast, and the response returns as a tool result. The remote node handles its tool execution, approval gates, and audit record.
The transport is included in the APK but has not been validated against a second live CUST/OS node. Local delegation runs specialist agents on the same device, each using its configured provider.
See also
- The ReAct loop -- the agent's core reasoning pattern
- How skills are loaded and shared -- skill files, reloading, and distribution
- Inference routing -- provider selection and failover
- Memory and context -- what the agent remembers and how
- The automation model -- scheduled, monitor, and event triggers
- Tiers and priority -- security modes and provider classification
- Trust and classification -- the layered security model