Start here

A guide to Runtime Conditions Profiles.

Runtime Conditions Profiles describe the external runtime integrations one workload requires. This guide starts with examples, then walks into the spec, generator, extensions, adapter, and demo.

Runtime Conditions is seeking adoption by an established parent project. These repositories are split for hands-on usability, review, demos, and implementation feedback; they are not intended to present Runtime Conditions as a standalone foundation or competing project.

The short version

  1. 1
    Source code uses integrations.The demo app calls an HTTP API and Redis.
  2. 2
    A generator emits a profile.The profile names requirements and environment variable names, not target values.
  3. 3
    An adapter fulfills the profile.The Kratix demo maps Conditions to API catalog validation, Redis provisioning, env vars, and Kubernetes resources.

Example first

A complete profile document Where this comes from
apiVersion: runtimeconditions.io/v1alpha1
kind: RuntimeConditionsProfile

metadata:
  name: request-logger-http

workload:
  uri: github.com/runtimeconditions/rc-demos/apps/request-logger-http
  version: v0.1.0

extensions:
  - https://runtimeconditions.io/extensions/common-integrations/v1alpha1/runtimeconditions.extension.yaml
  - https://runtimeconditions.io/extensions/env-configuration/v1alpha1/runtimeconditions.extension.yaml

conditions:
  - name: todos-api
    kind: api
    interface:
      type: http
      spec:
        format: openapi
        uri: catalog://api/default/todos-api
        version: 1.0.0
      operations:
        - method: GET
          path: /todos/{id}
    configuration:
      env:
        - property: baseUrl
          name: TODOS_API_URL

  - name: request-cache
    kind: cache
    interface:
      type: key_value
      engine: redis
    configuration:
      alternatives:
        - env:
            - property: url
              name: REDIS_URL
        - env:
            - property: hostname
              name: REDIS_HOST
            - property: port
              name: REDIS_PORT

The profile names the workload, declares the extensions needed to interpret its vocabulary, and lists runtime Conditions. It does not contain service URLs, Redis hostnames, credentials, or target-environment choices.

Why this exists

A developer's code needs ordinary things to work - somewhere to store files, somewhere to cache data, a way to call another team's API. None of that is unusual, and the code works fine wherever the developer first tries it. What's unusual is that this knowledge usually only lives in the developer's head, a Slack thread, or an outdated wiki page - never anywhere a machine can read it. So before anything can go live safely, a platform engineer has to dig through all of that by hand, piece it together, and set each need up separately: storage permissions here, a traffic rule there, a certificate somewhere else. Miss one, or get one slightly wrong, and nobody finds out until it's already broken in front of real users.

Then it has to happen all over again for the next environment - once for testing, once for the real thing - because none of it was ever connected back to a single source of truth.

A Runtime Conditions Profile writes that same intent down once, in plain, machine-readable form - "this needs storage," "this needs a cache," "this needs to call that API." The moment it's submitted, a check runs against it automatically, before the code ever gets a chance to run anywhere - so a missing or invalid requirement is rejected right there, with a clear reason, instead of shipping quietly and breaking later. Once it's accepted, every environment can read that same declaration and fulfill it on its own. Nobody re-derives the same fact by hand, differently, every time.

Yes, it's different from Docker Compose

A lot of teams already write a compose.yaml to describe how their services fit together, so it's a fair question: isn't that the same thing?

Not quite. A compose.yaml describes a specific, already-decided implementation - this exact Postgres image, on this exact port, wired up this exact way. Someone reading it still has to reverse-engineer the actual intent behind it: does this really have to be Postgres, or would any relational database work? What about a dependency that has no image at all, like another team's API? You can fake it with a mock, but now whoever's reading your compose file has to guess what that mock is even standing in for.

A Runtime Conditions Profile goes the other way around. It never describes a specific implementation - it describes the plain intent: "this needs a cache." It's not tied to any one image, port, or vendor, which is exactly why a platform team can decide the real implementation later, and can change it without the developer rewriting anything. And because the intent is written down cleanly in one place, you could generate a compose.yaml from a Runtime Conditions Profile for local development. Going the other way - guessing a profile out of a compose file - is a lot harder, because the intent was never written down to begin with.

How this fits with tools like Radius, Crossplane, and Kratix

There's a whole category of platform tools already doing real work here - Radius, Score, Porter, Crossplane, Sveltos, Kratix, and others. It's fair to ask where Runtime Conditions fits next to them.

The honest answer: it's less about being different from them, and more about how it fits into them. Every one of those tools starts from the same assumption - that you already know what a workload needs before you hand it to them. They're excellent at taking a known requirement and provisioning or wiring up the real thing. What none of them really solve is the step before that: capturing what a workload needs in the first place, in a plain, portable, machine-readable way, written down once by the person who actually knows the answer - the developer.

That's the gap a Runtime Conditions Profile fills. It's not a replacement for Radius or Kratix or any tool like them - it's the starting point they all assume you already have. A profile like "this needs storage," "this needs a cache," "this needs to call that API" is exactly the kind of input these tools are built to consume. Runtime Conditions isn't competing for the same job; it's producing the input that job has always needed someone to write down by hand.

Read in order

First half: what the profile is

Read chapters 2-5 to understand Conditions, profile shape, generator output, and extension vocabulary.

Second half: how it gets used

Read chapters 6-8 to understand platform adapters, the working Kratix demo, and where each source file lives.