Skip to main content
Version: Current

Syntax and Types

CRADLE scenarios use a block-oriented syntax for declaring scenario components, defining named elements and assigning properties.

This page describes the core syntax of the human-authored CRADLE language.

For a broader introduction to the language, see Language Overview.

Core syntax​

A CRADLE file is composed of blocks.

Blocks can declare collections, define named components or assign properties to a scenario section.

The main forms are:

ElementFormPurpose
Simple blockidentifier() > ... .Defines a section without a name.
Named blockidentifier("name") > ... .Defines a named component.
Propertyidentifier(value)Assigns one or more typed values to a block.
Referenceidentifier() or identifier("name")Refers to another section or named component.
Map{ key = value }Defines structured named parameters.
Separator,Separates entries inside a block or map.
Terminator.Ends a block.
Line comment// comment textAdds a comment until the end of the line.
Block comment/* comment text */Adds a comment that can span multiple lines.

A typical block looks like:

metadata() >
name("ExampleEnvironment"),
eventType("sequence").

The block begins with:

metadata()

The > operator introduces the contents of the block.

Properties are separated with commas:

,

The final property is followed by a period:

.

Simple blocks​

A simple block uses an identifier followed by empty parentheses:

identifier() >
...

For example:

networks() >
network("lan_0").

Here, networks() declares the networks used by the scenario.

Other common simple blocks include:

metadata()
instances()
networks()
events()
preEvent()
mainEvent()
postEvent()

Named blocks​

Named blocks identify a specific component using a quoted name.

The general form is:

identifier("name") >
...

For example:

instance("Client") >
os("ubuntu", "20.04").

The name:

Client

identifies this particular instance.

The same pattern is used for other named components, including networks, objects and events.

For example:

network("lan_0") >
endpoint("Client", "DHCP").
object("InitializationScript") >
location("${uriRemote}/scripts/initialize.sh").
event("initialise_client") >
instance("Client").

Properties​

Properties appear inside blocks.

The general form is:

property(value)

For example:

name("ExampleEnvironment")

Properties can accept more than one argument:

os("ubuntu", "20.04")

or:

endpoint("Client", "DHCP")

Arguments are comma-separated and enclosed in parentheses.

The properties accepted by a block depend on the type of component being defined.

Multiple properties​

A block can contain multiple properties.

Separate them with commas:

instance("Client") >
os("ubuntu", "20.04"),
object("InitializationScript"),
description("Example client system").

Do not place a comma after the final property.

The block ends with a period:

.

Strings​

CRADLE string values are written in double quotes.

For example:

name("HelloWorld")
description("Initialize the example client")
instance("Client")
subnet("192.168.10.0/24")

String values can contain spaces.

For example:

description("Initialize the example client")

Escaped characters are also supported by the grammar.

Identifiers​

Identifiers are used for block and property names.

An identifier can contain:

  • letters
  • digits
  • underscores
  • hyphens

The first character must be:

  • an ASCII letter

Examples of identifiers include:

metadata
instance
runObject
pauseBeforeRun
repositoryRemote
lan_0
note

Named CRADLE elements such as instances and networks are usually referenced through quoted string values rather than used directly as grammar identifiers.

Block terminators​

Every CRADLE block ends with a period.

For example:

networks() >
network("lan_0").

The period terminates the entire block.

It does not terminate each individual property.

For example:

instance("Client") >
os("ubuntu", "20.04"),
object("InitializationScript"),
description("Example client system").

There is only one terminating period.

Separators​

Entries inside a block are separated by commas.

For example:

instances() >
instance("Client"),
instance("Router").

The comma separates the first entry from the second.

The final entry is followed by the block terminator instead.

Comments​

CRADLE supports line comments using:

//

For example:

// Define the systems participating in the scenario
instances() >
instance("Client"),
instance("Router").

A comment continues until the end of the line.

Comments do not form part of the scenario definition.

Declarations and definitions​

A common CRADLE pattern is to declare named components first and define them separately.

For example:

instances() >
instance("Client"),
instance("Router").

This declares two instances.

Their definitions then appear in separate blocks:

instance("Client") >
os("ubuntu", "20.04").

instance("Router") >
os("ubuntu", "20.04"),
config("linux-router").

The same pattern applies to networks.

Declare:

networks() >
network("lan_0").

Then define:

network("lan_0") >
subnet("192.168.10.0/24"),
endpoint("Client", "DHCP"),
endpoint("Router", "192.168.10.1").

It also applies to events.

Declare an event within a phase:

mainEvent() >
event("initialize_client").

Then define it:

event("initialize_client") >
instance("Client"),
needRoot(false),
subject("bash", ""),
runObject("InitializationScript", "").

Named references​

Names connect declarations and definitions across a CRADLE scenario.

For example:

instances() >
instance("Client").

references:

instance("Client") >
...

Similarly:

network("lan_0") >
endpoint("Client", "DHCP").

references the instance named:

Client

An event can reference both an instance and an object:

event("initialize_client") >
instance("Client"),
runObject("InitializationScript", "").

Those names should resolve to corresponding declarations elsewhere in the scenario.

important

CRADLE names are cross-references. Use consistent spelling and capitalization whenever an instance, network, object or event is referenced.

Top-level scenario structure​

A CRADLE scenario commonly contains these principal sections:

SectionPurpose
metadata()Defines scenario-level information and artifact repositories.
instances()Declares systems participating in the scenario.
networks()Declares networks used by the scenario.
events()Declares the event lifecycle phases.
object("name")Defines an external artifact referenced by the scenario.

For example:

metadata() >
name("ExampleEnvironment"),
eventType("sequence"),
repositoryRemote("https://172.18.178.10:4443"),
object("InitializationScript").

instances() >
instance("Client"),
instance("Router").

networks() >
network("lan_0").

events() >
preEvent(),
mainEvent(),
postEvent().

The named components are then defined elsewhere in the same scenario.

Value conventions​

CRADLE values use strings, booleans, integers, durations and structured maps.

The meaning of those strings depends on the property.

Examples include:

PropertyExample value
Scenario name"HelloWorld"
Operating system"ubuntu"
Version"20.04"
Boolean valuefalse
Duration0 or 5s
Address"DHCP"
CIDR range"192.168.10.0/24"
Date-time"2026-01-15T10:00:00+00:00"
Description"Initialize the example client"

For example:

event("initialize_client") >
needRoot(false),
pauseBeforeRun(0),
scheduleExecution("2026-01-15T10:00:00+00:00").

The grammar preserves the type represented by each argument.

The compiler determines how a particular property interprets its values.

Boolean values​

Boolean properties use the unquoted literals:

true
false

For example:

needRoot(false)

Omit dependsOn() when an event has no explicit dependency.

Numeric values​

Integer and duration values are written without quotes.

For example:

pauseBeforeRun(0)
pauseAfterRun(10)

The optional s suffix explicitly denotes seconds.

Date and time values​

Scheduled event times use ISO 8601 date-time values.

For example:

scheduleExecution("2026-01-15T10:00:00+00:00")

Use a time-zone designator when specifying scheduled execution times.

Parameter maps​

Some properties accept a structured map as an additional argument.

For example:

runObject("InitializationScript", "")

For role variables, use:

role("example.collection", "router", {
lan = "lan_0"
})

Separate multiple parameters with commas. Map values can be strings, booleans, integers or durations.

For example:

runObject("InitializationScript", {
mode = "safe",
retries = 3
})

The interpretation of each parameter depends on the property using the map.

Interpolation​

CRADLE values can contain interpolated references.

For example:

object("InitializationScript") >
location("${uriRemote}/scripts/initialize.sh").

Here:

${uriRemote}

references the configured remote repository location.

Interpolation is covered in more detail in Objects and Interpolation.

Property validation​

The CRADLE grammar defines the general structure of a valid source file.

This includes:

  • blocks
  • identifiers
  • typed arguments
  • separators
  • terminators
  • comments

The grammar alone does not determine whether every property name or property value is meaningful.

CradleXC performs additional processing when it interprets the source.

For example, the grammar can recognize the general structure:

exampleProperty("value")

without the grammar itself determining whether exampleProperty is valid for the surrounding CRADLE component.

Language, compiler and schema​

CRADLE currently has several related sources that describe language behavior:

SourceResponsibility
GrammarDefines the valid structural form of CRADLE source.
CradleXCRecognizes supported CRADLE properties and processes their values.
JSON SchemaDescribes the expected structured representation and its properties.

These sources are related but are not currently identical in every case.

For example, the compiler can recognize properties or defaults that are not represented in the current schema.

The detailed differences are documented separately rather than treated as core syntax rules.

note

Do not rely on the grammar alone to determine whether a scenario has the intended meaning. Validate the scenario with CradleXC against the CRADLE release you are using.

Validate the syntax​

Use:

cxc validate -i <scenario.cradle>

For example:

cxc validate -i scenarios/HelloWorld.cradle

Validation checks the CRADLE source and reports syntax errors that need to be corrected.

For the full validation workflow, see Validate and Compile.

Example​

The following example demonstrates several core syntax features:

metadata() >
name("ExampleEnvironment"),
eventType("sequence"),
repositoryRemote("https://172.18.178.10:4443"),
object("InitializationScript").

instances() >
instance("Client"),
instance("Router").

instance("Client") >
os("ubuntu", "20.04"),
object("InitializationScript").

networks() >
network("lan_0").

network("lan_0") >
subnet("192.168.10.0/24"),
endpoint("Client", "DHCP"),
endpoint("Router", "192.168.10.1").

events() >
preEvent(),
mainEvent(),
postEvent().

mainEvent() >
event("initialize_client").

event("initialize_client") >
instance("Client"),
needRoot(false),
subject("bash", ""),
runObject("InitializationScript", ""),
pauseBeforeRun(0),
pauseAfterRun(0),
scheduleExecution("2026-01-15T10:00:00+00:00"),
description("Initialize the example client").

object("InitializationScript") >
location("${uriRemote}/scripts/initialize.sh").

This example contains:

  • a simple metadata() block
  • an instances() declaration block
  • a named instance("Client") definition
  • a network declaration and definition
  • lifecycle declarations
  • a named event definition
  • an external object definition
  • cross-references between named elements

Continue with the detailed language pages:

For a complete working scenario, see First Scenario.