product: maestro
audience: test-developer
authority: normative
YAML Schema Reference
Top-level structure
test: # REQUIRED root key
name: "string" # REQUIRED — display name, stored in every result record
version: "1.0.0" # REQUIRED — semantic version, bump before every deployment
device: "string" # optional — DUT identifier
test.version must be a quoted string in full three-part semantic version format:
"MAJOR.MINOR.PATCH".
| ✅ Valid |
❌ Invalid |
Reason |
version: "1.0.0" |
version: 1.0 |
Two-part version — PATCH part missing |
version: "2.3.1" |
version: 1.0.0 |
Unquoted — YAML parses as a float 1.0 (loses PATCH) |
version: "1.0.0-rc1" |
version: "v1.0.0" |
v prefix — not stored consistently |
Always quote the value and always increment before deploying — the version is
stored with every test result and is the only field that lets you correlate a result
record to a specific revision of the test definition.
Tip: validate_yaml will reject a missing version but does not currently check
the format. Use the three-part rule above to avoid ambiguous result records.
Top-level fields (continued)
test:
name: "string"
version: "1.0.0"
device: "string" # optional — DUT identifier
tags: # optional — key-value metadata (JSONB in DB)
ProductId: "PCB-100"
ProductRevision: "Rev C"
required_tags: # optional — keys that must be non-empty before Start
- ProductId
variables: # optional — initial variable values
var_name: value
setup: # optional — steps run before main steps
- { step }
steps: # REQUIRED — main test body
- { step }
teardown: # optional — steps run after main steps
- { step }
policy: # optional — test-level defaults
on_step_failure: "abort" # "abort" | "continue" (default: "abort")
timeout: 300 # overall test timeout in seconds
required_tags: is an optional list of tag key strings. The Start Test button on
the Test Monitor page stays disabled until every listed key has a non-empty value.
test:
name: "Board Functional Test"
version: "1.0.0"
tags:
ProductId: ""
BatchId: ""
required_tags:
- ProductId
- BatchId
steps:
- name: "Measure 3V3 Rail"
...
- Required keys render in an amber-highlighted section above optional tags.
- Well-known keys (
ProductId, ProductRevision, BatchId, Notes) render as
dedicated labelled inputs. Any other key gets a dynamic text input.
- When connected to MES, the MES system populates required_tags keys before the
operator sees the Start button.
- All tags are accessible in steps as
{{exec.tag.<Key>}}.
A required tag key may be given a non-empty default value in the tags: section.
When the operator selects that test file the Start Test dialog pre-fills the
corresponding input with the default. The operator can still edit the value before
starting.
tags:
ProductId: "ESH10000633" # pre-filled — operator can edit
ProductRevision: "R1" # pre-filled — operator can edit
AccordionA2_SN: "" # blank — operator must scan/type
NTop_SN: "" # blank — operator must scan/type
FixtureLink_SN: ""
FE_SN: ""
required_tags:
- ProductId
- ProductRevision
- AccordionA2_SN
- NTop_SN
- FixtureLink_SN
- FE_SN
| Tag |
Default in tags: |
Start dialog behaviour |
ProductId |
"ESH10000633" |
Pre-filled, editable |
ProductRevision |
"R1" |
Pre-filled, editable |
AccordionA2_SN |
"" |
Empty — operator must fill |
NTop_SN |
"" |
Empty — operator must fill |
Tip: Use defaults for values that are the same across most runs (e.g. product ID,
board revision) and leave serial-number fields empty so the operator is forced to
scan each barcode individually.
Step fields — complete reference
Identity and routing
| Field |
Type |
Required |
Description |
name |
string |
✅ |
Step display name |
type |
string |
— |
Built-in type: delay, mock, prompt, manual, sequence |
runner |
string |
— |
Runner: dotnet, python |
runner_type |
string |
— |
Version: net10.0, python3.11 |
runner_identifier |
string |
— |
Named runner instance |
.NET runner fields
| Field |
Type |
Required |
Description |
assembly |
string |
✅ (dotnet) |
DLL filename: "MyTests.dll" |
class |
string |
✅ (dotnet) |
Fully-qualified class: "MyTests.PowerTests" |
method |
string |
✅ (dotnet) |
Method name: "MeasureVoltage" |
Python runner fields
| Field |
Type |
Required |
Description |
module |
string |
✅ (python) |
Dotted module path: "instruments.dmm" |
function |
string |
✅ (python) |
Function name: "read_voltage" |
Sequence fields
| Field |
Type |
Required |
Description |
sequence |
string |
✅ (sequence) |
Package-relative path to YAML file |
Data flow
| Field |
Type |
Description |
parameters |
map |
Key-value pairs passed to runner. Values support {{var}} templates |
outputs |
map |
Maps return keys to variable names |
measurement |
object |
Single measurement point |
measurements |
array |
Multiple measurement points (takes precedence over measurement) |
Timing
| Field |
Type |
Description |
duration |
float |
delay steps only. Pause in seconds |
timeout_ms |
int |
Per-attempt wall-clock timeout. Exceeded → ABORTED |
Runtime control
| Field |
Type |
Default |
Description |
enabled |
bool |
true |
false → immediately SKIPPED |
precondition |
string |
— |
Boolean expression; false → SKIPPED |
force |
string |
— |
pass | fail | skip | run |
retry |
object |
— |
{count: int, delay_ms: int} |
repeat |
object |
— |
{condition: string, max_iterations: int} |
timeout_ms |
int |
— |
Per-attempt wall-clock timeout |
run_on_abort |
bool |
false |
Execute even when test is aborting |
requires |
array |
— |
Shared resources to lock exclusively while the step runs, e.g. [dmm, mux]. Serialises access under parallel execution; no effect on single-execution stations. See yaml/runtime-control.md |
Post-execution
| Field |
Type |
Default |
Description |
post_execution_action |
string |
continue |
continue | terminate-on-fail | terminate-always |
Prompt fields
| Field |
Type |
Required |
Description |
prompt.message |
string |
✅ |
Instruction text (Markdown supported) |
prompt.title |
string |
— |
Title above message |
prompt.image |
string |
— |
Image URL or package-relative path |
prompt.video |
string |
— |
Video URL |
prompt.buttons |
array |
— |
[{name: string, action: string}] |
prompt.buttons[].action |
string |
✅ |
continue | pass | fail | abort |
prompt.timeout |
object |
— |
{seconds: int, default_button: string} |
prompt.default_button |
string |
— |
Button triggered by Enter key |
prompt.input |
object |
— |
Value-input control — see ui/prompt-input.md |