Skip to content

Config Schema

OrgLoop uses YAML for all configuration, with JSON Schema for validation. Files use the .yaml extension (not .yml). Comments are encouraged — OrgLoop config is meant to be read by the team, and routing decisions deserve annotation.

An OrgLoop project is a directory containing .yaml files organized by convention:

my-org/
├── orgloop.yaml # Project manifest (required)
├── connectors/ # Connector definitions
│ ├── github.yaml
│ ├── linear.yaml
│ └── openclaw.yaml
├── routes/ # Route definitions
│ └── engineering.yaml
├── transforms/ # Transform definitions
│ ├── transforms.yaml
│ └── custom-filter.sh
├── sops/ # Launch prompt files (SOPs for actors)
│ ├── pr-review.md
│ ├── ci-failure.md
│ └── linear-ticket.md
└── loggers/ # Logger definitions
└── default.yaml

Every YAML file starts with apiVersion and kind:

apiVersion: orgloop/v1alpha1
kind: Project # or ConnectorGroup, RouteGroup, TransformGroup, LoggerGroup
KindPurpose
ProjectRoot project manifest (orgloop.yaml)
ConnectorGroupSource and/or actor definitions
RouteGroupRoute definitions
TransformGroupTransform definitions
LoggerGroupLogger definitions
ModuleModule manifest (orgloop-module.yaml)

The root orgloop.yaml declares the project and references external YAML files for connectors, routes, transforms, and loggers. The arrays contain file paths (relative to the project root), not package names.

apiVersion: orgloop/v1alpha1
kind: Project
metadata:
name: my-org
description: "Engineering organization event routing"
# Global defaults
defaults:
poll_interval: 5m
event_retention: 7d
log_level: info
# Connector definition files
connectors:
- connectors/github.yaml
- connectors/linear.yaml
- connectors/openclaw.yaml
- connectors/claude-code.yaml
# Route definition files
routes:
- routes/engineering.yaml
# Transform definition files
transforms:
- transforms/transforms.yaml
# Logger definition files
loggers:
- loggers/default.yaml
# Module references
modules:
- package: "@orgloop/module-engineering"
params:
github_repo: "my-org/my-repo"
agent_actor: engineering
FieldTypeRequiredDescription
metadata.namestringYesProject name. Used in logs and diagnostics.
metadata.descriptionstringNoHuman-readable project description.
FieldTypeDefaultDescription
defaults.poll_intervalduration5mDefault polling interval for sources that don’t specify their own.
defaults.event_retentionduration7dHow long to retain event data.
defaults.log_levelstringinfoDefault log level: debug, info, warn, error.

Sources are defined inside ConnectorGroup YAML files. Each source is an instance of a connector package with specific configuration.

apiVersion: orgloop/v1alpha1
kind: ConnectorGroup
sources:
- id: github
description: GitHub PR and CI activity
connector: "@orgloop/connector-github"
config:
repo: "${GITHUB_REPO}"
token: "${GITHUB_TOKEN}"
events:
- "pull_request.review_submitted"
- "pull_request_review_comment"
- "issue_comment"
- "pull_request.closed"
- "pull_request.merged"
- "workflow_run.completed"
poll:
interval: 5m
emits:
- resource.changed
FieldTypeRequiredDescription
idstringYesUnique identifier for this source. Referenced by routes.
descriptionstringNoHuman-readable description.
connectorstringYesPackage name of the connector (e.g., @orgloop/connector-github).
configobjectYesConnector-specific configuration.
poll.intervaldurationNoPolling interval. Overrides project default.
emitsstring[]NoEvent types this source emits. Informational/documentation.

GitHub (@orgloop/connector-github):

FieldTypeDescription
repostringRepository in owner/repo format.
tokenstringGitHub personal access token. Use "${GITHUB_TOKEN}".
eventsstring[]GitHub event types to poll for.
authorsstring[]Optional filter: only emit events from these authors.

Linear (@orgloop/connector-linear):

FieldTypeDescription
teamstringLinear team key.
projectstringOptional Linear project name filter.
api_keystringLinear API key. Use "${LINEAR_API_KEY}".

Claude Code (@orgloop/connector-claude-code):

Claude Code is hook-based, not poll-based. It exposes a webhook handler that receives POST requests from Claude Code’s post-exit hook script. No config fields beyond id and connector are required.

Webhook (@orgloop/connector-webhook):

FieldTypeDescription
pathstringURL path to mount the webhook receiver on.

Actors (targets) are also defined in ConnectorGroup files. An actor is an instance of a target connector.

apiVersion: orgloop/v1alpha1
kind: ConnectorGroup
actors:
- id: openclaw-engineering-agent
description: Engineering OpenClaw agent
connector: "@orgloop/connector-openclaw"
config:
base_url: "http://127.0.0.1:18789"
auth_token_env: "${OPENCLAW_WEBHOOK_TOKEN}"
agent_id: engineering
default_channel: slack
default_to: "${OPENCLAW_DEFAULT_TO}"
FieldTypeRequiredDescription
idstringYesUnique identifier for this actor. Referenced by routes.
descriptionstringNoHuman-readable description.
connectorstringYesPackage name of the target connector.
configobjectYesConnector-specific configuration.

OpenClaw (@orgloop/connector-openclaw):

FieldTypeDescription
base_urlstringOpenClaw server URL. Default: http://127.0.0.1:18789.
auth_token_envstringWebhook auth token. Use "${OPENCLAW_WEBHOOK_TOKEN}".
agent_idstringTarget agent identifier.
default_channelstringDefault delivery channel (e.g., slack).
default_tostringDefault recipient. Use "${OPENCLAW_DEFAULT_TO}".

Webhook (@orgloop/connector-webhook):

FieldTypeDescription
urlstringTarget URL to POST events to.
headersobjectOptional HTTP headers to include.
secretstringOptional HMAC secret for signing payloads.

Routes are the core wiring of OrgLoop. They declare: when source X emits event Y, run transforms, then deliver to actor Z with context C.

apiVersion: orgloop/v1alpha1
kind: RouteGroup
metadata:
name: engineering-routes
description: "Engineering event routing"
routes:
- name: github-pr-review
description: "PR review submitted -> Engineering agent"
when:
source: github
events:
- resource.changed
filter:
provenance.platform_event: pull_request.review_submitted
transforms:
- ref: drop-bot-noise
- ref: injection-scanner
then:
actor: openclaw-engineering-agent
config:
session_key: "hook:github:pr-review:engineering"
wake_mode: now
deliver: true
with:
prompt_file: "./sops/pr-review.md"
FieldTypeRequiredDescription
namestringYesUnique route name. Used in logs and diagnostics.
descriptionstringNoHuman-readable description.
FieldTypeRequiredDescription
when.sourcestringYesSource ID to match events from.
when.eventsstring[]YesEvent types to match (e.g., resource.changed).
when.filterobjectNoDot-path filter on event fields. All conditions must match.

Filter uses dot-path notation to match nested event fields:

filter:
provenance.platform_event: pull_request.review_submitted
provenance.author_type: team_member
FieldTypeRequiredDescription
transforms[].refstringYesName of a transform defined in a TransformGroup.

Transforms are applied sequentially. If any transform drops the event (returns null or exits non-zero), the pipeline stops and the event is not delivered.

FieldTypeRequiredDescription
then.actorstringYesActor ID to deliver the event to.
then.configobjectNoActor-specific config passed alongside the event.

The then.config fields are connector-specific. For OpenClaw:

FieldTypeDescription
session_keystringSession routing key.
wake_modestringWhen to wake the agent: now, next, queue.
deliverbooleanWhether to deliver the message to the agent’s chat.
FieldTypeRequiredDescription
with.prompt_filestringNoPath to a Markdown SOP file. Resolved relative to the route YAML file’s directory.

with is optional. Routes without it deliver events without additional context.

Only prompt_file is supported. Launch prompts are Markdown files, not inline YAML strings. This enforces clean separation: route logic (when/then) lives in YAML, operational content (the SOP) lives in Markdown files.

Multiple routes can target the same actor with different launch prompts. The routing layer decides which SOP is relevant — the actor does not need to figure it out.

orgloop validate checks that all referenced prompt files exist.

Transforms are defined inside TransformGroup YAML files. Two types are supported:

Reference a published transform package with configuration:

apiVersion: orgloop/v1alpha1
kind: TransformGroup
transforms:
- name: drop-bot-noise
type: package
package: "@orgloop/transform-filter"
config:
exclude:
provenance.author_type: bot
- name: dedup
type: package
package: "@orgloop/transform-dedup"
config:
key:
- source
- type
- provenance.platform_event
- payload.pr_number
window: 5m

Shell scripts with a stdin/stdout contract:

transforms:
- name: custom-filter
type: script
script: ./custom-filter.sh
timeout_ms: 5000

The script contract:

  • stdin: Event JSON
  • Environment variables: $SOURCE, $TARGET, $EVENT_TYPE
  • stdout with content: Modified event JSON (event continues through pipeline)
  • Empty stdout or exit 1: Event is filtered (dropped)
FieldTypeRequiredDescription
namestringYesUnique transform name. Referenced by routes.
typestringYesEither package or script.
packagestringIf type: packagePackage name of the transform.
configobjectNoPackage-specific configuration.
scriptstringIf type: scriptPath to the script file (relative to the YAML file).
timeout_msnumberNoScript execution timeout in milliseconds.

Loggers are passive observers that record pipeline activity. Every event, every transform, every delivery attempt is captured.

apiVersion: orgloop/v1alpha1
kind: LoggerGroup
metadata:
name: default-loggers
loggers:
- name: file-log
type: "@orgloop/logger-file"
config:
path: ~/.orgloop/logs/orgloop.log
format: jsonl
rotation:
max_size: 100MB
max_age: 7d
compress: true
- name: console-log
type: "@orgloop/logger-console"
config:
level: info
color: true
FieldTypeRequiredDescription
namestringYesUnique logger name.
typestringYesPackage name of the logger.
configobjectNoLogger-specific configuration.
FieldTypeDescription
pathstringLog file path. Supports ~ for home directory.
formatstringOutput format: jsonl.
rotation.max_sizestringMaximum file size before rotation (e.g., 100MB).
rotation.max_agestringMaximum age before rotation (e.g., 7d).
rotation.compressbooleanWhether to gzip rotated files.

Console Logger Config (@orgloop/logger-console)

Section titled “Console Logger Config (@orgloop/logger-console)”
FieldTypeDescription
levelstringMinimum log level: debug, info, warn, error.
colorbooleanEnable ANSI color output.

Modules are declared in the project manifest. They are expanded at config time into sources, actors, routes, transforms, and loggers. The engine never sees modules — only their expanded output.

modules:
- package: "@orgloop/module-engineering"
params:
github_repo: "my-org/my-repo"
agent_actor: engineering
github_source: github
FieldTypeRequiredDescription
packagestringYesModule package name or local path (e.g., ./modules/engineering).
paramsobjectNoParameters passed to the module for template expansion.

Use ${VAR_NAME} syntax in any config value. Variables are resolved at runtime, never stored in YAML.

config:
token: "${GITHUB_TOKEN}"
repo: "${GITHUB_REPO}"
api_key: "${LINEAR_API_KEY}"
auth_token_env: "${OPENCLAW_WEBHOOK_TOKEN}"

Rules:

  • The ${...} syntax works in any string value in any config block.
  • Variables are resolved when config is loaded (during validate, plan, and start).
  • Missing variables cause a clear error with the variable name and which config field references it.
  • Secrets should always use env var substitution. Never put credentials directly in YAML.
  • Use orgloop env to check which variables are set and which are missing.
  • Paths in the project manifest (connectors, routes, transforms, loggers) are resolved relative to the project root (the directory containing orgloop.yaml).
  • Paths inside referenced YAML files (script, prompt_file) are resolved relative to the YAML file that contains them.
  • The ~ prefix is expanded to the user’s home directory.
  • orgloop validate verifies that all referenced files exist.
orgloop.yaml
apiVersion: orgloop/v1alpha1
kind: Project
metadata:
name: engineering-org
description: "Autonomous engineering organization"
defaults:
poll_interval: 5m
log_level: info
connectors:
- connectors/github.yaml
- connectors/linear.yaml
- connectors/openclaw.yaml
- connectors/claude-code.yaml
routes:
- routes/engineering.yaml
transforms:
- transforms/transforms.yaml
loggers:
- loggers/default.yaml