7. Install the after-hours alarm
The second half of the job is not an immediate action. It is a flow that must remain installed and wait for an event.
The examples guide supplies this real flow:
{
"name": "dock door alert",
"trigger": {
"event": "sensor.door_dock.opened"
},
"steps": [
{
"id": "check",
"do": "branch",
"when": {
"gt": [
"$.world.time",
"21:00"
]
},
"then": [
{
"id": "alert",
"do": "call",
"device": "notify.facilities",
"action": "send",
"with": {
"message": "Dock door opened after hours"
}
}
]
}
]
}Make the near-miss on purpose: send a triggered flow as immediate. The response below is from a published fresh-session capture:
↑Request
{
"tool": "run_flow",
"arguments": {
"flow": {
"name": "dock door alert",
"trigger": {
"event": "sensor.door_dock.opened"
},
"steps": [
{
"id": "check",
"do": "branch",
"when": {
"gt": [
"$.world.time",
"21:00"
]
},
"then": [
{
"id": "alert",
"do": "call",
"device": "notify.facilities",
"action": "send",
"with": {
"message": "Dock door opened after hours"
}
}
]
}
]
},
"mode": "immediate",
"expected_catalog_version": "cv_590fefad56a7a504",
"trace_level": "full"
}
}↓Response
{
"run_id": "run_0003",
"outcome": {
"ok": false,
"status": "validation_error",
"error": "this flow declares a trigger; mode \"immediate\" would silently ignore it"
},
"diagnostics": [
{
"severity": "error",
"code": "bad_trigger",
"path": "/trigger",
"message": "mode \"immediate\" runs the steps once, now. It does not install the trigger",
"hint": "use mode \"deploy\" to install this flow as an automation, or remove 'trigger' to run the steps immediately"
}
]
}run_id values are session-scoped and are not gap-free. The value above belongs to the published capture.
Now change only the mode. The captured deployment result follows:
↑Request
{
"tool": "run_flow",
"arguments": {
"flow": {
"name": "dock door alert",
"trigger": {
"event": "sensor.door_dock.opened"
},
"steps": [
{
"id": "check",
"do": "branch",
"when": {
"gt": [
"$.world.time",
"21:00"
]
},
"then": [
{
"id": "alert",
"do": "call",
"device": "notify.facilities",
"action": "send",
"with": {
"message": "Dock door opened after hours"
}
}
]
}
]
},
"mode": "deploy",
"expected_catalog_version": "cv_590fefad56a7a504",
"trace_level": "full"
}
}↓Response
{
"run_id": "run_0004",
"outcome": {
"ok": true,
"status": "success",
"error": null
},
"output": {
"ref": "auto_001",
"trigger": {
"event": "sensor.door_dock.opened"
}
},
"trace": {
"run_id": "run_0004",
"level": "full",
"steps": [
{
"id": "deploy",
"input": null,
"output": {
"ref": "auto_001",
"trigger": {
"event": "sensor.door_dock.opened"
}
},
"outcome": {
"ok": true,
"status": "success",
"error": null
}
}
]
}
}Promotion is different. promote_flow stores an on-demand program callable by program_ref; it does not install a trigger.
What this taught
immediate runs now. deploy installs future behavior. A refusal can be a useful value whose diagnostic names the repair.
See Outcomes and Part II ยง6.5.7.