Status: IN
FTL2 AI-loop rules follow an observe → condition → action pattern: the loop runs `observe` to gather state, calls `condition(state)` to decide whether to act, and calls `action(ftl)` if the condition returns True.
Source: entries/2026/05/11/deployments-stargate-rules-harden_stargate_ssh.md
# From cloudflare-stargate/rules/ensure_stargate_linode.py
observe = [
{"name": "existing_linodes", "module": "community.general.linode_v4",
"params": {"label": "stargate", "state": "present"}}
]
async def condition(state: dict) -> bool:
linode = state.get("existing_linodes", {})
if linode.get("failed"):
return True
instance = linode.get("instance", {})
if not instance or instance.get("status") != "running":
return True
return False
async def action(ftl) -> None:
result = await ftl.community.general.linode_v4(
label="stargate", type="g6-standard-1", region="us-east",
image="private/37121878", state="present",
)
ip = result.get("instance", {}).get("ipv4", [None])[0]
if ip:
await ftl.wait_for(host=ip, port=22, timeout=300)