Binding

Rules for resolving capabilities to concrete providers during execution.

Overview

Bindings connect abstract capabilities to concrete implementations. When a task requires a capability (like "can write code" or "can access database"), bindings determine which provider fulfills that requirement. Bindings use a rules-based system with selectors to match specific capabilities, plans, or nodes, and a strategy to resolve conflicts when multiple rules match.

Schema

yaml
apiVersion: planspec.io/v1alpha1
kind: Binding
metadata:
  name: string          # Required, unique identifier
  namespace: string     # Required, resource namespace
  labels: object        # Optional, key-value pairs
  annotations: object   # Optional, metadata
spec:
  strategy: string      # Optional: FirstMatch | MostSpecific | ErrorOnConflict
  rules:                # Required, array of binding rules (minItems: 1)
    - priority: number  # Optional, rule priority (higher = preferred, 0-1000)
      selector:         # Required, exactly one selector pattern
        # One of the following patterns:
        capabilityRef:    # Pattern 1: Match by capability
          name: string
        planRef:          # Pattern 2: Match by plan (alone or with nodeId/capabilityRef)
          name: string
        nodeId: string    # Used with planRef only
        matchLabels:      # Pattern 3: Match by labels (exclusive)
          <key>: <value>
      target:           # Required, the provider
        provider: string  # Provider identifier (URI recommended)
        config: object    # Provider-specific configuration

Fields

Spec Fields

FieldTypeRequiredDescription
strategystringNoConflict resolution strategy (default: FirstMatch)
rulesobject[]YesArray of binding rules (minimum 1)

Strategy Values

StrategyDescription
FirstMatchUse the first matching rule (based on priority, then array order)
MostSpecificUse the most specific matching rule
ErrorOnConflictError if multiple rules match with same priority

Rule Fields

FieldTypeRequiredDescription
prioritynumberNoRule priority 0-1000 (higher wins, default: 0)
selectorobjectYesWhat this rule matches (see Selector Patterns)
targetobjectYesThe provider to use

Selector Patterns

Selectors use exactly one of these patterns. You cannot mix patterns arbitrarily.

PatternFieldsDescription
CapabilitycapabilityRefMatch all uses of a capability across all plans
PlanplanRefMatch all nodes within a specific plan
Plan + NodeplanRef + nodeIdMatch a specific node in a specific plan
Plan + CapabilityplanRef + capabilityRefMatch a capability within a specific plan
LabelsmatchLabelsMatch plans with all specified labels

Precedence order (most specific to least): planRef+nodeId > planRef+capabilityRef > capabilityRef > planRef > matchLabels

Target Fields

FieldTypeRequiredDescription
providerstringYesProvider identifier (URI format recommended)
configobjectNoProvider-specific configuration

Status Fields

FieldTypeDescription
phasestringCurrent phase: Ready, PartiallyBound, Unresolved
totalCountnumberTotal capability requirements that need binding
boundCountnumberSuccessfully bound requirements
unboundCapabilitiesobject[]Capabilities that could not be resolved
conditionsobject[]Status conditions
observedGenerationnumberLast observed spec generation

Example

yaml
apiVersion: planspec.io/v1alpha1
kind: Binding
metadata:
  name: development-bindings
  namespace: default
spec:
  strategy: MostSpecific
  rules:
    # Pattern: capabilityRef only
    # Matches all uses of code-generation capability
    - priority: 0
      selector:
        capabilityRef:
          name: code-generation
      target:
        provider: "agent://claude-sonnet"
        config:
          model: claude-sonnet-4-20250514
          maxTokens: 8192

    # Pattern: planRef + capabilityRef
    # Higher priority for code-generation in a specific plan
    - priority: 10
      selector:
        planRef:
          name: user-auth-implementation
        capabilityRef:
          name: code-generation
      target:
        provider: "agent://claude-opus"
        config:
          model: claude-opus-4-20250514
          maxTokens: 16384

    # Pattern: planRef + nodeId
    # Specific binding for a single node
    - priority: 20
      selector:
        planRef:
          name: user-auth-implementation
        nodeId: security-review
      target:
        provider: "agent://security-specialist"
        config:
          securityLevel: high

    # Pattern: capabilityRef only
    # Default database binding
    - priority: 0
      selector:
        capabilityRef:
          name: database-access
      target:
        provider: "service://postgres"
        config:
          connectionString: "${DATABASE_URL}"
          readOnly: false

    # Pattern: matchLabels only
    # Applies to all plans with environment: production label
    - priority: 5
      selector:
        matchLabels:
          environment: production
      target:
        provider: "service://postgres-prod"
        config:
          connectionString: "${PROD_DATABASE_URL}"
          readOnly: true

    # Pattern: capabilityRef only
    # Test execution binding
    - priority: 0
      selector:
        capabilityRef:
          name: test-execution
      target:
        provider: "tool://npm-test"
        config:
          command: npm
          args: ["test"]

JSON Schema

The full JSON Schema is available at: Binding Schema

Next Steps

  • Capability - Define reusable capabilities
  • Execution - See how bindings affect execution
  • Plan - Reference capabilities in tasks