Agent Manifest
Root manifest and compiled config blob
Overview
The agent manifest is the root definition of an agent artifact. It declares identity, optional layer sources, runtime hints, package dependencies, secret requirements, optional workspace source dependencies, optional subagent and instruction-tree sources, and the adapter used to materialize or import the artifact for a target consumer environment.
Agents are authored in TypeScript using defineAgent() and compiled to JSON for the OCI config blob.
Source file
A project MUST contain exactly one root agent definition file, typically agent.ts.
All relative paths in the agent definition are resolved relative to the directory containing agent.ts.
Resolved paths MUST remain within the project root unless the builder is explicitly run with an escape hatch such as --allow-outside-root.
Path resolution rules:
- Builders MUST resolve symlinks before checking containment. If the resolved target is outside the project root, the builder MUST reject the path.
- Paths containing
..segments MUST be normalized before containment checking. A path that escapes the project root after normalization MUST be rejected. --allow-outside-rootMUST NOT be the default. Builders SHOULD warn prominently when this flag is used.- Builders SHOULD default to
--symlink-mode reject. Builders MAY support--symlink-mode flattenfor selected directory-backed layers as defined in 03 — Layers.
defineAgent()
import { defineAgent } from "stax";
import claudeCode from "@stax/claude-code";
export default defineAgent({
name: "backend-engineer",
version: "3.1.0",
description: "Senior backend engineer with Go and distributed systems expertise.",
author: "myorg",
license: "MIT",
tags: ["code-review", "architecture", "golang"],
url: "https://github.com/myorg/backend-engineer",
adapter: claudeCode({
model: "claude-opus-4-1",
modelParams: { temperature: 0.3 },
}),
adapterFallback: [
{
type: "generic",
runtime: "generic",
adapterVersion: "1.0.0",
model: "any-model-id",
config: {},
features: {},
},
],
persona: "./personas/maya-chen.ts",
prompt: "./SYSTEM_PROMPT.md",
mcp: "./mcp-servers.ts",
skills: "./skills/",
rules: "./rules/",
knowledge: "./knowledge/",
memory: "./memory/",
surfaces: "./surfaces/",
instructionTree: "./instruction-tree/",
subagents: "./subagents.ts",
hints: {
isolation: "microvm",
capabilities: {
shell: true,
network: {
mode: "restricted",
allowlist: ["api.anthropic.com", "api.github.com"],
},
filesystem: {
workspace: "/workspace",
writable: ["/workspace"],
denyRead: ["**/.env", "**/*credentials*"],
},
},
},
secrets: [
{ key: "ANTHROPIC_API_KEY", required: true, kind: "api-key" },
{ key: "GITHUB_TOKEN", required: true, kind: "token" },
{ key: "SLACK_WEBHOOK", required: false, kind: "url" },
],
workspaceSources: [
{
id: "backend-repo",
ref: "ghcr.io/myorg/sources/backend@sha256:abcdef123456...",
mountPath: "/workspace/backend",
writable: true,
required: true,
},
],
packages: [
"ghcr.io/myorg/packages/github-workflow:2.0.0",
"ghcr.io/myorg/packages/org-standards@sha256:0123456789abcdef...",
"./packages/local-team-overrides",
],
});Type definitions
interface AgentDefinition {
specVersion?: "1.0.0";
// Identity
name: string;
version: string;
description: string;
author?: string;
license?: string;
url?: string;
tags?: string[];
// Adapter
adapter: AdapterConfig;
adapterFallback?: AdapterConfig[];
// Source paths resolved at build time
persona?: string;
prompt?: string;
mcp?: string;
skills?: string;
rules?: string;
knowledge?: string;
memory?: string;
surfaces?: string;
instructionTree?: string;
subagents?: string;
// Runtime hints
hints?: RuntimeHints;
// Secret declarations
secrets?: SecretDeclaration[];
// Shared workspace/source dependencies
workspaceSources?: WorkspaceSourceReference[];
// Package references
packages?: PackageReference[];
}
interface RuntimeHints {
isolation?: "process" | "container" | "gvisor" | "microvm";
capabilities?: {
shell?: boolean;
processes?: boolean;
docker?: boolean;
network?: NetworkHint;
filesystem?: FilesystemHint;
};
}
interface NetworkHint {
mode: "none" | "restricted" | "full";
allowlist?: string[];
}
interface FilesystemHint {
workspace?: string;
writable?: string[];
denyRead?: string[];
}
interface SecretDeclaration {
key: string;
required: boolean;
description?: string;
kind?: "api-key" | "token" | "password" | "certificate" | "connection-string" | "url" | "opaque";
exposeAs?: { env?: string; file?: string };
}
type PackageReference = string;
interface WorkspaceSourceReference {
id: string;
ref: string; // OCI ref to a source artifact
mountPath: string; // Where the consumer should materialize it
writable?: boolean; // Default: false
required?: boolean; // Default: true
subpath?: string; // Optional subdirectory inside the source artifact
}
interface AdapterConfig {
type: string; // Adapter identifier, e.g. "claude-code"
runtime: string; // Runtime family, e.g. "claude-code"
adapterVersion: string; // Adapter schema version
runtimeVersionRange?: string; // Tested runtime-version range for exact claims
model?: string;
modelParams?: Record<string, unknown>;
importMode?: "filesystem" | "api" | "bundle" | "object-map";
fidelity?: "byte-exact" | "schema-exact" | "best-effort" | "unsupported";
config: Record<string, unknown>;
features: AdapterFeatureMap;
targets?: MaterializationTarget[];
}
interface AdapterFeatureMap {
prompt?: "native" | "embedded" | "unsupported";
persona?: "native" | "embedded" | "unsupported";
rules?: "native" | "embedded" | "unsupported";
skills?: "native" | "unsupported";
mcp?: "native" | "translated" | "unsupported";
surfaces?: "native" | "translated" | "unsupported";
secrets?: "native" | "consumer-only";
toolPermissions?: "native" | "translated" | "unsupported";
modelConfig?: "native" | "translated" | "unsupported";
exactMode?: boolean;
}
interface MaterializationTarget {
kind: "file" | "directory" | "setting" | "api" | "bundle" | "object";
path: string;
description?: string;
scope?: "user" | "project" | "workspace" | "local" | "remote" | "account" | "organization";
exact?: boolean;
mediaType?: string;
}Field validation
Identity
nameMUST match^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$versionMUST be valid semvertags, if present, MUST contain unique case-sensitive strings
Paths
persona,prompt,mcp, andsubagentsMUST resolve to filesskills,rules,knowledge,memory,surfaces, andinstructionTreeMUST resolve to directories- Missing optional paths MUST be treated as validation errors if declared explicitly
- Symlinks MUST be rejected by default. Builders MAY allow symlink flattening only when explicitly invoked with
--symlink-mode flattenand only for the layers permitted by 03 — Layers.
Workspace sources
Each entry in workspaceSources MUST:
- have a unique
id - reference an OCI source artifact by digest or exact tag
- specify an absolute
mountPath - use a
mountPaththat does not collide with another workspace source entry
Consumers SHOULD cache workspace source artifacts by digest and SHOULD reuse the same cached source across many agents. See 22 — Workspace Sources.
Packages
Each entry in packages MUST be either:
- A relative local path beginning with
./or../ - An OCI reference with an explicit tag:
<registry>/<repo>:<tag> - An OCI digest reference:
<registry>/<repo>@sha256:<digest>
Semver ranges, globs, and floating selectors such as ^1, ~2, or latest SHOULD NOT be used in committed manifests. Builders MAY allow them interactively, and lockfile-capable implementations SHOULD resolve them into stax.lock and warn.
Adapter fallback
adapterFallback provides alternate adapter configs in descending preference order.
Consumers MUST:
- Try the primary
adapter. An adapter is compatible if the consumer supports itstype,runtime, andadapterVersionmajor version. - If the primary adapter is not compatible, try each
adapterFallbackentry in array order, stopping at the first compatible entry. - Fail with exit code 5 (materialization compatibility error) if no adapter is compatible. The error message MUST list the attempted adapter types and versions.
Consumers MUST NOT select a fallback adapter if the primary adapter is compatible, even if the fallback would produce a "better" result.
Compiled config blob
The OCI config blob for an agent MUST use media type application/vnd.stax.config.v1+json and MUST contain canonical JSON with stable key ordering.
If surfaces or instructionTree are present, the config blob SHOULD record that fact so consumers can distinguish artifacts that support exact runtime file materialization from those that only provide a single prompt.
Canonical config example
{
"specVersion": "1.0.0",
"kind": "agent",
"name": "backend-engineer",
"version": "3.1.0",
"description": "Senior backend engineer with Go and distributed systems expertise.",
"author": "myorg",
"license": "MIT",
"url": "https://github.com/myorg/backend-engineer",
"tags": ["code-review", "architecture", "golang"],
"adapter": {
"type": "claude-code",
"runtime": "claude-code",
"adapterVersion": "1.0.0",
"model": "claude-opus-4-1",
"modelParams": { "temperature": 0.3 },
"config": {
"permissions": {
"allowedTools": ["Read", "Edit", "Bash", "Grep", "Write"]
}
},
"features": {
"prompt": "embedded",
"persona": "embedded",
"rules": "native",
"skills": "native",
"mcp": "translated",
"secrets": "consumer-only",
"toolPermissions": "native",
"modelConfig": "native"
}
},
"hints": {
"isolation": "microvm",
"capabilities": {
"shell": true,
"network": {
"mode": "restricted",
"allowlist": ["api.anthropic.com", "api.github.com"]
}
}
},
"workspaceSources": [
{
"id": "backend-repo",
"ref": "ghcr.io/myorg/sources/backend@sha256:abcdef123456...",
"mountPath": "/workspace/backend",
"writable": true,
"required": true
}
],
"packages": ["ghcr.io/myorg/packages/github-workflow:2.0.0"]
}In vs out of scope
In the manifest
| Field | Why |
|---|---|
| Identity fields | Defines what the artifact is |
| Adapter and fallback | Declares intended runtimes |
| Layer paths, surfaces, instruction trees, and subagents | Defines the agent brain, exact runtime-facing documents, and bundled delegate agents |
| Runtime hints | Communicates non-binding requirements and recommendations |
| Secret declarations | Declares needed secret keys |
| Workspace source references | Declares shared repo/workspace dependencies |
| Package references | Defines composition |
Out of the manifest
| Concern | Why it's out |
|---|---|
| Secret values and providers | Environment-specific |
| Resource limits | Operational |
| Replicas | Orchestration |
| Retry policy | Runtime-specific |
| Session timeout | Operational |
| Scheduling and topology | Orchestration |
Directory structure
my-agent/
├── agent.ts
├── SYSTEM_PROMPT.md
├── persona.ts
├── mcp-servers.ts
├── personas/
│ ├── _base.ts
│ ├── maya-chen.ts
│ └── alex-rivera.ts
├── skills/
├── rules/
├── knowledge/
├── memory/
├── surfaces/
│ ├── instructions.md
│ ├── persona.md
│ └── tools.md
├── .staxignore
└── stax.lock