Intent model
Intent is where your platform's structure and standards live as code. A platform team
declares the rules once, in intent.yaml: which environments exist, which components ship
to them, which events activate what, and in what order environments promote. Each team
declares what it owns in a component.yaml next to its code: what the component is, which
golden path it follows, and what it depends on. Everything downstream reads this one
source: the planner compiles it, the catalog is derived from it, and coding agents query it
instead of guessing.
Intent says what should happen. It never says how a step executes; that belongs to compositions.
Who declares what
| Document | Declares | Owned by |
|---|---|---|
intent.yaml | Composition sources, presets, discovery roots, groups, environments, trigger bindings, platform-wide env | The platform team, one per repository |
component.yaml | One unit's name, type, domain, environment subscriptions, typed parameters, dependencies, env | The team that owns the code |
| Compositions | How a type is built: its schema, job templates, and execution profiles | The platform team, published as a Stack |
The split is the point. An application team can change its parameters without reading
runner code, and a platform team can change a golden path without touching any
component.yaml.
intent.yaml
All sections sit at the top level of the document:
apiVersion: sourceplane.io/v1
kind: Intent
metadata:
name: shop-platform
compositions: # where the golden paths come from
sources:
- name: platform
kind: oci
ref: ghcr.io/acme/platform-stack:v1.4.0 # the pin
extends: # platform rules inherited from that Stack's presets
- source: platform
preset: github-actions
discovery: # where component.yaml files are found
roots: [apps/, infra/]
env: # platform-wide environment variables
OWNER: sourceplane
groups: # defaults per domain
platform-foundation:
parameterDefaults:
"*":
namespacePrefix: platform-
environments: # where components ship, and under which rules
staging:
url: https://stage.example.com # the environment's front door
activation:
triggerRefs: [github-push-main]
parameterDefaults:
"*":
lane: verify
production:
description: Where customers are.
url: https://app.example.com
links: # further doors, after the url
- { title: API, url: https://api.example.com }
selectors:
domains: [platform-foundation, commerce]
activation:
triggerRefs: [github-tag-release]
promotion:
dependsOn:
- environment: staging
automation: # which CI events activate which environments
triggerBindings:
github-push-main:
on: { provider: github, event: push, branches: [main] }
plan: { scope: changed, base: before, head: after }
github-tag-release:
on: { provider: github, event: push, tags: ["v*"] }
plan: { scope: full }
| Section | What it declares | Read more |
|---|---|---|
compositions.sources | The golden paths this repository uses: a directory, an archive, or an OCI Stack, pinned by its reference | Stacks |
extends | Presets inherited from a Stack. The repository's own values always win; orun intent explain shows where each field came from | Intent presets |
discovery.roots | Directories scanned recursively for component.yaml, relative to the intent file. The planner and the catalog (so --changed too) scan the same roots; unset means the whole workspace. The intent file also marks the workspace root | Context discovery, where the catalog looks |
env | Platform-wide environment variables, the lowest-precedence user-declared layer | Runtime environment |
groups | Defaults shared by every component in a domain. A group is keyed by domain name: a component with domain: platform-foundation takes the platform-foundation group's defaults | Merge model |
environments | Each target environment: which components it selects (by name or domain), its parameter defaults, env, activation, promotion order, and default dependency mode. description, url (the environment's front door, an absolute http(s) address) and links describe the environment for the catalog: every environment named here is an Environment entity in the snapshot, with the url as its primary link and its promotion depth as spec.order, which the Orunbase Overview shows beside the product's description | Environment promotion, dependency rules |
automation.triggerBindings | Which CI events activate which environments, and how much of the repository each plans | Trigger bindings |
components | Optional inline components, for teams that want some declarations central |
Groups and environments also accept a policies map. It is carried onto every component
instance, but the planner and runner do not act on it yet; see
standards.
component.yaml
A component manifest sits next to the code it describes. Its fields live under spec:
apiVersion: sourceplane.io/v1
kind: Component
metadata:
name: network-foundation
spec:
type: terraform # the golden path: a composition type
domain: platform-foundation # which group's defaults apply
subscribe:
environments:
- name: development
profile: pull-request # how it may run in this environment
- name: staging
profile: verify
- name: production
profile: release
parameters: # checked against the type's schema at plan time
stackName: network-foundation
terraformDir: .
terraformVersion: 1.9.8
dependsOn:
- component: dns-zones
env:
SERVICE: platform-infra
typebinds the component to a composition.orun planchecksparametersagainst that composition's schema and fails if they do not match.subscribe.environmentslists where the component ships, as names or as objects with aprofile,profileRules, orenv. See profile rules.dependsOndeclares ordering between components. See dependency rules.changedeclares which intent sections and which outside files count as a change to this component under--changed. See change detection.secretEnvmaps variables tosecret://references, never to values. See secrets.
Merge model
At plan time, each component's parameters are merged from lowest to highest precedence:
- The environment's
parameterDefaults["*"], thenparameterDefaults[<type>]. - The component's group's
parameterDefaults["*"], thenparameterDefaults[<type>]. - The component's own
parameters.
The merged result is then checked against the composition's schema. path has its own
order: the component's path, then the group default, then the environment default, then
./. Environment variables follow a separate ladder, described in
runtime environment.
What reads intent
- The planner.
orun validatechecks the intent and its rules;orun plancompiles it, with the components and compositions, into a deterministicplan.json. See the plan DAG. - The catalog. Components, systems, domains, environments, and compositions are derived from intent, never curated by hand. See the service catalog.
- Agents.
orun mcp serveanswers an agent's questions about the repository from the same intent. See agents in orun repositories. - People.
orun intent explainandorun intent rendershow the effective intent after presets;orun component <name>shows one component's merged view.
Next: standards, the rules you can declare and which ones orun enforces, then compositions.