A policy-aware workflow compiler that turns intent into executable plan DAGs. Built on CNCF principles.
Transform declarative CI/CD intents into deterministic execution plans with automatic environment expansion, policy validation, and multi-platform support.
Intent.yaml + Job Compositions + Schemas
↓
Planner Engine (6-stage compiler)
↓
Plan.json (Fully resolved DAG)
- 🎯 Schema-Driven - All validation rules live inside the provider
- 🔐 Policy-First - Non-negotiable constraints at the group/domain level
- 🔄 Auto-Expansion - Environment × Component matrix with intelligent merging
- 🔗 Dependency Resolution - Automatic DAG creation with cycle detection
- 🐍 Cross-Platform - Linux, macOS support (amd64, arm64)
- 🐳 OCI Distribution - Docker/Podman/containerd/Kubernetes compatible
- ⚡ Deterministic - Same inputs → Same outputs, every time
- 📊 Debuggable - Detailed phase-by-phase IR dumps
- Start with the docs landing page: website/docs/intro.mdx
- Run the local docs site:
cd website && npm install && npm run docs:start - Build the static docs site:
cd website && npm run docs:build
The docs site builds into website/docs-build/. To publish it manually to Cloudflare Pages:
cd website
npm ci
npm run docs:build
wrangler login
wrangler pages deploy docs-build --project-name arx-docsReplace arx-docs with your Cloudflare Pages project name if it is different.
Replace <tag> with the release you want from the GitHub releases page.
# macOS (arm64 - Apple Silicon)
curl -L https://github.com/sourceplane/arx/releases/download/<tag>/arx_<tag>_darwin_arm64.tar.gz | tar xz
sudo mv entrypoint /usr/local/bin/arx
chmod +x /usr/local/bin/arx
# macOS (amd64 - Intel)
curl -L https://github.com/sourceplane/arx/releases/download/<tag>/arx_<tag>_darwin_amd64.tar.gz | tar xz
sudo mv entrypoint /usr/local/bin/arx
chmod +x /usr/local/bin/arx
# Linux (amd64)
curl -L https://github.com/sourceplane/arx/releases/download/<tag>/arx_<tag>_linux_amd64.tar.gz | tar xz
sudo mv entrypoint /usr/local/bin/arx
chmod +x /usr/local/bin/arx
# Linux (arm64)
curl -L https://github.com/sourceplane/arx/releases/download/<tag>/arx_<tag>_linux_arm64.tar.gz | tar xz
sudo mv entrypoint /usr/local/bin/arx
chmod +x /usr/local/bin/arxVerify installation:
arx --version
arx --helpgit clone https://github.com/sourceplane/arx.git
cd arx
go build -o arx ./cmd/arx
sudo mv arx /usr/local/bin/# Docker
docker run ghcr.io/sourceplane/arx:<tag> plan -i intent.yaml
# Podman (recommended for CI/CD)
podman run ghcr.io/sourceplane/arx:<tag> plan -i intent.yaml
# Kubernetes
kubectl run arx --image=ghcr.io/sourceplane/arx:<tag>repo_root="$(pwd)"
tinx init demo -p ghcr.io/sourceplane/arx:<tag> as arx
tinx --workspace demo -- arx plan \
--intent "$repo_root/examples/intent.yaml" \
--config-dir "$repo_root/assets/config/compositions"# Pull the provider artifact
oras pull ghcr.io/sourceplane/arx:<tag>
# Extract binaries
tar -xzf arx_<tag>_linux_amd64_oci.tar.gz
./entrypoint plan -i intent.yaml- Core overview: docs/CORE-ARCHITECTURE.md
- Detailed design: docs/ARCHITECTURE.md
- Load & Validate - Parse YAML, validate against JSON schemas
- Normalize - Resolve wildcards, default missing fields
- Expand - Environment × Component matrix with policy merging
- Bind Jobs - Match components to job definitions, render templates
- Resolve Dependencies - Convert component deps → job deps, detect cycles
- Materialize - Output final plan with all references resolved
- Intent is policy-aware, not execution-specific
- Jobs define HOW, Intent defines WHAT
- Plans are deterministic and execution-runtime agnostic
- Schema controls everything - inputs, expansion, validation
arx/
├── cmd/arx/
│ ├── main.go # CLI entry point & command handlers
│ └── models.go # Domain models and types
├── internal/
│ ├── model/ # Data structures
│ │ ├── intent.go # Intent model
│ │ ├── job.go # Job composition model
│ │ └── plan.go # Output plan model
│ ├── loader/ # YAML parsing & loading
│ ├── schema/ # JSON Schema validation
│ ├── normalize/ # Intent canonicalization
│ ├── expand/ # Env × Component expansion
│ ├── planner/ # Dependency resolution & DAG
│ │ ├── graph.go # Graph algorithms
│ │ └── planner.go # Planner orchestration
│ └── render/ # Plan materialization
├── assets/
│ └── config/
│ ├── schemas/ # JSON schemas (intent, jobs, plan)
│ └── compositions/ # Job definitions
│ ├── charts/ # Helm Charts composition
│ ├── helm/ # Helm deployment composition
│ ├── helmCommon/ # Common Helm composition
│ └── terraform/ # Terraform composition
├── examples/
│ └── intent.yaml # Example intent file
├── docs/
│ ├── ARCHITECTURE.md # Detailed design docs
│ ├── RUNTIME_TOOLS.md # Container runtime options
│ └── *.md # Additional documentation
└── provider.yaml # Provider manifest
arx compositions --config-dir assets/config/compositionsOutput shows all available job compositions (helm, terraform, charts, etc.)
arx validate \
--intent examples/intent.yaml \
--config-dir assets/config/compositionsSee detailed logs of each compiler stage:
arx debug \
--intent examples/intent.yaml \
--config-dir assets/config/compositionsarx plan \
--intent examples/intent.yaml \
--config-dir assets/config/compositions \
--output plan.json \
--debugOutput: Fully resolved execution DAG in plan.json
docker run \
-v $(pwd):/workspace \
ghcr.io/sourceplane/arx:<tag> \
plan \
--intent /workspace/intent.yaml \
--config-dir /workspace/assets/config/compositions \
--output /workspace/plan.jsonpodman run \
-v $(pwd):/workspace \
ghcr.io/sourceplane/arx:<tag> \
plan \
--intent /workspace/intent.yaml \
--config-dir /workspace/assets/config/compositionskubectl run arx-planner \
--image=ghcr.io/sourceplane/arx:<tag> \
--rm -it \
-- plan \
--intent intent.yaml \
--config-dir /config/compositions- name: Generate CI Plan
uses: docker://ghcr.io/sourceplane/arx:<tag>
with:
args: |
plan \
--intent intent.yaml \
--config-dir assets/config/compositions \
--output plan.jsonThis container-based usage is separate from GitHub Actions compatibility mode during `arx run`. When a compiled plan contains `use:` steps, `arx run` auto-selects the GitHub Actions executor unless you explicitly set `--runner`, `ARX_RUNNER`, or a deprecated compatibility alias.
The intent file defines your desired deployment across environments.
Example:
apiVersion: sourceplane.io/v1
kind: Intent
metadata:
name: microservices-deployment
description: Multi-environment microservices deployment
discovery:
roots:
- services/
- infra/
- deploy/
# Domain-level configuration
groups:
platform:
policies:
isolation: strict
approval_required: true
defaults:
timeout: 15m
retries: 2
# Environment definitions
environments:
production:
selectors:
domains: ["platform"]
policies:
region: us-east-1
staging:
defaults:
replicas: 2
# Inline components still work when you need them
components:
- name: component-charts
type: charts
domain: platform
subscribe:
environments: [development, staging, production]
inputs:
registry: mycompany.azurecr.io/helm/chartsExternal components can live next to the code they own. Each component.yaml is loaded from the configured discovery roots, and if spec.path is omitted arx defaults the job working directory to the directory containing the manifest.
Example component.yaml:
apiVersion: sourceplane.io/v1
kind: Component
metadata:
name: web-app
spec:
type: helm
domain: platform
subscribe:
environments: [development, staging, production]
inputs:
chart: oci://mycompany.azurecr.io/helm/charts/default
dependsOn:
- component: common-servicesSchema validation at:
assets/config/schemas/intent.schema.yaml
Compositions define how to deploy components.
Available Compositions:
- helm - Helm chart deployments
- terraform - Infrastructure as code
- charts - Kubernetes manifests
- helmCommon - Common Helm definitions
Example Composition:
# assets/config/compositions/helm/job.yaml
apiVersion: sourceplane.io/v1
kind: JobRegistry
metadata:
name: helm-jobs
description: Deploy Helm charts
jobs:
- name: deploy
description: Deploy Helm charts
runsOn: ubuntu-22.04
timeout: 15m
retries: 2
steps:
- name: add-repo
run: helm repo add myrepo https://repo.example.com
- name: deploy
run: helm install {{.Component}} {{.chart}} --namespace={{.namespace}}
inputs:
chart: myrepo/chart
namespace: defaultarx also supports GitHub Actions-style use: steps inside a composition. arx run auto-selects the GitHub Actions executor when the compiled plan contains any use: step, and you can still force it with --gha.
See the example files at:
examples/compositions/gha-helm/job.yamlexamples/compositions/gha-helm/schema.yaml
Example step definitions:
steps:
- id: setup-helm
use: azure/setup-helm@v4.3.0
with:
version: "{{.helmVersion}}"
- id: setup-kubectl
use: azure/setup-kubectl@v4
with:
version: "{{.kubectlVersion}}"
- name: deploy
run: helm upgrade --install {{.Component}} {{.chart}} --namespace {{.namespacePrefix}}{{.Component}}To use that example composition:
- Copy
examples/compositions/gha-helm/into your config directory. - Set the component type to
gha-helm. - Execute the compiled plan with
arx run --plan plan.json --execute.
Example component snippet:
spec:
type: gha-helm
inputs:
chart: oci://mycompany.azurecr.io/helm/charts/default
helmVersion: v3.15.4
kubectlVersion: v1.30.2Supported use: forms in GHA mode:
owner/repo@refowner/repo/path/to/action@ref./local-actiondocker://image
For production usage, pin remote actions to a full commit SHA and make sure the runner machine has any required runtimes such as Node.js or Docker.
The generated plan is a fully resolved DAG.
Structure:
{
"apiVersion": "arx.io/v1",
"kind": "Plan",
"metadata": {
"name": "microservices-deployment",
"description": "...",
"generatedAt": "2026-04-18T00:00:00Z",
"checksum": "sha256-..."
},
"execution": {
"concurrency": 4,
"failFast": true,
"stateFile": ".arx-state.json"
},
"spec": {
"jobBindings": {
"helm": "helm-jobs",
"terraform": "terraform-jobs",
"charts": "charts-jobs"
}
},
"jobs": [
{
"id": "web-app@production.deploy",
"name": "deploy",
"component": "web-app",
"environment": "production",
"composition": "helm",
"steps": [
{
"name": "deploy",
"run": "helm install web-app repo/chart --namespace=production"
}
],
"dependsOn": ["common-services@production.deploy"],
"timeout": "15m",
"retries": 2,
"env": {
"image": "web-app:1.0",
"replicas": 3,
"namespace": "production"
},
"config": {
"image": "web-app:1.0",
"replicas": 3,
"namespace": "production"
}
}
]
}Low Priority ← Overridden by ← High Priority
1. Type defaults
2. Composition defaults
3. Domain/Group defaults
4. Environment defaults
5. Component inputs (highest)
Policy Rules: Cannot be merged or overridden - enforced at all levels
- Parse
intent.yamland compositions - Validate against JSON schemas
- Fail fast on schema violations
- Resolve component selectors
- Expand wildcards in domain/environment selectors
- Default missing fields
- Canonicalize dependency references
- For each environment, select matching components
- Skip disabled components
- Merge inputs according to precedence
- Validate policy constraints
- Match component type → composition definition
- Create JobInstance per (component × environment)
- Render step templates with merged config
- Convert component dependencies → job dependencies
- Handle same-environment and cross-environment deps
- Validate all dependencies exist
- Topological sort
- Detect cycles (error if found)
- Verify all references are concrete
- Render final
plan.json - All templates resolved
- All references concrete
- Ready for execution
# List available compositions
arx compositions \
--config-dir assets/config/compositions
# Validate intent without generating plan
arx validate \
--intent intent.yaml \
--config-dir assets/config/compositions
# Debug with detailed logging
arx debug \
--intent intent.yaml \
--config-dir assets/config/compositions
# Generate execution plan
arx plan \
--intent intent.yaml \
--config-dir assets/config/compositions \
--output plan.json \
--format json \
--debug
# Preview execution from a compiled plan (dry-run)
arx run \
--plan plan.json
# Execute plan steps
arx run \
--plan plan.json \
--execute
# Execute using the Docker backend
arx run \
--plan plan.json \
--execute \
--runner docker
# Execute using GitHub Actions compatibility mode
arx run \
--plan plan.json \
--execute \
--ghaFlags:
-i, --intent- Path to intent YAML file-c, --config-dir- Path to compositions directory (required)-o, --output- Output plan file (default: plan.json)-f, --format- Output format: json or yaml (default: json)--debug- Enable verbose logging-p, --plan- Path to compiled plan file forrun-x, --execute- Execute commands (without this,runis dry-run)--gha- Shortcut for GitHub Actions compatibility mode (--runner github-actions)--runner- Execution backend forrun:local,github-actions, ordocker
run selects its backend in this order:
--gha--runnerARX_RUNNER- Auto-detect
github-actionswhenGITHUB_ACTIONS=true - Auto-detect
github-actionswhen the compiled plan contains anyuse:step - Otherwise
local
Runner notes:
localuses the host shell and installed binaries.github-actionsenables GitHub Actions-compatibleuse:steps, expression evaluation, file commands such asGITHUB_ENVandGITHUB_OUTPUT, and post-step handling for supported actions.dockerruns each step in a fresh container, mounts the workspace at/workspace, and usesjob.runsOnas the image. Common GitHub-style labels such asubuntu-22.04map toubuntu:22.04. IfrunsOnis empty,ubuntu:22.04is used.
# Ensure path exists
ls -la assets/config/compositions/
# Use absolute path if relative doesn't work
arx plan -i intent.yaml -c $(pwd)/assets/config/compositions# Check your intent.yaml against the schema
arx validate -i intent.yaml -c assets/config/compositions# Use debug mode to see dependency graph
arx debug -i intent.yaml -c assets/config/compositions# Login to GHCR
docker login ghcr.io
# or
podman login ghcr.io- Typical plan generation: < 1 second
- Supported environments: Unlimited
- Supported components: Unlimited
- Cycle detection: O(V + E) with DFS
- Topological sort: O(V + E)
Contributions welcome! Areas:
- New composition types
- Schema enhancements
- Performance optimizations
- Documentation
- Container runtime support
- Documentation: docs/
- Examples: examples/
- Architecture: docs/ARCHITECTURE.md
- Runtime Tools: docs/RUNTIME_TOOLS.md
MIT License - See LICENSE file for details
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: team@sourceplane.io