Skip to content

Add Goals and Actions

Goals define the invariants and thresholds the system must maintain. Actions define what to do when a goal is violated. Together they form the GOAP (Goal-Oriented Action Planning) loop.

Goals are evaluated continuously by GoalEvaluatorPlugin against the live world state. When a goal is violated, PlannerPluginL0 selects matching actions from ActionRegistry. ActionDispatcherPlugin fires them subject to a WIP limit.

Edit workspace/goals.yaml:

goals:
- id: my.goal
type: Threshold
severity: medium
selector: "domains.my_service.data.value"
min: 10
max: 100
description: "Value must stay between 10 and 100"

Checks a numeric value against min and/or max bounds. Both are optional — you can set only one.

- id: ci.success_rate_healthy
type: Threshold
severity: high
selector: "domains.ci.data.successRate"
min: 0.70
description: "CI success rate must stay >= 70%"

Violated when: value < min OR value > max.

Checks that a value satisfies a boolean condition.

- id: security.no_open_incidents
type: Invariant
severity: critical
selector: "domains.security.data.openIncidents"
operator: falsy
description: "No open security incidents"

Supported operators: truthy, falsy, exists, not_exists.

Violated when the operator condition is not met.

Checks that a distribution of named categories meets proportion targets, with a tolerance band.

- id: flow.distribution_balanced
type: Distribution
severity: medium
description: "Board must have >= 40% features, <= 30% defects"
distribution:
feature: 0.40
defect: 0.30
tolerance: 0.10

The selector for Distribution goals points to an object whose keys are category names and values are counts. The evaluator computes proportions and compares against the targets within tolerance.

FieldRequiredTypeDescription
idYesstringUnique goal ID. Referenced by actions via goalId.
typeYesThreshold | Invariant | DistributionEvaluation strategy.
severityYeslow | medium | high | criticalAffects planner priority and alert routing.
selectorYes (Threshold/Invariant)stringDot-path into world state.
minNo (Threshold)numberLower bound (inclusive).
maxNo (Threshold)numberUpper bound (inclusive).
operatorYes (Invariant)stringtruthy, falsy, exists, not_exists.
distributionYes (Distribution)Record<string, number>Target proportions (0–1).
toleranceNo (Distribution)numberAllowed deviation (default: 0.05).
descriptionNostringHuman-readable explanation. Appears in logs and API.

Edit workspace/actions.yaml:

actions:
- id: my.action
goalId: my.goal
tier: tier_0
priority: 10
cost: 1
name: "Human-readable name"
preconditions:
- path: "domains.my_service.data.value"
operator: lt
value: 10
effects:
- path: "domains.my_service.data.alerted"
type: set
value: true
meta:
fireAndForget: true

Preconditions guard action dispatch. All conditions must be true simultaneously for an action to be selected. If any condition fails, the action is skipped.

preconditions:
- path: "domains.my_service.data.errorCount"
operator: gt
value: 0
- path: "domains.ci.data.successRate"
operator: gte
value: 0.70
OperatorMeaning
eqStrictly equal
neqNot equal
gtGreater than
gteGreater than or equal
ltLess than
lteLess than or equal
existsKey exists and is not null/undefined
not_existsKey is missing, null, or undefined

The path is a dot-path into the world state — same syntax as selector in goals.

Effects describe how the world state changes after the action runs. They are applied by the planner when simulating action sequences (useful for tier_1/tier_2 plans). For tier_0 fire-and-forget actions they are informational.

effects:
- path: "domains.my_service.data.alertSent"
type: set
value: true
- path: "domains.my_service.data.alertCount"
type: increment
value: 1
TypeMeaning
setSet the path to value
incrementAdd value to the current numeric value
decrementSubtract value from the current numeric value
deleteRemove the key
TierMeaning
tier_0Deterministic, cheap — alert sends, ceremony triggers. Executed immediately.
tier_1A*-planned — requires plan-level sequencing, multi-step recovery.
tier_2LLM-driven — requires autonomous reasoning to decide next step.

Most alert and ceremony-trigger actions should be tier_0. Reserve higher tiers for actions that need to be sequenced with other actions or that require agent judgment.

FieldRequiredTypeDescription
idYesstringUnique action ID.
goalIdYesstringWhich goal this action remedies. Must match a goal id.
tierYestier_0 | tier_1 | tier_2Execution tier.
priorityNonumberHigher priority actions are preferred when multiple match. Default: 0.
costNonumberPlanning cost (used by A* for tier_1). Default: 1.
nameNostringHuman-readable name.
preconditionsNoarrayGuard conditions. All must be true.
effectsNoarrayWorld state mutations applied after execution.
meta.skillHintNostringSkill name to invoke. Defaults to the action id.
meta.agentIdNostringHint to route the action to a specific agent.
meta.fireAndForgetNobooleanDo not wait for a response. Default: false.

workspace/goals.yaml
goals:
- id: services.all_healthy
type: Invariant
severity: high
selector: "domains.services.metadata.failed"
operator: falsy
description: "No service collection failures"
# workspace/actions.yaml
actions:
- id: alert.service_collection_failed
goalId: services.all_healthy
tier: tier_0
priority: 20
cost: 1
name: "Alert on service collection failure"
preconditions:
- path: "domains.services.metadata.failed"
operator: exists
effects: []
meta:
fireAndForget: true
- id: ceremony.health_check
goalId: services.all_healthy
tier: tier_0
priority: 10
cost: 1
name: "Trigger health check ceremony"
preconditions:
- path: "domains.services.metadata.failed"
operator: exists
effects: []
meta:
skillHint: health_check
fireAndForget: true