Pioreactor Experiment Profiles
Goal
Help Codex produce valid Pioreactor experiment profile YAML that matches the runtime schema and uses the supported action and expression syntax.
Experiment Profile Spec
# Main structure of the experiment profile
experiment_profile_name: <string> # Name of the experiment profile
# Metadata (optional)
metadata:
author: <string>
description: <string>
# Plugins (optional)
plugins:
- name: <string>
version: <string> # version or constraint, e.g. "1.2.3" or ">=1.2.3"
# Inputs available to expressions (optional)
inputs:
<input_name>: <value>
# Jobs common to all Pioreactors (optional)
common:
jobs:
<job_name>:
description: <string>
actions:
- # see Action definitions below
# Jobs per Pioreactor (optional)
pioreactors:
<pioreactor_unit_name>:
label: <string>
jobs:
<job_name>:
description: <string>
actions:
- # see Action definitions below
# Action definitions
# - type: log
# t: <time_string_or_float>
# if: <bool_or_expression>
# options:
# message: <string>
# level: DEBUG|debug|WARNING|warning|INFO|info|NOTICE|notice|ERROR|error (default: notice)
#
# - type: start
# t: <time_string_or_float>
# if: <bool_or_expression>
# options: {<option_name>: <value>} # expressions allowed via ${{ }}
# args: [<string>, ...]
# config_overrides: {<config_name>: <value>}
#
# - type: update
# t: <time_string_or_float>
# if: <bool_or_expression>
# options: {<option_name>: <value>} # expressions allowed via ${{ }}
#
# - type: pause
# t: <time_string_or_float>
# if: <bool_or_expression>
#
# - type: resume
# t: <time_string_or_float>
# if: <bool_or_expression>
#
# - type: stop
# t: <time_string_or_float>
# if: <bool_or_expression>
#
# - type: repeat
# t: <time_string_or_float>
# if: <bool_or_expression>
# every: <time_string_or_float>
# while: <bool_or_expression> # optional stop condition
# max_time: <time_string_or_float> # optional cap on total time loops run for
# actions:
# - # basic action only (log, start, pause, resume, stop, update)
#
# - type: when
# t: <time_string_or_float>
# if: <bool_or_expression>
# wait_until: <bool_or_expression>
# actions:
# - # any action (including repeat/when)
#
#
# Profile expression syntax (used in ${{ ... }} in options/conditions)
#
# Literals
# - Numbers: integer or float (e.g., 1, -2.5)
# - Booleans: true, false (case-insensitive)
# - Names resolve to values provided in the expression environment (inputs, etc.); otherwise they remain strings.
#
# Operators
# - Arithmetic: +, -, *, / (raises on division by zero), ** (exponent)
# - Comparisons: <, <=, ==, >=, >
# - Logical: and, or, not
# - Parentheses for precedence
#
# Functions
# - random(): float in [0,1)
# - unit(): current unit name
# - hours_elapsed(): current action time
# - experiment(): current experiment name
# - job_name(): current job name
#
# MQTT lookups
# - <unit>:<job>:<setting>[.<nested_key>]*
# - ::<job>:<setting>[.<nested_key>]* (uses current unit)
# Examples: unit():od_reading:od600, ::stirring:setting.target_rpm
# Fails if worker is inactive or topic missing.
#
# Conversion rules
# - Numeric strings become floats; "true"/"false" become booleans; otherwise strings stay strings.
# Time strings
# Accepted formats are either a number (float/int) meaning hours, or a string that is a number immediately followed by a unit:
# s, m, h, or d (case-insensitive). Examples: 0.5 (30min), "30s", "2m", "1.5h", "2d". Whitespace or extra text is rejected, and
# negative values are disallowed
#
Examples
See more examples at https://github.com/Pioreactor/experiment_profile_examples
Source: Pioreactor/pioreactor — distributed by TomeVault.
1---2name: pioreactor-experiment-profiles3description: Write, edit, review, or debug Pioreactor experiment profile YAML, including profile structure, inputs, common jobs, per-Pioreactor jobs, action timing, expressions, MQTT lookups, and repeat or wait-until blocks. Use when this capability is needed.4---56# Pioreactor Experiment Profiles78## Goal910Help Codex produce valid Pioreactor experiment profile YAML that matches the runtime schema and uses the supported action and expression syntax.1112## Experiment Profile Spec1314```15# Main structure of the experiment profile16experiment_profile_name: <string> # Name of the experiment profile171819# Metadata (optional)20metadata:21 author: <string>22 description: <string>2324# Plugins (optional)25plugins:26 - name: <string>27 version: <string> # version or constraint, e.g. "1.2.3" or ">=1.2.3"2829# Inputs available to expressions (optional)30inputs:31 <input_name>: <value>323334# Jobs common to all Pioreactors (optional)35common:36 jobs:37 <job_name>:38 description: <string>39 actions:40 - # see Action definitions below4142# Jobs per Pioreactor (optional)43pioreactors:44 <pioreactor_unit_name>:45 label: <string>46 jobs:47 <job_name>:48 description: <string>49 actions:50 - # see Action definitions below515253# Action definitions54# - type: log55# t: <time_string_or_float>56# if: <bool_or_expression>57# options:58# message: <string>59# level: DEBUG|debug|WARNING|warning|INFO|info|NOTICE|notice|ERROR|error (default: notice)60#61# - type: start62# t: <time_string_or_float>63# if: <bool_or_expression>64# options: {<option_name>: <value>} # expressions allowed via ${{ }}65# args: [<string>, ...]66# config_overrides: {<config_name>: <value>}67#68# - type: update69# t: <time_string_or_float>70# if: <bool_or_expression>71# options: {<option_name>: <value>} # expressions allowed via ${{ }}72#73# - type: pause74# t: <time_string_or_float>75# if: <bool_or_expression>76#77# - type: resume78# t: <time_string_or_float>79# if: <bool_or_expression>80#81# - type: stop82# t: <time_string_or_float>83# if: <bool_or_expression>84#85# - type: repeat86# t: <time_string_or_float>87# if: <bool_or_expression>88# every: <time_string_or_float>89# while: <bool_or_expression> # optional stop condition90# max_time: <time_string_or_float> # optional cap on total time loops run for91# actions:92# - # basic action only (log, start, pause, resume, stop, update)93#94# - type: when95# t: <time_string_or_float>96# if: <bool_or_expression>97# wait_until: <bool_or_expression>98# actions:99# - # any action (including repeat/when)100#101#102# Profile expression syntax (used in ${{ ... }} in options/conditions)103#104# Literals105# - Numbers: integer or float (e.g., 1, -2.5)106# - Booleans: true, false (case-insensitive)107# - Names resolve to values provided in the expression environment (inputs, etc.); otherwise they remain strings.108#109# Operators110# - Arithmetic: +, -, *, / (raises on division by zero), ** (exponent)111# - Comparisons: <, <=, ==, >=, >112# - Logical: and, or, not113# - Parentheses for precedence114#115# Functions116# - random(): float in [0,1)117# - unit(): current unit name118# - hours_elapsed(): current action time119# - experiment(): current experiment name120# - job_name(): current job name121#122# MQTT lookups123# - <unit>:<job>:<setting>[.<nested_key>]*124# - ::<job>:<setting>[.<nested_key>]* (uses current unit)125# Examples: unit():od_reading:od600, ::stirring:setting.target_rpm126# Fails if worker is inactive or topic missing.127#128# Conversion rules129# - Numeric strings become floats; "true"/"false" become booleans; otherwise strings stay strings.130131# Time strings132# Accepted formats are either a number (float/int) meaning hours, or a string that is a number immediately followed by a unit:133# s, m, h, or d (case-insensitive). Examples: 0.5 (30min), "30s", "2m", "1.5h", "2d". Whitespace or extra text is rejected, and134# negative values are disallowed135#136```137138139### Examples140141See more examples at https://github.com/Pioreactor/experiment_profile_examples142143---144> Source: [Pioreactor/pioreactor](https://github.com/Pioreactor/pioreactor) — distributed by [TomeVault](https://tomevault.io).145<!-- tomevault:4.0:skill_md:2026-06-26 -->