Harness DSL — one source of truth per plugin
Every OMA plugin describes its runtime surface in a single YAML file:
plugins/<name>/<name>.oma.yaml
python -m tools.oma_compile translates that file into the native files
Claude Code and Kiro already understand:
<plugin>.oma.yaml ──(oma-compile)──▶ .mcp.json
▶ kiro-agents/<agent>.agent.json
▶ .omao/triggers.json (merged across plugins)
▶ hooks/hooks.json (PreToolUse enforcement)
▶ hooks/harness-rules.json + hooks/enforce.py
Plugins keep shipping the compiled output, so /plugin install from the
marketplace works even on machines that have never seen the compiler.
Example
# plugins/ai-infra/ai-infra.oma.yaml
version: 1
plugin: ai-infra
agents:
- id: autopilot-deploy
runtime: claude-code
mcp: [eks, cloudwatch, prometheus]
tier: 0
ontology:
produces: [Deployment]
consumes: [Spec, ADR]
mcp:
eks:
command: uvx
args: ["awslabs.eks-mcp-server==0.1.28"]
env: { FASTMCP_LOG_LEVEL: ERROR }
cloudwatch:
command: uvx
args: ["awslabs.cloudwatch-mcp-server==0.0.25"]
hooks:
session-start:
runs: hooks/session-start.sh
triggers:
- keyword: platform-bootstrap
route: /oma:platform-bootstrap
Guarantees enforced at compile time
- Pinned MCP versions.
argsmust contain==X.Y.Z. Floating versions (@latest, unpinned, caret ranges) are rejected so a compromised upstream release cannot silently land alongside AWS credentials. - Declared MCP references.
agents[*].mcpcan only name ids that exist in the top-levelmcp:map. Unknown references fail the build. - Real hook scripts.
hooks.<event>.runsmust point at an existing file under the plugin. No phantom hook declarations. - Valid enforcement rules. Every
policies[].enforce.deny_ifregex must compile, or the build fails — a broken rule can never ship and silently stop enforcing (fail-closed at build time). - Stable output. Emitted JSON is sorted deterministically; CI fails the
build if committed
.mcp.jsonor.agent.jsondrift from the DSL source (oma-compile --check).
Runtime enforcement (policies)
A policies entry turns a declarative rule into real enforcement — pure
Claude Code, no external policy engine and no opa binary. The compiler emits
hooks/harness-rules.json plus a PreToolUse entry in hooks/hooks.json that
runs the bundled hooks/enforce.py. Because the hook fires at the harness layer
before a tool executes, a denied call never reaches the model — this is
enforcement, not prompt-level guidance.
policies:
- id: deny-eks-mutating-kubectl
severity: blocking
phase: [construction, operations]
description: Block mutating kubectl; EKS writes need an approved Deployment.
enforce:
tool: Bash # omit to match every tool
deny_if:
command_matches: "kubectl\\s+(apply|create|delete|patch|exec|rollout)"
decision: deny # deny | ask
reason: "Harness: mutating kubectl is blocked. Use platform-bootstrap."
deny_if supports command_matches, command_matches_any (list),
file_path_matches (Write/Edit), and input_field ({path, matches}). A rule
fires when the tool matches and every declared condition matches; the first
firing rule wins. At runtime the enforcer fails open only when no ruleset is
present, and fails closed when a shipped ruleset is unreadable. See the
Harness DSL v2 page for the full enforcement model and a
before/after (OPA → pure-CC) migration example.
Commands
# Compile one plugin
python -m tools.oma_compile plugins/ai-infra/ai-infra.oma.yaml
# Compile every plugin that has a *.oma.yaml
python -m tools.oma_compile --all
# Fail if committed native files drift from DSL
python -m tools.oma_compile --check
Where the ontology plugs in
agents[*].ontology.produces and consumes use the entity enum from
schemas/ontology/agent.schema.json. The compiler doesn't invent new
vocabulary — the Ontology page (Ontology) is the source of
truth.
Schema reference
Full JSON Schema: schemas/harness/dsl.schema.json.