Skip to main content

CRADLE Language Structure

A CRADLE scenario is composed of named blocks. The four principal sections describe scenario metadata, instances, networks, and events. Named object definitions connect external artifacts to the scenario.

This page documents the human-authored CRADLE source language: the block syntax, declarations, references, and properties recognized by the current reference implementation. Tool developers working with structured output can consult the developer schema reference.

How to read this reference

CRADLE currently has three related sources of language behavior:

  • the grammar, which defines valid block, identifier, string, separator, and comment syntax
  • the JSON Schema, which describes the expected structured output and its required properties
  • the compiler, which recognizes CRADLE properties and supplies some defaults

These sources are not yet completely aligned. Tables on this page use the following labels:

StatusMeaning
Schema requiredThe current JSON Schema lists the property as required.
Schema optionalThe schema recognizes the property but does not require it.
Compiler extensionThe compiler recognizes the property, but the current schema does not document it.
StructuralThe property declares or links a language block rather than becoming a direct schema field.

Review the known language and schema differences at the end of this page before relying on validation alone.

Core syntax

ElementFormNotes
Simple blockidentifier() > ... .A period terminates the block.
Named blockidentifier("name") > ... .The quoted name identifies the definition.
Propertyidentifier("value")Properties contain one or more comma-separated strings.
Referenceidentifier() or identifier("name")A reference links declarations and definitions.
Separator,Separates entries inside a block.
Comment// comment textContinues to the end of the line.
IdentifierLetters, digits, and _The first character must be a letter or _.
String"quoted value"Values are double-quoted; escaped characters are supported.

The grammar validates the general shape of a file. It does not by itself restrict property names or the semantic meaning of their values.

Scenario structure

SectionPurpose
metadata()Identifies the scenario, event model, repositories, and artifacts.
instances()Declares the systems participating in the scenario.
networks()Declares networks and connects instances to them.
events()Organizes behavior into pre-event, main-event, and post-event phases.
object("name")Defines the location and optional heuristic tags of an artifact.

Names act as cross-references. An instance listed in instances() must have a matching instance("name") definition, for example. The same principle applies to networks, events, and objects.

Metadata

The metadata() block identifies the scenario and the artifacts it uses.

PropertyArgumentsStatusDescription
nameScenario nameSchema requiredHuman-readable identifier for the scenario.
eventTypesequence or DAGSchema requiredSelects a sequential or dependency-graph event model. The compiler defaults to sequence when omitted.
repositoryRemoteURISchema requiredBase location for remotely stored artifacts.
repositoryLocalLocationCompiler extensionBase location for locally available artifacts.
objectObject nameSchema requiredDeclares an artifact used by the scenario. Repeat for multiple objects.
metadata() >
name("ExampleEnvironment"),
eventType("sequence"),
repositoryRemote("https://example.com/repository"),
object("InitializationScript").
Repository values identify artifact locations. They should not contain embedded credentials.

Object definitions

Each object declared by metadata is defined in a matching named block.

PropertyArgumentsStatusDescription
locationURI or repository-relative locationStructuralLocates the corresponding artifact. ${uriRemote} can refer to the remote repository defined in metadata.
heuristicFramework, identifierCompiler extensionAssociates the object with an external classification or framework identifier. Repeat for multiple tags.
object("InitializationScript") >
location("${uriRemote}/scripts/initialize.sh"),
heuristic("mbc", "F0002").
Object names must match their declarations and references exactly.

Instances

The instances() block declares the systems in the scenario. Each system is then described in a matching instance("name") block.

PropertyArgumentsStatusDescription
instanceInstance nameStructuralDeclares an instance. Repeat for multiple systems.
osPlatform, version, architectureSchema requiredDescribes the operating system. Architecture is optional in the compiler and defaults to AMD64.
objectObject nameSchema requiredAssociates a declared object with the instance. Repeat for multiple objects.
configConfiguration nameCompiler extensionAssociates a predefined configuration with the instance. Repeat for multiple configurations.
ioI/O definition nameCompiler extensionAssociates a predefined input/output definition with the instance.
roleCollection, role, variablesSchema optional, compiler-specific formAssociates a predefined role. Variables are optional semicolon-separated key=value pairs.
descriptionTextCompiler extensionProvides a human-readable explanation of the instance.
heuristicFramework, identifierCompiler extensionAssociates an external classification or framework identifier.
instances() >
instance("Client"),
instance("Router").

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

instance("Router") >
os("ubuntu", "20.04"),
config("linux-router"),
role("example.collection", "router", "lan=lan_0").
Collection, role, configuration, and image availability can depend on the selected deployment platform and product delivery.

Networks

The networks() block declares network names. Each network definition describes its address range and connected instances.

PropertyArgumentsStatusDescription
networkNetwork nameStructuralDeclares a network. Repeat for multiple networks.
subnetIPv4 CIDR rangeSchema requiredDefines the network address range. The compiler currently permits omission and emits an empty value.
endpointInstance name, addressSchema requiredConnects a declared instance. The address defaults to DHCP when omitted by the compiler.
networks() >
network("lan_0").

network("lan_0") >
subnet("192.168.10.0/24"),
endpoint("Client", "DHCP"),
endpoint("Router", "192.168.10.1").
Endpoint names must match declared instance names. Address behavior can also depend on the selected platform.

Events

The events() block divides the scenario timeline into three phases:

  • preEvent() for preparation that occurs before the primary scenario
  • mainEvent() for the primary scenario behavior
  • postEvent() for follow-up or evidence-related activity

Each phase lists named events, and every event is described in a matching event("name") block.

PropertyArgumentsStatusDescription
eventEvent name or orderStructuralDeclares an event within a phase.
instanceInstance nameSchema requiredSelects the instance associated with the event.
needRoottrue or falseSchema requiredIndicates whether elevated privileges are requested. The compiler defaults to false.
executionFlowFlow type, timeout, poll intervalCompiler extensionSelects synchronous or asynchronous handling. Additional values apply to asynchronous handling.
subjectSubject, parametersSchema requiredIdentifies the execution subject and optional parameters.
runObjectObject name, parametersSchema requiredSelects a declared object and optional semicolon-separated key=value parameters.
pauseBeforeRunDuration in secondsSchema optionalAdds a delay before the event. The compiler defaults to 0.
pauseAfterRunDuration in secondsSchema optionalAdds a delay after the event. The compiler defaults to 0.
waitforfalse or event referenceSchema/compiler mismatchExpresses no dependency or a dependency on another event. See the compatibility note below.
scheduleExecutionISO 8601 date-timeSchema optionalAssociates the event with a scheduled time.
descriptionTextSchema optionalExplains the purpose of the event.
heuristicFramework, identifierCompiler extensionAssociates an external classification or framework identifier.
events() >
preEvent(),
mainEvent(),
postEvent().

mainEvent() >
event("1").

event("1") >
instance("Client"),
needRoot("false"),
subject("bash", ""),
runObject("InitializationScript", ""),
pauseBeforeRun("0"),
pauseAfterRun("0"),
waitfor("false"),
scheduleExecution("2026-01-15T10:00:00+00:00"),
description("Initialize the example client").
Event names or order values should be unique within the scenario. Any `instance`, `runObject`, or dependency reference must resolve to a corresponding declaration.

Heuristic properties

heuristic("framework", "identifier") can appear on supported instances, objects, and events. It adds classification metadata without replacing the underlying CRADLE definition.

See Heuristic Annotations for documented conventions and examples.

Known language and schema differences

The current reference sources contain differences that maintainers should resolve before treating the JSON Schema as the sole validation authority:

  • The grammar validates generic identifiers and quoted arguments but does not enforce recognized property names, argument counts, or allowed values.
  • The schema requires metadata properties, instance operating systems and objects, and network subnets and endpoints; the compiler supplies defaults or empty values for some of them.
  • The compiler recognizes repositoryLocal, config, io, description, heuristic, and executionFlow in contexts not represented by the current schema.
  • The schema models waitfor as true or false, while existing scenarios and compiler behavior also use event names or order identifiers.
  • The schema and compiler represent some values differently, including event delays and endpoint details.

Until these sources are aligned, validate both the language structure and its intended behavior against the CRADLE release being documented.