Agent Manifest Reference
Complete specification for the AgentManifest YAML format (v1.0) — schema, field definitions, examples, and validation configuration.
Agent Manifest Reference
API Version: 100monkeys.ai/v1 | Kind: Agent | Status: Canonical
The Agent Manifest is the source of truth for an Agent's identity, capabilities, security constraints, and execution requirements. It allows the Aegis Host to run agents safely and deterministically within the Membrane.
The manifest uses Kubernetes-style declarative format (apiVersion/kind/metadata/spec) for consistency across all AEGIS resources.
Annotated Full Example
apiVersion: 100monkeys.ai/v1 # required; must be exactly this value
kind: Agent # required; must be exactly "Agent"
metadata:
name: python-coder # required; unique DNS-label name (lowercase, alphanumeric, hyphens)
version: "1.0.0" # required; semantic version. (name + version) must be unique.
# Overwriting an existing version requires the `force` parameter in management tools.
description: "Writes Python solutions to programming tasks." # optional
labels: # optional; key-value pairs for filtering and discovery
role: worker
team: platform
annotations: # optional; non-identifying metadata
maintainer: "[email protected]"
spec:
# security_context: aegis-system-agent-runtime # operators only
# Runtime configuration (StandardRuntime path: language + version)
runtime:
language: python # StandardRuntime: required if image not specified
version: "3.11" # StandardRuntime: required if image not specified
isolation: docker # optional; inherit | firecracker | docker | process
# image_pull_policy: IfNotPresent # optional for StandardRuntime; default: IfNotPresent
# OR, for CustomRuntime (uncomment to use private/custom image):
#
# runtime:
# image: "ghcr.io/my-org/custom-agent:v1.0" # CustomRuntime: fully-qualified image
# image_pull_policy: IfNotPresent # optional; Always | IfNotPresent | Never
# isolation: docker # optional; inherit | firecracker | docker | process
#
# NOTE: Mutual Exclusion — specify EITHER (language + version) OR image, NOT both.
# Task definition (instructions for the agent)
task:
instruction: | # optional; high-level task guidance
Write a Python solution to the given problem.
Save the solution to /workspace/solution.py.
Run it to verify correctness and write a JSON summary to /workspace/result.json.
prompt_template: | # optional; Handlebars template for LLM prompts
{{instruction}}
User: {{input}}
{{#if previous_error}}
Previous attempt failed: {{previous_error}}
{{/if}}
Assistant:
# Security policy (deny-by-default; declare only what is needed)
security:
network:
mode: allow # allow | deny | none
allowlist:
- pypi.org
- api.github.com
filesystem:
read:
- /workspace
- /agent
write:
- /workspace
resources:
cpu: 1000 # millicores (1000 = 1 CPU core)
memory: "1Gi" # human-readable: "512Mi", "1Gi", "2Gi"
disk: "5Gi" # human-readable disk quota
timeout: "300s" # human-readable: "300s", "5m", "1h"
# Volume mounts (ephemeral and persistent storage)
volumes:
- name: workspace
type: seaweedfs # Default backend; seaweedfs | opendal | hostPath | seal
storage_class: ephemeral # ephemeral | persistent
mount_path: /workspace # absolute path inside container
access_mode: read-write # read-write | read-only
ttl_hours: 1 # required for ephemeral; hours until auto-deletion
size_limit: "5Gi" # maximum volume size (Kubernetes-style: "500Mi", "5Gi")
- name: shared-data
type: seaweedfs
storage_class: persistent
mount_path: /workspace/shared-data
access_mode: read-only
source:
volume_id: "vol-a1b2c3d4-..." # pin to existing volume
- name: cloud-datasets
type: opendal # External Volume
provider: s3
config:
bucket: my-ml-datasets
endpoint: "https://s3.us-east-1.amazonaws.com"
storage_class: persistent
mount_path: /workspace/datasets
access_mode: read-only
# Execution strategy and validation
execution:
mode: iterative # one-shot | iterative
max_iterations: 10 # range: 1–20; default: 10
iteration_timeout: "60s" # per-iteration timeout (default: 300s); "30s", "60s", "5m"
memory: false # enable Cortex memory system
validation:
- type: exit_code
expected: 0
- type: json_schema
schema:
type: object
required: ["solution_path", "output"]
properties:
solution_path:
type: string
output:
type: string
- type: semantic
judge_agent: "output-judge"
criteria: "Ensure the final output is correct and complete."
min_score: 0.80
min_confidence: 0.70
tool_validation:
- type: semantic # Inner-loop pre-execution semantic judge for tool calls
judge_agent: "security-judge"
criteria: "Ensure the tool call is safe and aligns with the agent's goal."
min_score: 0.85
min_confidence: 0.0
timeout_seconds: 300
# MCP tools the agent may invoke
tools:
- name: filesystem
server: "mcp:filesystem"
config:
allowed_paths:
- /workspace
access_mode: read-write
- name: web-search
server: "mcp:web-search"
config:
allowed_domains:
- pypi.org
- docs.python.org
max_results_per_query: 10
# Environment variables (static, secret references, config references)
env:
PYTHONUNBUFFERED: "1"
LOG_LEVEL: "debug"
OPENAI_API_KEY: "secret:openai-key" # injected from secure vaultField Reference
Top-Level Fields
| Field | Type | Required | Description |
|---|---|---|---|
apiVersion | string | ✓ | Must be 100monkeys.ai/v1. |
kind | string | ✓ | Must be Agent. |
metadata | object | ✓ | Manifest metadata. |
spec | object | ✓ | Agent specification. |
metadata
| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✓ | Unique agent name. Pattern: ^[a-z0-9][a-z0-9-]{0,62}$. |
version | string | ✓ | Manifest schema version. Semantic versioning (e.g., "1.0.0"). |
description | string | Human-readable description of the agent's purpose. | |
labels | map[string]string | Key-value labels for categorization and discovery. Common keys: role, category, team, environment. | |
annotations | map[string]string | Arbitrary non-identifying metadata (e.g., maintainer, docs). |
spec
| Field | Type | Required | Description |
|---|---|---|---|
security_context | string | Named security context for executions. Operators only. | |
output_handler | object | Egress handler that fires after execution completes. See spec.output_handler. | |
runtime | object | ✓ | Runtime configuration. |
task | object | Task definition (instructions for the agent). | |
input_schema | JSON Schema object | Declares named inputs accepted at execution time. See spec.input_schema. | |
security | object | Security policy (deny-by-default). | |
volumes | object[] | Volume mount declarations. | |
execution | object | Execution strategy and acceptance criteria. | |
context | object[] | Additional resources attached to the execution. | |
schedule | object | Automatic execution scheduling. | |
delivery | object | Output delivery destinations. | |
tools | object[] or string[] | MCP tools the agent may invoke. | |
env | map[string]string | Environment variables injected into the container. |
spec.security_context
| Field | Type | Required | Default |
|---|---|---|---|
security_context | string | No | (inherits caller context) |
Declares the named security context this agent's executions run under. When set, overrides the caller's execution context at runtime.
Permitted values are platform-configured security context names. On the standard
platform, the only valid value is aegis-system-agent-runtime.
Only platform operators may set this field. Consumer accounts receive a 403 Forbidden
error if they attempt to register an agent with security_context set.
Omitting this field (the default) means the agent runs under the calling user's or workflow's security context.
spec.output_handler
| Field | Type | Required | Default |
|---|---|---|---|
output_handler | object | No | (omitted) |
Declares an egress handler that fires after agent execution completes. The handler receives the agent's final output and routes or transforms it through a delivery channel. When omitted, no post-execution delivery occurs.
Failure behavior: Controlled by the required field on the handler object.
required value | Handler failure effect |
|---|---|
true | The execution is marked failed. |
false (default) | Failure is logged; execution status is unaffected. |
Workflow override: When an agent is invoked from a workflow, the workflow
state's output_handler takes precedence over the agent manifest's declaration.
Four handler types are supported:
type: agent
Spawns a named agent and passes the output to it as input. Use this to chain a formatter, validator, or delivery agent after execution.
spec:
output_handler:
type: agent
agent_id: my-formatter-agent
required: false| Field | Type | Required | Description |
|---|---|---|---|
type | string | ✓ | Must be agent. |
agent_id | string | ✓ | Name of the agent to invoke. |
required | boolean | If true, handler failure marks execution failed. Default: false. |
type: webhook
POSTs the result to an external HTTP endpoint. Supports secret interpolation in headers and a Handlebars body template.
spec:
output_handler:
type: webhook
url: https://hooks.example.com/results
method: POST
headers:
Authorization: Bearer {{secret:my-token}}
body_template: '{"result": "{{output}}"}'
timeout_seconds: 30
required: true| Field | Type | Required | Description |
|---|---|---|---|
type | string | ✓ | Must be webhook. |
url | string | ✓ | Target URL. |
method | string | HTTP method. Default: POST. | |
headers | map[string]string | Request headers. Supports {{secret:<name>}} interpolation. | |
body_template | string | Handlebars template for the request body. Variable: {{output}}. | |
timeout_seconds | integer | Request timeout in seconds. Default: 30. | |
required | boolean | If true, handler failure marks execution failed. Default: false. |
type: mcp_tool
Invokes an MCP tool after execution — for example, sending a notification or writing to an external system.
spec:
output_handler:
type: mcp_tool
tool_name: slack.send_message
arguments:
channel: "#results"
text: "{{output}}"
required: false| Field | Type | Required | Description |
|---|---|---|---|
type | string | ✓ | Must be mcp_tool. |
tool_name | string | ✓ | Fully-qualified MCP tool name (e.g., slack.send_message). |
arguments | object | Tool arguments. Supports {{output}} interpolation. | |
required | boolean | If true, handler failure marks execution failed. Default: false. |
type: container
Runs a container to transform or deliver the output. The output is injected into
the command via {{output}} interpolation.
spec:
output_handler:
type: container
image: my-registry/formatter:latest
command: ["/bin/format", "--input", "{{output}}"]
required: false| Field | Type | Required | Description |
|---|---|---|---|
type | string | ✓ | Must be container. |
image | string | ✓ | Fully-qualified container image reference. |
command | string[] | Command and arguments. Supports {{output}} interpolation. | |
required | boolean | If true, handler failure marks execution failed. Default: false. |
spec.runtime
Supports two mutually exclusive runtime modes:
- StandardRuntime: Specify
language+version; orchestrator resolves to official Docker image - CustomRuntime: Specify
image(fully-qualified reference); orchestrator pulls from registry
Mutual Exclusion: Cannot specify both paths in one manifest.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
language | string | Conditional | StandardRuntime: Programming language (python, javascript, typescript, rust, go). Required unless image is specified. | |
version | string | Conditional | StandardRuntime: Language version (e.g., "3.11", "20"). Required if language is specified. | |
image | string | Conditional | CustomRuntime: Fully-qualified Docker image (e.g., ghcr.io/org/agent:v1.0). Required unless both language and version are specified. | |
image_pull_policy | string | IfNotPresent | Image caching strategy: Always (pull from registry every time), IfNotPresent (use cache if available, pull if missing), Never (cache only — fail if missing, no network attempt). See Container Registry & Image Management. | |
isolation | string | inherit | inherit | firecracker | docker | process | |
model | string | default | LLM model alias from aegis-config.yaml. |
Mutual Exclusion Validation Rules:
- ✅ Valid (StandardRuntime):
language: "python"+version: "3.11" - ✅ Valid (CustomRuntime):
image: "ghcr.io/org/custom:latest" - ❌ Invalid: Both
language+versionANDimagespecified - ❌ Invalid:
languagewithoutversion - ❌ Invalid:
versionwithoutlanguage - ❌ Invalid:
imagewithout fully-qualified format (missing/)
spec.task
| Field | Type | Required | Description |
|---|---|---|---|
instruction | string | High-level guidance for the agent (multi-line YAML |). Auto-enables semantic validation. | |
prompt_template | string | Handlebars template for constructing LLM prompts. Default: "{{instruction}}\n\nUser: {{input}}\nAssistant:". | |
input_data | object | Structured input parameters available at execution time. |
Prompt template variables: {{intent}}, {{instruction}}, {{input}}, {{iteration_number}}, {{previous_error}}, {{context}}.
To import community skill definitions as agent baselines, use the built-in skill-import workflow.
spec.input_schema
An optional JSON Schema object describing the named inputs this agent accepts at execution time. Declaring input_schema lets callers know exactly what to pass and enables automatic validation of execution inputs before the agent runs.
| Field | Type | Required | Description |
|---|---|---|---|
input_schema | JSON Schema object | Describes the named inputs accepted at execution time. Must be a JSON Schema object with type: object. |
The following JSON Schema property types are supported. The Zaru client context panel renders each type as a specific UI element:
| JSON Schema type | Zaru UI control |
|---|---|
string | Text input |
number / integer | Number spinner |
boolean | Checkbox |
enum | Dropdown select |
object | Nested form group |
array | Repeatable row builder |
intent and input
Every agent invocation accepts two optional fields on the execution request:
intent— natural-language steering. Describes what the caller wants the agent to achieve. Always available as{{intent}}in prompt templates (empty string when absent).input— structured data for the execution. Wheninput_schemais declared,inputmust conform to it (validated before dispatch; rejection = HTTP 422). Available as{{input}}(full JSON blob) and{{input.KEY}}(dot-notation when the value is an object).
These are complementary, not alternatives — intent steers the LLM with natural language; input supplies typed data.
intent | input | Rendered prompt |
|---|---|---|
| Present | Present (object) | {{intent}} available; {{input.KEY}} dot-notation available. |
| Present | Absent / empty | {{intent}} available; {{input}} is empty. |
| Absent | Present (object) | {{intent}} is empty; {{input.KEY}} dot-notation available. |
| Absent | Absent | Both empty; prompt rendered from spec.task.instruction only. |
| Any | Present (string) | {{input}} is the raw string value; no dot-notation. |
Example:
spec:
input_schema:
type: object
required:
- document_url
- output_format
properties:
document_url:
type: string
description: "URL of the document to process."
output_format:
type: string
enum: ["json", "markdown", "html"]
description: "Desired output format."
max_pages:
type: integer
description: "Maximum number of pages to process. Default: all pages."
include_metadata:
type: boolean
description: "Whether to include document metadata in the output. Default: false."aegis agent run document-processor \
--input '{"document_url": "https://example.com/report.pdf", "output_format": "json", "max_pages": 10}'Note:
spec.input_schemais a schema descriptor — it declares what inputs the agent accepts and validates them at invocation time. It is distinct fromspec.task.input_data, which is a map of default runtime values injected into the container environment at startup and is not validated.
Judge agents: When an agent is used as a judge in a
semanticormulti_judgevalidator, itsinput_schemaproperty names determine how the orchestrator maps evaluation data (output content, objective, criteria, etc.) to the judge's prompt. Declaringinput_schemain a judge manifest gives the judge structured access to all evaluation fields rather than receiving raw string content. See Judge Input Schema for the canonical property names.
spec.security
| Field | Type | Required | Description |
|---|---|---|---|
network.mode | allow | deny | none | Policy mode. allow = use allowlist; none = no network interface. | |
network.allowlist | string[] | Domain names and CIDR blocks permitted for outbound connections. | |
network.denylist | string[] | Domain names explicitly blocked (applied after allowlist). | |
filesystem.read | string[] | Paths inside container where reads are permitted. Glob patterns supported. | |
filesystem.write | string[] | Paths inside container where writes are permitted. Glob patterns supported. | |
filesystem.read_only | boolean | Set true to make all mounts read-only. | |
resources.cpu | integer | CPU limit in millicores (1000 = 1 core). Default: 1000. | |
resources.memory | string | Memory limit. Human-readable: "512Mi", "1Gi". Default: "512Mi". | |
resources.disk | string | Disk quota. Human-readable: "1Gi", "10Gi". Default: "1Gi". | |
resources.timeout | string | Total execution timeout. Human-readable: "300s", "5m", "1h". Max "1h". |
spec.volumes[]
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | ✓ | Local identifier. Must be unique within this manifest. | |
type | seaweedfs | opendal | hostPath | seal | seaweedfs | The storage backend mapping orchestrating this volume. | |
provider | string | Required for opendal | The specific cloud API (e.g. s3, gcs) or scheme. | |
config | object | Required for non-seaweedfs types | Configuration fields unique to the specific backend proxy mechanism. | |
storage_class | ephemeral | persistent | ✓ | Lifetime of the volume. | |
mount_path | string | ✓ | Absolute path inside the container, rooted at /workspace (e.g., /workspace, /workspace/datasets). | |
access_mode | read-write | read-only | ✓ | Access mode enforced by AegisFSAL. | |
ttl_hours | integer | Required for ephemeral | Hours until auto-deletion (e.g., 1, 24). | |
size_limit | string | no limit | Maximum volume size as a Kubernetes resource string (e.g., "500Mi", "5Gi"). Writes beyond this return ENOSPC. | |
source.volume_id | string | Required for persistent | UUID of an existing persistent volume. Supports Handlebars: {{input.dataset_volume_id}}. |
spec.execution
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
mode | iterative | one-shot | one-shot | Execution strategy. | |
max_iterations | integer | 10 | Maximum refinement loops. Range: 1–20. | |
iteration_timeout | string | "300s" | Per-iteration timeout. Human-readable: "30s", "60s", "5m". Each iteration gets this much time for LLM calls + tool invocations. | |
memory | boolean | false | Enable Cortex learning memory. | |
llm_timeout_seconds | integer | 300 | HTTP socket timeout for bootstrap.py LLM proxy calls in seconds. Applies to network requests from agent to orchestrator. | |
validation | ValidatorSpec[] | Ordered outer-loop validators executed after each iteration. | ||
tool_validation | ValidatorSpec[] | Ordered inner-loop tool-call validators. Current runtime consumes semantic entries for pre-execution judging; see Tool-Call Judging. |
spec.execution.validation
validation is an ordered list of ValidatorSpec entries executed after each iteration. Each variant has its own fields:
exit_code
| Field | Type | Default | Description |
|---|---|---|---|
expected | integer | 0 | Required exit code. |
min_score | float | 1.0 | Minimum score to accept this step. |
json_schema
| Field | Type | Default | Description |
|---|---|---|---|
schema | JSON Schema object | — | Schema applied to the output payload. |
min_score | float | 1.0 | Minimum score to accept this step. |
regex
| Field | Type | Default | Description |
|---|---|---|---|
pattern | string | — | Regular expression to match against the selected output stream. |
target | string | stdout | Output stream to inspect: stdout or stderr. |
min_score | float | 1.0 | Minimum score to accept this step. |
semantic
| Field | Type | Default | Description |
|---|---|---|---|
judge_agent | string | — | Deployed judge agent to spawn as a child execution. |
criteria | string | — | Human-readable rubric passed to the judge. |
min_score | float | 0.7 | Minimum score required to accept the output. |
min_confidence | float | 0.0 | Minimum self-reported confidence required. |
timeout_seconds | integer | 300 | Maximum wait time for the judge child execution in seconds. |
multi_judge
| Field | Type | Default | Description |
|---|---|---|---|
judges | string[] | — | Deployed judge agents to spawn in parallel. |
consensus | enum | weighted_average | Aggregation strategy used to combine judge results. |
min_judges_required | integer | 1 | Minimum number of judges that must complete. |
criteria | string | — | Human-readable rubric passed to each judge. |
min_score | float | 0.7 | Minimum score required to accept the output. |
min_confidence | float | 0.0 | Minimum self-reported confidence required. |
timeout_seconds | integer | 300 | Maximum wait time for all judge child executions in seconds. |
tool_validation is an ordered list of validator specifications. In the current runtime, only semantic entries are used for tool-call gating; they run before dispatch and can block the call synchronously. See Tool-Call Judging for the inner-loop contract.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
type | semantic | ✓ | Validator type used by the inner-loop tool gate. | |
judge_agent | string | ✓ | Deployed judge agent to spawn as a child execution. | |
criteria | string | ✓ | Human-readable rubric passed to the judge. | |
min_score | float | 0.7 | Minimum score required to allow the tool call. | |
min_confidence | float | 0.0 | Minimum self-reported confidence required to allow the tool call. | |
timeout_seconds | integer | 300 | Maximum wait time for the judge child execution in seconds. |
Tool-call judging is conjunctive: the orchestrator allows the tool only when both the score and confidence thresholds are satisfied.
If a non-semantic validator is present in tool_validation, it is ignored by the current inner-loop tool gate and should be documented as an outer-loop validator instead.
spec.tools[]
Tools can be declared in simple (string) or detailed (object) format.
Simple format:
tools:
- "mcp:filesystem"
- "mcp:web-search"
- "mcp:gmail"Detailed format:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✓ | Local name for this tool binding. |
server | string | ✓ | MCP server identifier (e.g., "mcp:filesystem"). |
config | object | Tool-specific configuration. |
Filesystem tool config (mcp:filesystem):
| Field | Type | Default | Description |
|---|---|---|---|
allowed_paths | string[] | ["/workspace"] | Permitted directory prefixes. |
access_mode | read-only | read-write | read-only | Write access mode. |
max_file_size_bytes | integer | 10485760 | Maximum file size per operation. |
Web search tool config (mcp:web-search):
| Field | Type | Default | Description |
|---|---|---|---|
allowed_domains | string[] | [] (all) | Restrict search results to these domains. |
max_results_per_query | integer | 10 | Maximum results returned per search. |
max_calls_per_execution | integer | 50 | Rate limit for search invocations. |
Gmail tool config (mcp:gmail):
| Field | Type | Default | Description |
|---|---|---|---|
allowed_operations | string[] | ["read","search"] | Permitted operations: read, search, send. |
max_messages_per_query | integer | 50 | Maximum messages returned per query. |
max_calls_per_execution | integer | 30 | Rate limit for Gmail API calls. |
allowed_labels | string[] | [] (all) | Restrict access to these Gmail labels. |
Builtin command executor (builtin:cmd):
cmd.run is not an MCP server. Use executor: "builtin:cmd" to enable in-container subprocess execution via the Dispatch Protocol. The server field is omitted; only name, executor, and config are used.
tools:
- name: cmd
executor: "builtin:cmd"
config:
subcommand_allowlist:
git: [clone, add, commit, push, pull, status, diff]
cargo: [build, test, fmt, clippy, check, run]
npm: [install, run, test, build, ci]
python: ["-m"]
env_var_denylist:
- OPENAI_API_KEY
timeout_ceiling_secs: 120
max_output_bytes: 524288| Field | Type | Default | Description |
|---|---|---|---|
subcommand_allowlist | object | — | Required. Map of command → [allowed_first_args]. Any cmd.run call with a command or first argument not in this map is rejected with a policy violation. |
env_var_denylist | string[] | [] | Additional env vars stripped before forwarding to the subprocess. Appended to the node-level global_env_denylist. |
timeout_ceiling_secs | integer | 300 | Maximum per-subprocess timeout this agent may request. Cannot exceed builtin_dispatchers.cmd.max_timeout_ceiling_secs in the node config. |
max_output_bytes | integer | 524288 | Maximum captured stdout+stderr per subprocess in bytes. Truncated output is signaled to the LLM with a notice. |
builtin:cmd is the only valid non-mcp: executor value. The subcommand_allowlist is the only required config field; all other fields inherit node-level defaults when omitted.
spec.env
Environment variable values support three formats:
| Format | Example | Description |
|---|---|---|
| Static string | "production" | Literal value. |
| Secret reference | "secret:openai-key" | Injected from secure vault (OpenBao). Never logged. |
| Config reference | "config:log_level" | From configuration store. |
Field Definitions
spec.runtime
Defines the execution environment for the agent.
StandardRuntime (Official Images)
When you specify language and version, the orchestrator resolves them to a deterministic official Docker image by consulting the StandardRuntime Registry committed to the repository. The registry enforces:
- No "latest" tags: Every language+version maps to an exact, immutable image tag
- Production-grade variants:
-slimfor Debian-based,-alpinefor Alpine (minimal image size) - Validation at execution time: Unsupported language/version combinations fail fast with clear error messages
| Language | Version | Docker Image | Status |
|---|---|---|---|
python | 3.11 | python:3.11-slim | Supported |
python | 3.10 | python:3.10-slim | Supported |
python | 3.9 | python:3.9-slim | Deprecated — migrate to 3.10 or 3.11 |
javascript | 20 | node:20-alpine | Supported (Current LTS) |
javascript | 18 | node:18-alpine | Supported (Legacy LTS) |
typescript | 5.1 | node:20-alpine | Supported |
rust | 1.75 | rust:1.75-alpine | Supported |
rust | 1.74 | rust:1.74-alpine | Supported (Legacy) |
go | 1.21 | golang:1.21-alpine | Supported |
go | 1.20 | golang:1.20-alpine | Supported (Legacy) |
For the full matrix including pre-installed toolchains, deprecation lifecycle, and pre-caching guidance, see Standard Runtime Registry.
Where the mapping lives: The canonical registry is defined in runtime-registry.yaml in the orchestrator repository. This file is committed and loaded at daemon startup.
Benefits:
- Deterministic: Same language+version always pulls the same vetted image
- Managed by AEGIS: No arbitrary image choices; all runtimes are vetted for security and compatibility
- Fast: Images are cached; only pulled once
- Validated: Manifests with unsupported language/version combinations are rejected at execution validation time
CustomRuntime (User-Supplied Images)
When you specify image, the orchestrator pulls from your container registry. Supports fully-qualified references like ghcr.io/org/custom:v1.0.
Benefits: Flexibility for OS packages, custom dependencies, private registries. See Custom Runtime Agents for a complete walkthrough.
Bootstrap Script
Both paths use the orchestrator-provided bootstrap script for 100monkeys iteration control. To bundle your own bootstrap script in a CustomRuntime image, declare its path in spec.advanced.bootstrap_path. See Custom Runtime Agents — Bootstrap Handling.
Isolation Mode
isolation specifies process isolation technology:
inherit(default): Use node configuration settingdocker: Run in a container managed by the configured container runtime (Phase 1)firecracker: Firecracker microVM (Phase 2)process: Host process (Phase 2)
The docker isolation type uses the container runtime configured via container_socket_path in the node configuration. This works with both Docker and Podman — the runtime is auto-detected.
spec.task
task.instruction
High-level steering instructions for the agent. When present, the instruction text can be reused as the criteria for a semantic validator in the ordered spec.execution.validation list.
task.prompt_template
Handlebars template that controls how the LLM prompt is assembled.
Available variables:
| Variable | Description |
|---|---|
{{intent}} | Natural-language steering from the caller's execution request. Empty string when absent. |
{{instruction}} | The task.instruction text. |
{{input}} | JSON input supplied at execution time. |
{{iteration_number}} | Current iteration (1-based). |
{{previous_error}} | Validator failure output from the previous iteration; empty on iteration 1. |
{{context}} | Concatenated context attachments. |
spec.security
All permissions are deny-by-default. When spec.security is omitted entirely, the agent runs with no network or filesystem access and default resource limits.
Network Policy
mode: none attaches no network interface to the container — the strongest isolation. mode: allow with an allowlist permits only the listed domains. mode: deny with a denylist blocks specific domains and allows all others.
Filesystem Policy
Paths support glob patterns (e.g., "/config/*.yaml"). filesystem.read_only: true overrides all other settings and makes every mount read-only regardless of access_mode.
Resource Limits — Timeout Hierarchy
The timeout field is the outer bound for the entire execution. All validation sub-timeouts must fit within this budget:
security.resources.timeout (e.g., 600s)
└─ execution.validation[*].timeout_seconds (e.g., 90s) — outer-loop validator budgets
└─ execution.tool_validation[*].timeout_seconds (e.g., 30s) — inner-loop tool-call judgespec.volumes[]
Storage volumes are mounted into the agent container via the orchestrator's AegisFSAL layer. Volume mount declarations are transport-agnostic -- the runtime automatically selects the appropriate transport (NFS for rootful Docker, FUSE bind mounts for rootless Podman, virtio-fs for Firecracker) based on the node configuration. The agent manifest does not need to specify which transport to use; the orchestrator intercepts all file operations regardless of transport, enforcing policy and maintaining a full audit trail.
| Class | TTL | Use Case |
|---|---|---|
ephemeral | Required; auto-cleanup | Scratch space, build artifacts |
persistent | None; explicit delete | Shared datasets, long-lived output |
access_mode: read-write is exclusive — only one execution may hold write access to a persistent volume at a time. read-only volumes may be read by multiple agents simultaneously.
All spec.volumes[].mount_path values must be rooted at /workspace.
spec.execution
Controls the 100monkeys iterative execution strategy. When mode: iterative, if any validation check fails the orchestrator sends the failure output back to the agent as {{previous_error}} and starts a new iteration (up to max_iterations). When mode: one-shot, the first run is final.
Setting memory: true enables the Cortex learning system to index refinements from this execution, improving suggestions for future runs.
validation and tool_validation
validation and tool_validation are both ordered lists of ValidatorSpec entries. Outer-loop validators run after each iteration; inner-loop tool-call validators run before dispatch.
Common validator variants:
exit_code- checks the process exit code.json_schema- validates the agent output against a JSON Schema document.regex- validates output text with a regular expression.semantic- spawns a judge agent as a child execution and compares the returnedscoreandconfidenceagainst thresholds.multi_judge- runs multiple judge agents and aggregates their results.
For tool-call judging specifics, including the judge payload and bypass semantics, see Tool-Call Judging.
spec.tools[]
The orchestrator mediates all tool calls — agents never access MCP servers or credentials directly.
Security model:
| Layer | What is enforced |
|---|---|
| Authentication | Orchestrator validates execution_id before forwarding any call. |
| Authorization | Tool name must appear in spec.tools. Absent = rejected. |
| Policy validation | Arguments validated against tool-specific config (paths, domains, operations). |
| Rate limiting | Call count tracked per execution; calls beyond limit return 429. |
| Credential isolation | OAuth tokens and API keys held by orchestrator; never exposed to agent. |
| Audit trail | Every invocation published as MCPToolEvent domain event. |
spec.context[]
Additional resources attached to the agent at execution time.
| Field | Type | Required | Description |
|---|---|---|---|
type | text | file | directory | url | ✓ | Resource type. |
content | string | Required for text | Inline text content. |
path | string | Required for file, directory | File or directory path. |
url | string | Required for url | URL to fetch. |
description | string | Human-readable description. |
spec.schedule
| Field | Type | Description |
|---|---|---|
type | cron | interval | manual | Schedule type. |
cron | string | Standard cron expression (e.g., "0 * * * *" = hourly). |
timezone | string | IANA timezone (e.g., "America/New_York"). |
enabled | boolean | Whether the schedule is active. |
spec.advanced
| Field | Type | Description |
|---|---|---|
bootstrap_path | string | Path to custom bootstrap script inside the container. Only valid for CustomRuntime. The field is declared in the schema and exposed in the Python and TypeScript SDKs; runtime wiring is tracked in the orchestrator backlog and is not yet active in the current release. |
warm_pool_size | integer | Number of pre-warmed container instances. |
swarm_enabled | boolean | Enable multi-agent coordination. |
startup_script | string | Custom startup script. |
spec.delivery
Output delivery destinations evaluated after execution completes. Each destination:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✓ | Unique identifier for this destination. |
condition | on_success | on_failure | always | ✓ | When to deliver. |
transform | object | ETL script applied to output before delivery. | |
type | email | webhook | rest | sms | ✓ | Delivery mechanism. |
Transform fields:
| Field | Type | Description |
|---|---|---|
script | string | Path to transformation script. Receives agent output on stdin. |
args | string[] | Additional CLI arguments for the script. |
timeout_seconds | integer | Script timeout. Default: 30. |
Email delivery fields: email.to, email.subject (supports {{date}}, {{agent.name}}), email.body_template, email.attachments.
Webhook delivery fields: webhook.url, webhook.method (default POST), webhook.headers (supports {{secret:token-name}}).
Examples
Minimal Agent (StandardRuntime)
apiVersion: 100monkeys.ai/v1
kind: Agent
metadata:
name: pr-reviewer
version: "1.0.0"
description: "Reviews pull request diffs and returns structured feedback."
spec:
runtime:
language: python
version: "3.11"
task:
instruction: |
Review the provided code diff and return structured feedback covering:
- Security vulnerabilities or concerns
- Performance issues or opportunities
- Code quality and maintainability
Provide specific line references where relevant.
security:
network:
mode: allow
allowlist:
- api.github.com
resources:
cpu: 1000
memory: "1Gi"
timeout: "300s"
execution:
mode: iterative
max_iterations: 5Minimal Agent (CustomRuntime)
apiVersion: 100monkeys.ai/v1
kind: Agent
metadata:
name: diagram-generator
version: "1.0.0"
description: "Generates diagrams using Graphviz (requires custom image)."
spec:
runtime:
image: "ghcr.io/my-org/diagram-generator:latest"
image_pull_policy: IfNotPresent # Use cache if available
task:
instruction: |
Generate a Graphviz diagram from the user's description.
Save the DOT file to /workspace/diagram.dot
Render to SVG: dot -Tsvg diagram.dot -o diagram.svg
security:
filesystem:
read:
- /workspace
write:
- /workspace
resources:
cpu: 1000
memory: "1Gi"
timeout: "120s"
volumes:
- name: workspace
storage_class: ephemeral
mount_path: /workspace
access_mode: read-write
ttl_hours: 1
size_limit: "1Gi"
execution:
mode: iterative
max_iterations: 3Agent with JSON Output Validation
apiVersion: 100monkeys.ai/v1
kind: Agent
metadata:
name: data-extractor
version: "1.0.0"
spec:
runtime:
language: python
version: "3.11"
task:
instruction: |
Extract structured data from the provided document and output valid JSON
matching the required schema.
security:
filesystem:
read:
- /workspace
write:
- /workspace/output
resources:
cpu: 500
memory: "512Mi"
timeout: "120s"
volumes:
- name: workspace
storage_class: ephemeral
mount_path: /workspace
access_mode: read-write
ttl_hours: 1
size_limit: "500Mi"
execution:
mode: iterative
max_iterations: 8
validation:
system:
must_succeed: true
allow_stderr: false
timeout_seconds: 60
output:
format: json
schema:
type: object
required: ["entities", "relationships", "confidence"]
properties:
entities:
type: array
relationships:
type: array
confidence:
type: number
minimum: 0
maximum: 1
semantic:
threshold: 0.85
fallback_on_unavailable: skip
tools:
- name: filesystem
server: "mcp:filesystem"
config:
allowed_paths: ["/workspace"]
access_mode: read-writeCode Reviewer (Judge Agent)
Judge agents evaluate the output of other agents and must return structured JSON with gradient scoring:
{
"score": 0.85,
"confidence": 0.92,
"reasoning": "The code correctly implements the requirements with minor style issues.",
"suggestions": ["Add type hints", "Improve error handling"],
"verdict": "pass"
}Required judge output fields:
| Field | Type | Description |
|---|---|---|
score | float (0.0–1.0) | Quality/correctness score on a continuous gradient. |
confidence | float (0.0–1.0) | Judge's certainty in its assessment. |
reasoning | string | Explanation for the score. |
Optional fields: signals, suggestions, verdict, and any custom metadata.
apiVersion: 100monkeys.ai/v1
kind: Agent
metadata:
name: code-quality-judge
version: "1.0.0"
labels:
role: judge
domain: code-review
spec:
runtime:
language: python
version: "3.11"
task:
instruction: |
You are a code quality judge. Evaluate the provided code output on:
1. Correctness: Does it solve the stated problem?
2. Code quality: Is it idiomatic and well-structured?
3. Error handling: Does it handle edge cases?
Always respond with valid JSON:
{
"score": <0.0-1.0>,
"confidence": <0.0-1.0>,
"reasoning": "<explanation>",
"suggestions": ["<improvement>"],
"verdict": "pass|fail|warning"
}
security:
network:
mode: none
resources:
cpu: 500
memory: "512Mi"
timeout: "60s"
execution:
mode: one-shot
validation:
system:
must_succeed: true
output:
format: json
schema:
type: object
required: ["score", "confidence", "reasoning"]
properties:
score:
type: number
minimum: 0
maximum: 1
confidence:
type: number
minimum: 0
maximum: 1
reasoning:
type: stringMulti-Judge Consensus
For validation requiring multiple independent judges with consensus aggregation, use ValidatorSpec::MultiJudge inside spec.execution.validation. For workflow-level fan-out and consensus, use workflow ParallelAgents states. See:
- Building Workflows —
ParallelAgentsstate type - Validation Guide — gradient scoring and confidence gating
| Feature | spec.execution.validation.multi_judge | Workflow ParallelAgents |
|---|---|---|
| Number of judges | Single | Multiple in parallel |
| Consensus algorithm | N/A | mean, min, max, majority |
| Configuration location | Agent manifest | Workflow manifest |
| Use case | Per-iteration quality gate | Final output multi-panel review |
Runtime Selection Guide
When to Use StandardRuntime
✅ Choose StandardRuntime if:
- Your agent only needs Python, Node.js, TypeScript, Rust, or Go
- Standard system packages are sufficient (no OS binaries required)
- You want AEGIS to manage image updates
- You want deterministic, cached deployments
When to Use CustomRuntime
✅ Choose CustomRuntime if:
- You need OS-level packages (graphviz, imagemagick, system libraries)
- You require a specialized language version not in StandardRuntime registry
- You want to include custom dependencies in the image
- You're using a private container registry
- You need image signing or vulnerability scanning
See: Custom Runtime Agents for complete walkthrough.
Image Pull Policies
IfNotPresent (Default)
Use local cached image if available; pull from registry only if missing.
Best for: Release versions (stable, changes rarely), reducing network traffic, offline deployments.
Always
Always pull from registry, even if already cached locally.
Best for: -dev, -latest tags (frequently updated), ensuring agents use current fixes.
Never
Only use cached images; fail if image is not already cached.
Best for: Locked production versions, guaranteed deterministic content, airgapped deployments. Images must be pre-loaded on the node via docker pull before execution. See Pre-Caching for Airgapped Environments.
Version History
| Version | Date | Notes |
|---|---|---|
| v1.0 | 2026-02-16 | Kubernetes-style format with apiVersion/kind/metadata/spec. Canonical format for all new agents. |
Production Hardening
Security checklist and hardening guide for production AEGIS deployments — TLS, secrets rotation, resource limits, network segmentation, and access control.
Standard Runtime Registry
The complete language-version-to-image mapping table for AEGIS StandardRuntime — supported versions, base images, pre-installed toolchains, and the version support lifecycle.