Plan

A directed acyclic graph (DAG) of nodes with dependencies that describes how to achieve a goal.

Overview

Plans are the core resource in PlanSpec. They define a graph of nodes that can be executed to achieve a goal. The graph supports multiple node kinds: Tasks (work to be done), Gates (approval checkpoints), Groups (logical groupings), and External (references to external plans). Each node can have dependencies on other nodes, forming a DAG that determines execution order. Tasks can include machine-verifiable acceptance criteria that allow automated validation of completion.

Schema

yaml
apiVersion: planspec.io/v1alpha1
kind: Plan
metadata:
  name: string          # Required, unique identifier
  namespace: string     # Required, resource namespace
  labels: object        # Optional, key-value pairs
  annotations: object   # Optional, metadata
spec:
  description: string   # Required, what this plan accomplishes
  goalRef:              # Optional, reference to a Goal
    name: string        # Name of the goal this plan achieves
  series: string        # Optional, plan series identifier (requires version)
  version: string       # Optional, plan version (requires series)
  supersedes:           # Optional, references to plans this supersedes
    - name: string
  graphDigest: string   # Optional, hash of the graph for integrity
  context: object[]     # Optional, contextual attachments
  graph:
    nodes:              # Required, list of nodes (minItems: 1)
      - id: string      # Required, unique node identifier
        kind: string    # Required: Task | Gate | Group | External
        # ... kind-specific fields
    edges:              # Optional, explicit dependency edges
      - from: string
        to: string
        type: string    # hard | soft
status:
  phase: string         # Ready | Invalid
  nodeCount: number     # Total number of nodes in the graph
  conditions: object[]  # Status conditions
  observedGeneration: number  # Last observed generation

Fields

Spec Fields

FieldTypeRequiredDescription
descriptionstringYesWhat this plan accomplishes
goalRefobjectNoReference to the goal this plan achieves
goalRef.namestringYes*Name of the referenced goal (*if goalRef provided)
seriesstringNoPlan series identifier (requires version)
versionstringNoVersion within the series (requires series)
supersedesobject[]NoReferences to plans this plan supersedes
graphDigeststringNoHash of the graph for integrity verification
contextobject[]NoContextual attachments
graphobjectYesThe node graph
graph.nodesNode[]YesList of nodes (minimum 1)
graph.edgesEdge[]NoExplicit dependency edges

Node Kinds

KindDescription
TaskWork to be performed by an agent or tool
GateApproval checkpoint referencing a Gate resource
GroupLogical grouping of other nodes
ExternalReference to an external system or process

Task Node Fields

FieldTypeRequiredDescription
idstringYesUnique identifier within the plan
kindstringYesMust be "Task"
namestringNoHuman-readable name
descriptionstringNoWhat this task accomplishes
dependsOnstring[]NoIDs of nodes that must complete first
capabilityRefsobject[]NoRequired capabilities to execute this task
inputsobjectNoInput parameters for the task
outputsstring[]NoExpected output names
timeoutstringNoMaximum time allowed for task execution
retriesnumberNoNumber of retry attempts on failure (0-10)
whenstringNoConditional expression for task execution
estimatedEffortstringNoEffort level: small, medium, large, xlarge
acceptanceCriteriaobject[]NoMachine-verifiable success criteria

Gate Node Fields

FieldTypeRequiredDescription
idstringYesUnique identifier within the plan
kindstringYesMust be "Gate"
namestringNoHuman-readable name
descriptionstringNoWhat this gate approves
dependsOnstring[]NoIDs of nodes that must complete first
gateRefobjectYesReference to the Gate resource
gateRef.namestringYesName of the Gate resource

Acceptance Criteria Types

TypeRequired FieldsDescription
artifact_existsname, pathVerify a file or directory exists
test_passesname, commandRun a test command and check exit code
endpoint_respondsname, urlCheck HTTP endpoint responds correctly
command_succeedsname, commandRun a shell command and verify success
customname, webhookUrl, expectedResponseCustom webhook validation

Acceptance Criteria Common Fields

FieldTypeRequiredDescription
idstringNoUnique identifier for this criterion
namestringYesHuman-readable name
typestringYesCriterion type
requiredbooleanNoWhether this criterion is required (default: true)
timeoutstringNoTimeout for verification
extensionsobjectNoExtension data

Acceptance Criteria Field Details

artifact_exists

FieldTypeRequiredDescription
pathstringYesPath to the file or directory
contentMatchstringNoRegex pattern to match file content

test_passes / command_succeeds

FieldTypeRequiredDescription
commandstringYesCommand to execute
argsstring[]NoCommand arguments
expectedExitCodenumberNoExpected exit code (default: 0)
outputMatchstringNoRegex pattern to match output (command_succeeds only)

endpoint_responds

FieldTypeRequiredDescription
urlstringYesURL to check
methodstringNoHTTP method (default: GET)
expectedStatusnumberNoExpected status code (default: 200)
bodyMatchstringNoRegex pattern to match response body

custom

FieldTypeRequiredDescription
webhookUrlstringYesURL to call for validation
payloadobjectNoPayload to send with the request
expectedResponseobjectYesExpected response constraints

Status Fields

FieldTypeDescription
phasestringPlan validity phase: Ready or Invalid
nodeCountnumberTotal number of nodes in the graph
conditionsobject[]Status conditions with details
observedGenerationnumberLast observed spec generation

Example

yaml
apiVersion: planspec.io/v1alpha1
kind: Plan
metadata:
  name: user-auth-implementation
  namespace: default
  labels:
    component: auth
spec:
  description: Implementation plan for user authentication system
  series: user-auth
  version: "1.0.0"
  goalRef:
    name: user-authentication
  graph:
    nodes:
      - id: setup-database
        kind: Task
        name: Setup Database
        description: Create users table with required columns
        timeout: 30m
        estimatedEffort: small
        acceptanceCriteria:
          - type: command_succeeds
            name: Users table exists
            command: psql
            args: ["-c", "SELECT 1 FROM users LIMIT 1"]

      - id: implement-signup
        kind: Task
        name: Implement Signup
        description: Create signup endpoint with email validation
        dependsOn: [setup-database]
        estimatedEffort: medium
        capabilityRefs:
          - name: code-generation
        inputs:
          language: typescript
          framework: express
        outputs: [signup_endpoint, validation_logic]
        acceptanceCriteria:
          - type: endpoint_responds
            name: Signup endpoint works
            url: http://localhost:3000/api/signup
            method: POST
            expectedStatus: 201
          - type: test_passes
            name: Signup tests pass
            command: npm
            args: ["test", "--", "--grep", "signup"]

      - id: implement-login
        kind: Task
        name: Implement Login
        description: Create login endpoint with JWT generation
        dependsOn: [setup-database]
        estimatedEffort: medium
        acceptanceCriteria:
          - type: endpoint_responds
            name: Login returns JWT
            url: http://localhost:3000/api/login
            method: POST
            expectedStatus: 200

      - id: security-review
        kind: Gate
        name: Security Review
        description: Security team reviews authentication implementation
        dependsOn: [implement-signup, implement-login]
        gateRef:
          name: auth-security-review

      - id: implement-refresh
        kind: Task
        name: Implement Refresh
        description: Add refresh token endpoint
        dependsOn: [security-review]
        estimatedEffort: small
        acceptanceCriteria:
          - type: endpoint_responds
            name: Refresh endpoint works
            url: http://localhost:3000/api/refresh
            method: POST
            expectedStatus: 200

JSON Schema

The full JSON Schema is available at: Plan Schema

Next Steps