Workspace contract
The runtime loads configuration recursively from config/. Filenames are organizational only;
semantics come from the YAML object kind, metadata, and spec. This keeps the repository flexible while
preserving a stable contract for discovery.
config/
workspace.yaml
agent-context.md
catalogs/
models.yaml
embedding-models.yaml
stores.yaml
vector-stores.yaml
tools.yaml
backends.yaml
mcp.yaml
agents/
direct.yaml
orchestra.yaml
Recommended layout
Start with one stable directory layout and keep it boring. Teams move faster when every repository looks familiar and every major runtime concern has one obvious place to live.
config/
workspace.yaml
agent-context.md
catalogs/
models.yaml
embedding-models.yaml
stores.yaml
vector-stores.yaml
backends.yaml
tools.yaml
mcp.yaml
agents/
direct.yaml
orchestra.yaml
resources/
tools/
skills/
src/
test/
Code and test layout in the harness tree
If you work on the open-source package itself, keep implementation in src/ and tests in
test/ so local builds match CI and the repository layout.
YAML principles
- Use YAML for assembly, policy, and reusable catalog state.
- Do not invent harness-specific semantics where upstream already defines the primitive.
- Keep collection files Kubernetes-style with
apiVersion, pluralkind, andspec: []. - Keep singleton runtime config as one document with
metadataandspec.
Avoid semantic duplication
YAML should expose upstream concepts directly where possible. The goal is not to create a second agent framework inside configuration.
workspace.yaml: runtime-level settings only
Treat workspace.yaml as the runtime singleton. It should express application-level routing,
recovery, concurrency, maintenance, and runtime defaults. It should not become a dump of agent-private
behavior or prompt-level details.
Tool-module discovery policy also belongs here. Use it when the runtime should keep YAML catalogs recursive
but limit local resources/tools/-style module loading to files directly under each tool root.
apiVersion: agent-harness/v1alpha1
kind: Workspace
metadata:
name: default
spec:
runtime:
runtimeRoot: ./.agent
defaults:
governance:
toolPolicy: default
recovery:
resumeResumingRequestsOnStartup: true
maintenance:
enabled: true
concurrency:
maxConcurrentRuns: 4
toolModuleDiscovery:
scope: top-level
routing:
defaultAgent: orchestra
Routing defaults, concurrency policy, maintenance, recovery, tool-module discovery policy, and runtime-owned governance defaults.
Agent prompt fragments, backend-private tuning knobs, or transient request state.
Catalog files and what each one owns
Catalogs should answer one question clearly: what reusable named object is this file responsible for? Keep each catalog narrow so users know where to add the next thing without scanning the whole repository.
models.yaml
Named chat model presets. Start with one default model and one obvious fallback.
apiVersion: agent-harness/v1alpha1
kind: Models
spec:
- metadata:
name: model/default
provider: openai
model: gpt-5.4
temperature: 0.2
- metadata:
name: model/fallback
provider: anthropic
model: claude-sonnet-4-5
embedding-models.yaml
Named embedding presets used by vector stores and semantic recall.
apiVersion: agent-harness/v1alpha1
kind: EmbeddingModels
spec:
- metadata:
name: embedding/default
provider: openai
model: text-embedding-3-large
stores.yaml
Durable structured persistence and checkpoint recovery. Keep stores and checkpointers distinct.
apiVersion: agent-harness/v1alpha1
kind: Stores
spec:
- metadata:
name: store/default
kind: Store
storeKind: SqliteStore
url: ./.agent/runtime.db
- metadata:
name: checkpointer/default
kind: Checkpointer
storeKind: SqliteCheckpointer
url: ./.agent/runtime.db
vector-stores.yaml
Semantic recall and embedding-backed lookup. This is not the same thing as the canonical durable store.
apiVersion: agent-harness/v1alpha1
kind: VectorStores
spec:
- metadata:
name: vector/default
storeKind: LibSQLVectorStore
url: ./.agent/runtime.db
table: memory_embeddings
embeddingModelRef: embedding/default
backends.yaml
Named backend presets. Keep these simple and focused on backend selection.
apiVersion: agent-harness/v1alpha1
kind: Backends
spec:
- metadata:
name: backend/deepagent-default
backend: deepagent
- metadata:
name: backend/langchain-default
backend: langchain-v1
tools.yaml
Named tool resources or references. The implementation still lives under resources/tools/.
apiVersion: agent-harness/v1alpha1
kind: Tools
spec:
- metadata:
name: tool/write-file
source: local
toolName: write_file
mcp.yaml
Named MCP servers. Use catalogs for remote, shared capability surfaces rather than burying them in agents.
apiVersion: agent-harness/v1alpha1
kind: McpServers
spec:
- kind: McpServer
id: awesome-github-mcp
name: awesome-mcp/github-mcp
description: MCP server for GitHub workflows and repository operations
repositoryUrl: https://github.com/modelcontextprotocol/servers
transport: stdio
command: npx
args:
- -y
- "@modelcontextprotocol/server-github"
env:
GITHUB_TOKEN: CHANGE_ME
Treat id as the runtime identity. Fields such as transport, command,
args, url, env, cwd, token, and
headers drive runtime behavior; richer fields such as name,
description, and repositoryUrl are useful catalog metadata.
Keep the server preset in the catalog, then attach it from agents with an object-form
spec.mcpServers usage entry. That is where per-agent tool filters and transport overrides
belong.
Agent definitions
Agent is the primary product configuration object. Subagents are simply agents referenced by
another agent through spec.subagents. Routing answers which host agent starts a run; it should
not introduce a second harness-owned role taxonomy.
apiVersion: agent-harness/v1alpha1
kind: Agent
metadata:
name: orchestra
spec:
backend: deepagent
modelRef: model/default
runtime:
runtimeRoot: ./.agent
tools: []
skills: []
subagents: []
mcpServers: []
In practice, most teams should write at least two agent examples: one direct-response agent and one orchestrating agent that can call subagents.
apiVersion: agent-harness/v1alpha1
kind: Agent
metadata:
name: direct
spec:
backend: langchain-v1
modelRef: model/default
runtime:
runtimeRoot: ./.agent
tools:
- tool/write-file
skills: []
mcpServers: []
subagents: []
---
apiVersion: agent-harness/v1alpha1
kind: Agent
metadata:
name: orchestra
spec:
backend: deepagent
modelRef: model/default
runtime:
runtimeRoot: ./.agent
tools:
- tool/write-file
skills:
- repo-review
mcpServers:
- ref: mcp/awesome-github-mcp
toolFilters:
- "^issue_"
subagents:
- direct
Catalogs and reusable objects
Catalog documents let teams name and reuse models, embedding models, stores, vector stores, tools, MCP servers, and backends. The runtime compiles those named objects into the final agent bindings.
Named chat model presets with provider, model id, and provider options.
Durable runtime persistence and recovery configuration.
Reusable tool definitions or catalog references for agents to whitelist.
Shared remote capability endpoints, usually heavier than local tools.
Assembly flow
- Load YAML documents from the workspace.
- Discover local resources such as
resources/tools/andresources/skills/. - Resolve named references from catalogs into compiled agent bindings.
- Attach runtime-owned policy, persistence, recovery, and governance defaults.
- Expose one stable runtime surface to the application.
Common mistakes
Structured persistence, recovery, and semantic recall are related, but they are not one object.
Catalogs name resources. Tool code still belongs in resources/tools/ and app code in src/.
workspace.yaml
Keep runtime policy there. Do not turn it into a second agent prompt or a backend tuning dump.
If upstream already has the primitive, map it cleanly instead of renaming it in YAML.
What not to do in YAML
Do not use YAML to encode transient request state, checkpoint internals, or app-private view models. YAML is for assembly and operating policy, not for ad hoc duplication of runtime data.