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

FieldRequiredDescription
nameYesUnique agent name. Used in ash agent run, hierarchy display, and audit entries.
versionYesSemVer string (e.g. 1.0.0).
descriptionNoHuman-readable description.

spec.trust_level

Required. Controls the sandbox permissions and capability ceiling.

ValueDescription
untrustedMaximum isolation. No filesystem or network access.
sandboxedLimited access within a sandbox. Default for most agents.
trustedBroader access. Can write files and use local network.
privilegedFull 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.

ValueDescription
rustNative compiled Rust binary. Uses spec.command.
python3.12Python 3.12 in a managed venv. Uses spec.entrypoint.
python3.11Python 3.11 in a managed venv. Uses spec.entrypoint.
node22Node.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)
FieldDefaultDescription
memory_limit256MiMemory limit string: 256Mi, 1Gi, 512M, etc.
cpu_shares100cgroup cpu.shares relative weight
max_open_files64RLIMIT_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 valueDescription
noneNo outbound network access (default)
localLoopback and LAN only
allowlistOnly the listed host:port entries
fullUnrestricted 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.
FieldDefaultDescription
restart_policyon-failureWhen to restart the agent
max_restarts3Maximum restart attempts before giving up
timeout_secs3600Wall-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
FieldDefaultDescription
retentiondeleteWhat to do with the workspace on terminate: delete, archive, persist
max_snapshots50Maximum retained snapshots (oldest are pruned)
snapshot_policybefore_actWhen 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.
FieldDefaultDescription
priority50Scheduling 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
ValueDescription
advisoryPlan deviations are logged but not blocked (default)
strictPlan 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
FieldRequiredDescription
labelYesHuman-readable policy name shown in audit entries
secret_patternYesGlob matching secret names
tool_patternYesGlob matching tool names
host_patternNoGlob matching destination host (for web.fetch)
expires_atNoISO-8601 expiry; policy stops applying after this time
max_usesNoAuto-disable after N approvals
agent_matcherNoWhich agents this rule applies to (default: any)

agent_matcher types

TypeExtra fieldDescription
any-Applies to all agents (default)
by_idid: <uuid>Applies to one specific agent
by_name_globpattern: <glob>Applies to agents whose name matches
by_trust_levellevel: <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
ValueDescription
noneNo protection. Suitable for fully-trusted agents on internal data only.
delimiter_onlyWrap external content in <external_content>…</external_content> delimiters (default for trusted)
dual_validateSame 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/sandboxeddual_validate, trusteddelimiter_only, privilegednone.

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
ValueDescription
explicitUse the model from spec.model or the per-call model field as-is (default)
cheapestSelect the lowest-cost model within the remaining cost budget
fastestSelect the model with the lowest latency hint
most_capableSelect 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