Manifest Reference
Complete reference for all fields in a Scarab-Runtime agent manifest.
Top-level structure
apiVersion: scarab/v1 # Required. Must be exactly "scarab/v1".
kind: AgentManifest # Required. Must be exactly "AgentManifest".
metadata: # Required.
name: <string>
version: <semver>
description: <string> # Optional.
spec: # Required.
...
metadata
| Field | Required | Description |
|---|---|---|
name | Yes | Unique agent name. Used in ash agent run, hierarchy display, and audit entries. |
version | Yes | SemVer string (e.g. 1.0.0). |
description | No | Human-readable description. |
spec.trust_level
Required. Controls the sandbox permissions and capability ceiling.
| Value | Description |
|---|---|
untrusted | Maximum isolation. No filesystem or network access. |
sandboxed | Limited access within a sandbox. Default for most agents. |
trusted | Broader access. Can write files and use local network. |
privileged | Full access. Reserved for system agents. |
Trust levels form a strict ordering: untrusted < sandboxed < trusted < privileged. An agent cannot hold capabilities that exceed its trust level.
spec.capabilities
Required. List of capability strings the agent may use.
capabilities:
- fs.read
- fs.write:/home/agent/workspace/**
- tool.invoke:lm.complete
- tool.invoke:web.*
- secret.use:openai-key
- mcp.github.*
Format: <domain>.<action>[:<scope>]. Scope supports glob matching (* = one segment, ** = multiple segments).
See the Capability Reference for the full list.
spec.task
Optional. The agent's goal or instruction. Injected as SCARAB_TASK at spawn time.
task: "Summarize the latest news about renewable energy in 3 bullet points."
Can be overridden at runtime with ash agent run <name> --task <text>.
spec.model
Optional. Preferred LLM model identifier passed to lm.complete. Injected as SCARAB_MODEL.
model: "anthropic/claude-opus-4-6"
If absent, the OS router selects a model (future phase).
spec.runtime
Optional. Execution runtime. Default: rust.
| Value | Description |
|---|---|
rust | Native compiled Rust binary. Uses spec.command. |
python3.12 | Python 3.12 in a managed venv. Uses spec.entrypoint. |
python3.11 | Python 3.11 in a managed venv. Uses spec.entrypoint. |
node22 | Node.js 22.x. Uses spec.entrypoint. |
spec.command
Optional. Path to the agent binary (Rust runtime). Absolute or relative to install_dir.
command: target/debug/my-agent
Mutually exclusive with spec.entrypoint.
spec.entrypoint
Optional. Path to the Python or Node script (non-Rust runtimes). Relative to install_dir.
entrypoint: src/agent.py
spec.args
Optional. Arguments passed to the agent binary/script.
args:
- "--config"
- "/etc/my-agent/config.toml"
spec.packages
Optional. Packages to install into the runtime environment at first spawn.
packages:
- requests
- numpy==1.26.0
For Python: pip packages. For Node: npm packages. Cached by SHA-256 of the sorted list.
spec.resources
Optional. Resource limits enforced via cgroups v2.
resources:
memory_limit: 512Mi # Default: 256Mi
cpu_shares: 200 # Default: 100 (relative weight)
max_open_files: 128 # Default: 64 (file descriptor limit)
| Field | Default | Description |
|---|---|---|
memory_limit | 256Mi | Memory limit string: 256Mi, 1Gi, 512M, etc. |
cpu_shares | 100 | cgroup cpu.shares relative weight |
max_open_files | 64 | RLIMIT_NOFILE file descriptor limit |
spec.network
Optional. Network access policy enforced via nftables.
network:
policy: allowlist # none | local | allowlist | full
allowlist:
- "api.openai.com:443"
- "*.example.com:443"
policy value | Description |
|---|---|
none | No outbound network access (default) |
local | Loopback and LAN only |
allowlist | Only the listed host:port entries |
full | Unrestricted outbound access (requires trusted or higher) |
allowlist entries are host:port strings; host supports glob patterns.
spec.lifecycle
Optional. Restart and timeout behavior.
lifecycle:
restart_policy: on-failure # never | on-failure | always
max_restarts: 3 # Default: 3
timeout_secs: 3600 # Default: 3600 (1 hour). Must be > 0.
| Field | Default | Description |
|---|---|---|
restart_policy | on-failure | When to restart the agent |
max_restarts | 3 | Maximum restart attempts before giving up |
timeout_secs | 3600 | Wall-clock timeout; agent is terminated if exceeded. Must be > 0. |
spec.workspace
Optional. Overlay filesystem workspace configuration.
workspace:
retention: delete # delete | archive | persist
max_snapshots: 50 # Default: 50. 0 = unlimited.
snapshot_policy: before_act # before_act | after_observe | manual
| Field | Default | Description |
|---|---|---|
retention | delete | What to do with the workspace on terminate: delete, archive, persist |
max_snapshots | 50 | Maximum retained snapshots (oldest are pruned) |
snapshot_policy | before_act | When to auto-snapshot: before_act, after_observe, or manual |
spec.scheduler
Optional. Scheduling hints.
scheduler:
priority: 50 # Default: 50. Range: 1 (lowest) – 100 (highest).
cost_budget: 5.0 # Default: unlimited. Must be > 0 if set.
| Field | Default | Description |
|---|---|---|
priority | 50 | Scheduling priority 1–100 |
cost_budget | (none) | Lifetime cost budget in abstract units; agent is suspended when exceeded |
spec.planning_mode
Optional. How plan deviations are handled.
planning_mode: advisory # advisory | strict
| Value | Description |
|---|---|
advisory | Plan deviations are logged but not blocked (default) |
strict | Plan deviations cause the action to be rejected |
spec.secret_policy
Optional. Pre-approval policies applied automatically at spawn time. Secrets must still be registered separately with ash secrets add.
secret_policy:
- label: "Standard OpenAI access"
secret_pattern: "openai-key" # glob
tool_pattern: "web.fetch" # glob
host_pattern: "api.openai.com" # optional glob
expires_at: "2027-01-01T00:00:00Z" # optional ISO-8601
max_uses: 1000 # optional
agent_matcher: # optional; default: any
type: any # any | by_id | by_name_glob | by_trust_level
| Field | Required | Description |
|---|---|---|
label | Yes | Human-readable policy name shown in audit entries |
secret_pattern | Yes | Glob matching secret names |
tool_pattern | Yes | Glob matching tool names |
host_pattern | No | Glob matching destination host (for web.fetch) |
expires_at | No | ISO-8601 expiry; policy stops applying after this time |
max_uses | No | Auto-disable after N approvals |
agent_matcher | No | Which agents this rule applies to (default: any) |
agent_matcher types
| Type | Extra field | Description |
|---|---|---|
any | - | Applies to all agents (default) |
by_id | id: <uuid> | Applies to one specific agent |
by_name_glob | pattern: <glob> | Applies to agents whose name matches |
by_trust_level | level: <trust-level> | Applies to agents at or above the given trust level |
spec.mcp_servers
Optional. Names of MCP servers (registered via ash mcp add) to auto-attach at spawn time. Inline server definitions are also supported.
mcp_servers:
- github # pre-registered name
- name: inline-server # inline definition
transport: stdio
command: my-mcp-server
Server definitions (command, URL, credentials) live in agentd's MCP store, not in the manifest. See Manifest Auto-Attach.
Phase 9 Fields
spec.injection_policy
Optional. Prompt injection defence policy applied to all lm.* tool calls made by this agent (Phase 9.1).
injection_policy: dual_validate # none | delimiter_only | dual_validate
| Value | Description |
|---|---|
none | No protection. Suitable for fully-trusted agents on internal data only. |
delimiter_only | Wrap external content in <external_content>…</external_content> delimiters (default for trusted) |
dual_validate | Same as delimiter_only, plus a secondary classifier LLM call screens for injection patterns (default for untrusted/sandboxed) |
When absent, the default is derived from trust_level: untrusted/sandboxed → dual_validate, trusted → delimiter_only, privileged → none.
spec.model_policy
Optional. Determines how agentd selects a model for lm.* tool calls when the agent does not provide one explicitly (Phase 9.3). Default: explicit.
model_policy: cheapest # explicit | cheapest | fastest | most_capable
| Value | Description |
|---|---|
explicit | Use the model from spec.model or the per-call model field as-is (default) |
cheapest | Select the lowest-cost model within the remaining cost budget |
fastest | Select the model with the lowest latency hint |
most_capable | Select the highest-capability model within budget |
See SCARAB_DEFAULT_MODEL for the fallback when policy is explicit and no model is set.
spec.sensitive
Optional. Mark this agent as handling sensitive data from spawn time (Phase 9.2). Default: false.
sensitive: true
When true, the agent starts with the sensitive flag set permanently. Combined with the tainted flag (set automatically when an Input-category tool is called), this triggers the runtime exfiltration gate for all Output-category tool calls (e.g. net.send, email.send).
spec.control_schema
Optional. JSON Schema (draft-07) validated against every write to a control.* blackboard key made by this agent (Phase 9.2.3). Writes that fail validation are rejected before any reader sees them.
control_schema:
type: object
required: [action]
properties:
action:
type: string
enum: [approve, reject, escalate]
reason:
type: string
null or absent means no schema enforcement on control writes.
Complete annotated example
apiVersion: scarab/v1
kind: AgentManifest
metadata:
name: report-agent
version: 1.2.0
description: Fetches data and produces a daily analytics report.
spec:
trust_level: trusted
task: "Generate the daily analytics report for {{date}}."
model: "anthropic/claude-opus-4-6"
runtime: rust
command: report-agent
capabilities:
- tool.invoke:lm.complete
- tool.invoke:web.fetch
- tool.invoke:fs.write:/home/agent/reports/**
- secret.use:analytics-api-key
- obs.append
- memory.read:*
- memory.write:*
resources:
memory_limit: 1Gi
cpu_shares: 200
max_open_files: 128
network:
policy: allowlist
allowlist:
- "api.analytics.example.com:443"
lifecycle:
restart_policy: on-failure
max_restarts: 2
timeout_secs: 7200
workspace:
retention: archive
max_snapshots: 10
snapshot_policy: before_act
scheduler:
priority: 70
cost_budget: 10.0
secret_policy:
- label: "Analytics API - daily report"
secret_pattern: "analytics-api-key"
tool_pattern: "web.fetch"
host_pattern: "api.analytics.example.com"
mcp_servers:
- github
# Phase 9 fields
injection_policy: delimiter_only
model_policy: cheapest
sensitive: false