{
  "$schema": "https://farmslot.io/schemas/action-manifest-v1.schema.json",
  "actions": {
    "command": {
      "description": "Run a shell command from the project root.",
      "examples": [
        {
          "action": "command",
          "cmd": "pwd",
          "intent": "Prepare the project state needed for this proof.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "cmd": {
            "type": "string"
          },
          "command": {
            "type": "string"
          },
          "cwd": {
            "type": "string"
          },
          "timeout_ms": {
            "type": "number"
          },
          "allow_failure": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      }
    },
    "wait": {
      "description": "Base wait action.",
      "examples": [
        {
          "action": "wait",
          "duration_ms": 1,
          "intent": "Allow the requested asynchronous state to settle.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "duration_ms": {
            "type": "integer"
          },
          "ms": {
            "type": "integer"
          }
        },
        "additionalProperties": false
      }
    },
    "assert_file": {
      "description": "Assert that a project file exists and optionally contains text.",
      "examples": [
        {
          "action": "assert_file",
          "path": "reports/result.txt",
          "contains": "ok",
          "intent": "Confirm the requested project file state.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string"
          },
          "contains": {
            "type": "string"
          }
        },
        "required": ["path"],
        "additionalProperties": false
      }
    },
    "assert_json": {
      "description": "Assert a JSON file value with a JSONPath-style selector.",
      "examples": [
        {
          "action": "assert_json",
          "path": "reports/result.json",
          "assert": {
            "path": "$.status",
            "operator": "eq",
            "value": "ok"
          },
          "intent": "Confirm the recorded data satisfies the requested condition.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string"
          },
          "assert": {
            "type": "object",
            "properties": {
              "path": {
                "type": "string"
              },
              "operator": {
                "type": "string"
              },
              "value": {
                "type": [
                  "string",
                  "number",
                  "integer",
                  "boolean",
                  "object",
                  "array"
                ],
                "items": {
                  "type": ["string", "number", "integer", "boolean", "object"]
                }
              },
              "all": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "any": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "none": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            },
            "additionalProperties": false
          }
        },
        "required": ["path", "assert"],
        "additionalProperties": false
      }
    },
    "assert_exit_code": {
      "description": "Assert the exit code captured from a command node output.",
      "examples": [
        {
          "action": "assert_exit_code",
          "source": "run-tests",
          "expected": 0,
          "intent": "Confirm the project command completed with the expected result.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string"
          },
          "node": {
            "type": "string"
          },
          "expected": {
            "type": "number"
          }
        },
        "additionalProperties": false
      }
    },
    "assert_output": {
      "description": "Assert stdout or stderr captured from a command node output.",
      "examples": [
        {
          "action": "assert_output",
          "source": "run-tests",
          "stream": "stdout",
          "contains": "PASS",
          "intent": "Confirm the recorded output satisfies the requested condition.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string"
          },
          "node": {
            "type": "string"
          },
          "stream": {
            "type": "string"
          },
          "contains": {
            "type": "string"
          },
          "match": {
            "type": "string"
          },
          "assert": {
            "type": "object",
            "properties": {
              "path": {
                "type": "string"
              },
              "operator": {
                "type": "string"
              },
              "value": {
                "type": [
                  "string",
                  "number",
                  "integer",
                  "boolean",
                  "object",
                  "array"
                ],
                "items": {
                  "type": ["string", "number", "integer", "boolean", "object"]
                }
              },
              "all": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "any": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "none": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      }
    },
    "watch_logs": {
      "description": "Base log assertion/capture action.",
      "examples": [
        {
          "action": "watch_logs",
          "path": "logs/app.log",
          "intent": "Observe the runtime behavior needed for this proof.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string"
          },
          "contains": {
            "type": "string"
          },
          "scope": {
            "type": "string",
            "enum": ["run", "file"]
          }
        },
        "required": ["path"],
        "additionalProperties": false
      }
    },
    "index_artifacts": {
      "description": "Index extra recipe-authored artifacts that already exist on disk. Do not use after ui.screenshot; screenshots are registered by the runner.",
      "examples": [
        {
          "action": "index_artifacts",
          "artifacts": [
            {
              "path": "reports/result.json",
              "type": "report",
              "category": "validation",
              "label": "Validation report"
            }
          ],
          "intent": "Preserve generated evidence in the review package.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "artifacts": {
            "type": "array",
            "items": {
              "type": ["string", "object"],
              "properties": {
                "path": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "nodeId": {
                  "type": "string"
                },
                "mimeType": {
                  "type": "string"
                },
                "category": {
                  "type": "string"
                },
                "proofTarget": {
                  "type": "string"
                },
                "covers": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "additionalProperties": false
            }
          }
        },
        "required": ["artifacts"],
        "additionalProperties": false
      }
    },
    "end": {
      "description": "Base terminal action.",
      "examples": [
        {
          "action": "end",
          "status": "pass"
        }
      ]
    },
    "call": {
      "description": "Invoke a named recipe by ref and run its steps inline.",
      "examples": [
        {
          "action": "call",
          "ref": "mydev.open_perps_setup",
          "intent": "Run a personal Perps setup recipe",
          "next": "done"
        }
      ]
    },
    "switch": {
      "description": "Choose a graph branch when one resolved string equals another.",
      "examples": [
        {
          "action": "switch",
          "value": "{{params.mode}}",
          "equals": "background_resume",
          "cases": {
            "match": "background"
          },
          "default": "warm",
          "intent": "Choose the graph path matching the observed state."
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string"
          },
          "equals": {
            "type": "string"
          }
        },
        "required": ["value", "equals"],
        "additionalProperties": false
      },
      "result_cases": ["match"]
    },
    "ui.navigate": {
      "description": "Navigate by semantic page intent through the adapter-owned current route mapping, then verify the live destination. Route drift fails loudly; raw route/screen params must be verified against the current app first.",
      "schema": {
        "type": "object",
        "properties": {
          "page": {
            "type": "string",
            "enum": ["home", "perps", "perps-market-list", "perps-market", "swap"]
          },
          "market": {
            "type": "string"
          },
          "symbol": {
            "type": "string"
          },
          "mode": {
            "type": "string",
            "enum": [
              "lite",
              "pro"
            ],
            "default": "lite"
          },
          "url": {
            "type": "string"
          },
          "hash": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "route": {
            "type": "string"
          },
          "screen": {
            "type": "string"
          },
          "params": {
            "type": "object"
          },
          "timeout_ms": {
            "type": "number"
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "ui.navigate",
          "page": "perps",
          "intent": "Open the requested application surface.",
          "next": "done"
        },
        {
          "action": "ui.navigate",
          "page": "perps-market",
          "market": "ETH",
          "intent": "Open the requested application surface.",
          "next": "done"
        },
        {
          "action": "ui.navigate",
          "route": "PerpsMarketListView",
          "intent": "Open the requested application surface.",
          "next": "done"
        }
      ]
    },
    "ui.press": {
      "description": "Press a React Native component by exact testID/test_id, selector identifier, or contained visible text.",
      "schema": {
        "type": "object",
        "properties": {
          "selector": {
            "type": "string"
          },
          "test_id": {
            "type": "string"
          },
          "testID": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "timeout_ms": {
            "type": "number"
          },
          "settle": {
            "type": "boolean"
          },
          "long_press": {
            "type": "boolean",
            "description": "Invoke the target component's long-press gesture. Requires identifier targeting."
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "ui.press",
          "test_id": "perps-tab",
          "intent": "Activate the requested visible control.",
          "next": "done"
        },
        {
          "action": "ui.press",
          "text": "Ethereum",
          "intent": "Activate the requested visible control.",
          "next": "done"
        },
        {
          "action": "ui.press",
          "test_id": "keypad-delete-button",
          "long_press": true,
          "intent": "Activate the requested visible control.",
          "next": "done"
        }
      ]
    },
    "ui.key_press": {
      "description": "Send a trusted keyboard press to the currently focused UI element through the UI transport.",
      "schema": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "timeout_ms": {
            "type": "number"
          },
          "settle": {
            "type": "boolean"
          }
        },
        "required": ["key"],
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "ui.key_press",
          "key": "Enter",
          "intent": "Continue the requested keyboard interaction.",
          "next": "done"
        }
      ]
    },
    "ui.set_input": {
      "description": "Set text on a React Native TextInput by testID through the app control bridge.",
      "schema": {
        "type": "object",
        "properties": {
          "selector": {
            "type": "string"
          },
          "test_id": {
            "type": "string"
          },
          "testID": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "timeout_ms": {
            "type": "number"
          },
          "settle": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "ui.set_input",
          "test_id": "network-selector-network-search-input",
          "value": "Sepolia",
          "intent": "Provide the requested value in the visible form.",
          "next": "done"
        }
      ]
    },
    "ui.scroll": {
      "description": "Scroll through the UI through the Farmslot base platform adapter. Supports deltas and scroll_into_view for selector/test-id proof positioning.",
      "examples": [
        {
          "action": "ui.scroll",
          "delta_y": 300,
          "intent": "Expose the requested content for visible review.",
          "next": "done"
        },
        {
          "action": "ui.scroll",
          "test_id": "wallet-screen",
          "scroll_into_view": true,
          "intent": "Expose the requested content for visible review.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "selector": {
            "type": "string"
          },
          "test_id": {
            "type": "string"
          },
          "testID": {
            "type": "string"
          },
          "delta_x": {
            "type": "number"
          },
          "delta_y": {
            "type": "number"
          },
          "deltaX": {
            "type": "number"
          },
          "deltaY": {
            "type": "number"
          },
          "offset": {
            "type": "number"
          },
          "measure_from_test_id": {
            "type": "string",
            "description": "Visible start target sampled inside the app immediately before scrolling. Requires exactly one measurement target."
          },
          "measure_target_test_id": {
            "type": "string",
            "description": "Visible testID whose first in-app observation ends the measured scroll transition. Mutually exclusive with measure_target_text."
          },
          "measure_target_text": {
            "type": "string",
            "description": "Visible text whose first in-app observation ends the measured scroll transition. Mutually exclusive with measure_target_test_id."
          },
          "measure_required_present_test_id": {
            "type": "string",
            "description": "Optional React-tree testID that must be present at the same observation as the visible measurement target."
          },
          "scroll_into_view": {
            "type": "boolean"
          },
          "into_view": {
            "type": "boolean"
          },
          "animated": {
            "type": "boolean"
          },
          "timeout_ms": {
            "type": "number"
          },
          "settle": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      }
    },
    "ui.swipe": {
      "description": "Swipe from a test-id target or screen coordinates in one cardinal direction through the shared native UI provider.",
      "schema": {
        "type": "object",
        "properties": {
          "target": {
            "type": ["string", "object"],
            "properties": {
              "x": { "type": "number" },
              "y": { "type": "number" }
            },
            "required": ["x", "y"],
            "additionalProperties": false
          },
          "direction": {
            "type": "string",
            "enum": ["up", "down", "left", "right"]
          },
          "distance": { "type": "number", "minimum": 1 },
          "duration_ms": { "type": "integer", "minimum": 1 },
          "timeout_ms": { "type": "integer", "minimum": 1 },
          "settle": { "type": "boolean" }
        },
        "required": ["target", "direction", "distance", "duration_ms"],
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "ui.swipe",
          "target": "example-scrollable",
          "direction": "up",
          "distance": 240,
          "duration_ms": 300,
          "intent": "Swipe the requested visible surface.",
          "next": "done"
        }
      ]
    },
    "ui.pan": {
      "description": "Pan from a test-id target or screen coordinates through the shared native UI provider.",
      "schema": {
        "type": "object",
        "properties": {
          "target": {
            "type": ["string", "object"],
            "properties": {
              "x": { "type": "number" },
              "y": { "type": "number" }
            },
            "required": ["x", "y"],
            "additionalProperties": false
          },
          "path": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1,
            "items": {
              "type": "object",
              "properties": {
                "x": { "type": "number" },
                "y": { "type": "number" }
              },
              "required": ["x", "y"],
              "additionalProperties": false
            }
          },
          "delta": {
            "type": "object",
            "properties": {
              "x": { "type": "number" },
              "y": { "type": "number" }
            },
            "required": ["x", "y"],
            "additionalProperties": false
          },
          "duration_ms": { "type": "integer", "minimum": 1 },
          "timeout_ms": { "type": "integer", "minimum": 1 },
          "settle": { "type": "boolean" }
        },
        "required": ["target", "duration_ms"],
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "ui.pan",
          "target": "example-surface",
          "path": [{ "x": 80, "y": 20 }],
          "duration_ms": 400,
          "intent": "Pan through the requested pointer path.",
          "next": "done"
        }
      ]
    },
    "ui.drag": {
      "description": "Drag a test-id target or screen coordinate through the shared native UI provider.",
      "schema": {
        "type": "object",
        "properties": {
          "target": {
            "type": ["string", "object"],
            "properties": {
              "x": { "type": "number" },
              "y": { "type": "number" }
            },
            "required": ["x", "y"],
            "additionalProperties": false
          },
          "path": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1,
            "items": {
              "type": "object",
              "properties": {
                "x": { "type": "number" },
                "y": { "type": "number" }
              },
              "required": ["x", "y"],
              "additionalProperties": false
            }
          },
          "delta": {
            "type": "object",
            "properties": {
              "x": { "type": "number" },
              "y": { "type": "number" }
            },
            "required": ["x", "y"],
            "additionalProperties": false
          },
          "duration_ms": { "type": "integer", "minimum": 1 },
          "timeout_ms": { "type": "integer", "minimum": 1 },
          "settle": { "type": "boolean" }
        },
        "required": ["target", "duration_ms"],
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "ui.drag",
          "target": "example-slider",
          "delta": { "x": 120, "y": 0 },
          "duration_ms": 500,
          "intent": "Drag the requested control to a new value.",
          "next": "done"
        }
      ]
    },
    "ui.long_press": {
      "description": "Hold a test-id target or screen coordinate through the shared native UI provider.",
      "schema": {
        "type": "object",
        "properties": {
          "target": {
            "type": ["string", "object"],
            "properties": {
              "x": { "type": "number" },
              "y": { "type": "number" }
            },
            "required": ["x", "y"],
            "additionalProperties": false
          },
          "hold_ms": { "type": "integer", "minimum": 1 },
          "timeout_ms": { "type": "integer", "minimum": 1 },
          "settle": { "type": "boolean" }
        },
        "required": ["target", "hold_ms"],
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "ui.long_press",
          "target": "example-control",
          "hold_ms": 700,
          "intent": "Hold the requested visible control.",
          "next": "done"
        }
      ]
    },
    "ui.wait_for": {
      "description": "Wait for a React Native testID/test_id or text target. expected=visible requires a measured viewport intersection; expected=present only requires the mounted tree.",
      "schema": {
        "type": "object",
        "properties": {
          "selector": {
            "type": "string"
          },
          "test_id": {
            "type": "string"
          },
          "testID": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "text_match": {
            "type": "string"
          },
          "textMatch": {
            "type": "string"
          },
          "expected": {
            "type": "string",
            "enum": ["present", "visible", "absent", "hidden", "not_present"]
          },
          "visible": {
            "type": "boolean"
          },
          "timeout_ms": {
            "type": "number"
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "ui.wait_for",
          "test_id": "perps-home-heading",
          "expected": "present",
          "intent": "Confirm the requested application state is visible.",
          "next": "done"
        },
        {
          "action": "ui.wait_for",
          "test_id": "conditional-banner",
          "expected": "absent",
          "intent": "Confirm the requested application state is visible.",
          "next": "done"
        },
        {
          "action": "ui.wait_for",
          "text": "Limit long",
          "expected": "visible",
          "intent": "Confirm the requested text is actually inside the viewport.",
          "next": "done"
        }
      ]
    },
    "ui.locators": {
      "description": "List ranked, copy-pasteable ui.press targets from the current ui.visible observation. Prefer high-confidence test IDs when updating durable recipe source after exploratory interaction.",
      "execution_capabilities": ["host-read-export"],
      "schema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "ui.locators",
          "intent": "Find stable targets for durable recipe authoring.",
          "next": "done"
        }
      ]
    },
    "ui.screenshot": {
      "description": "Capture registered PNG evidence with xcrun simctl on iOS or adb screencap on Android. Artifact metadata records the native provider, command mode, and selected device; invalid or empty PNG output fails before registration.",
      "examples": [
        {
          "action": "ui.screenshot",
          "path": "screenshots/example.png",
          "intent": "Preserve the visible application state as review evidence.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "timeout_ms": {
            "type": "number"
          }
        },
        "additionalProperties": false
      }
    },
    "ui.capture_surface": {
      "description": "Capture the complete current native scroll surface as one registered PNG while leaving ui.screenshot viewport-only.",
      "schema": {
        "type": "object",
        "properties": {
          "path": { "type": "string" },
          "label": { "type": "string" },
          "surface_test_id": { "type": "string" },
          "until_test_id": { "type": "string" },
          "max_scrolls": { "type": "integer", "minimum": 1 },
          "restore_position": { "type": "boolean" }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "ui.capture_surface",
          "path": "screenshots/full-screen.png",
          "surface_test_id": "screen-scroll-surface",
          "until_test_id": "screen-bottom",
          "intent": "Preserve the complete scrollable context for human review.",
          "next": "done"
        }
      ]
    },
    "app.lifecycle": {
      "description": "Drive outer mobile app lifecycle for deterministic performance start states without rebuilding: foreground/launch, background, terminate, or restart the installed app.",
      "examples": [
        {
          "action": "app.lifecycle",
          "command": "background",
          "settle_ms": 1000,
          "intent": "Converge the application to the requested lifecycle state.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "command": {
            "type": "string",
            "enum": [
              "launch",
              "foreground",
              "background",
              "terminate",
              "restart"
            ]
          },
          "event": {
            "type": "string",
            "enum": [
              "launch",
              "foreground",
              "background",
              "terminate",
              "restart"
            ]
          },
          "state": {
            "type": "string",
            "enum": [
              "launch",
              "foreground",
              "background",
              "terminate",
              "restart"
            ]
          },
          "settle_ms": {
            "type": "integer"
          },
          "timeout_ms": {
            "type": "integer"
          },
          "runtime_ready_timeout_ms": {
            "type": "integer"
          },
          "require_process_continuity": {
            "type": "boolean"
          },
          "platform": {
            "type": "string",
            "enum": ["ios", "android"]
          },
          "watcher_port": {
            "type": "number"
          },
          "metro_port": {
            "type": "number"
          },
          "launch_url": {
            "type": "string"
          },
          "launchUrl": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "adb_serial": {
            "type": "string"
          },
          "android_device": {
            "type": "string"
          },
          "device": {
            "type": "string"
          },
          "package_id": {
            "type": "string"
          },
          "packageName": {
            "type": "string"
          },
          "app_id": {
            "type": "string"
          },
          "simulator": {
            "type": "string"
          },
          "ios_simulator": {
            "type": "string"
          },
          "bundle_id": {
            "type": "string"
          },
          "bundleId": {
            "type": "string"
          }
        },
        "additionalProperties": false
      }
    },
    "app.network": {
      "description": "Set the selected Android device offline or online for deterministic network-recovery recipes. iOS simulator network mutation is refused until a safe device-scoped mechanism exists.",
      "examples": [
        {
          "action": "app.network",
          "state": "offline",
          "settle_ms": 3000,
          "intent": "Disconnect the selected device before exercising recovery.",
          "next": "restore-network"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "state": {
            "type": "string",
            "enum": ["offline", "online"]
          },
          "settle_ms": {
            "type": "integer"
          },
          "adb_serial": {
            "type": "string"
          },
          "device": {
            "type": "string"
          }
        },
        "required": ["state"],
        "additionalProperties": false
      },
      "execution_capabilities": ["app-mutation"]
    },
    "app.network_capture": {
      "description": "Capture redacted HTTP requests between named Recipe Protocol v1 nodes through the adapter's persistent Network observer.",
      "examples": [
        {
          "action": "app.network_capture",
          "phase": "start",
          "id": "perps-home",
          "url_includes": ["api.hyperliquid.xyz/info"],
          "methods": ["POST"],
          "body_json_fields": ["type", "req.coin", "dex"],
          "intent": "Start the redacted request window",
          "next": "exercise-flow"
        },
        {
          "action": "app.network_capture",
          "phase": "end",
          "id": "perps-home",
          "artifact_path": "network/perps-home.json",
          "intent": "End and index the redacted request window",
          "next": "assert-network"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "phase": {
            "type": "string",
            "enum": ["start", "end"]
          },
          "id": {
            "type": "string"
          },
          "url_includes": {
            "type": "array",
            "items": { "type": "string" }
          },
          "methods": {
            "type": "array",
            "items": { "type": "string" }
          },
          "body_json_fields": {
            "type": "array",
            "items": { "type": "string" }
          },
          "max_requests": {
            "type": "integer"
          },
          "max_duration_ms": {
            "type": "integer"
          },
          "artifact_path": {
            "type": "string"
          }
        },
        "required": ["phase", "id"],
        "additionalProperties": false
      },
      "execution_capabilities": []
    },
    "app.network_assert": {
      "description": "Assert a previously indexed app.network_capture summary without hiding its diagnostics on failure.",
      "examples": [
        {
          "action": "app.network_assert",
          "id": "perps-home",
          "artifact_path": "network/perps-home.json",
          "required_status": "complete",
          "required_min_requests": 1,
          "required_types": ["allMids"],
          "forbidden_types": ["candleSnapshot"],
          "intent": "Assert the indexed request summary",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "artifact_path": {
            "type": "string"
          },
          "required_status": {
            "type": "string",
            "enum": ["complete", "partial", "unavailable"]
          },
          "required_min_requests": {
            "type": "integer"
          },
          "required_max_requests": {
            "type": "integer"
          },
          "required_types": {
            "type": "array",
            "items": { "type": "string" }
          },
          "forbidden_types": {
            "type": "array",
            "items": { "type": "string" }
          }
        },
        "required": ["id"],
        "additionalProperties": false
      },
      "execution_capabilities": []
    },
    "app.performance_capture": {
      "description": "Capture bounded CDP native UI frame metrics and separately labelled JavaScript work across Recipe Protocol v1 node boundaries.",
      "examples": [
        {
          "action": "app.performance_capture",
          "phase": "start",
          "id": "homepage-scroll",
          "max_duration_ms": 300000,
          "intent": "Start the bounded UI smoothness window",
          "next": "exercise-flow"
        },
        {
          "action": "app.performance_capture",
          "phase": "end",
          "id": "homepage-scroll",
          "artifact_path": "performance/homepage-scroll.json",
          "html_path": "performance/homepage-scroll.html",
          "intent": "End and index the UI smoothness window",
          "next": "assert-performance"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "phase": {
            "type": "string",
            "enum": ["start", "end"]
          },
          "id": {
            "type": "string"
          },
          "max_duration_ms": {
            "type": "integer",
            "minimum": 1,
            "description": "Maximum accepted at runtime: 3600000 ms."
          },
          "artifact_path": {
            "type": "string"
          },
          "html_path": {
            "type": "string"
          }
        },
        "required": ["phase", "id"],
        "additionalProperties": false
      },
      "execution_capabilities": ["host-read-export"]
    },
    "app.performance_assert": {
      "description": "Assert a previously indexed app.performance_capture summary without hiding unavailable or partial source coverage.",
      "examples": [
        {
          "action": "app.performance_assert",
          "id": "homepage-scroll",
          "artifact_path": "performance/homepage-scroll.json",
          "required_status": ["complete", "partial"],
          "minimum_frame_count": 1,
          "require_native_ui_when_supported": true,
          "required_node_ids": ["scroll-homepage"],
          "intent": "Assert the indexed UI smoothness summary",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "artifact_path": {
            "type": "string"
          },
          "required_status": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["complete", "partial", "unavailable"]
            }
          },
          "minimum_frame_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Minimum native UI frame count. JavaScript task count cannot satisfy this assertion."
          },
          "require_native_ui_when_supported": {
            "type": "boolean"
          },
          "required_node_ids": {
            "type": "array",
            "items": { "type": "string" }
          }
        },
        "required": ["id"],
        "additionalProperties": false
      },
      "execution_capabilities": ["host-read-export"]
    },
    "app.status": {
      "description": "Report the adapter's static status — platform, project root, resolved checkout shape, and headless compatibility mode (no live route or account).",
      "examples": [
        {
          "action": "app.status",
          "intent": "Record the resolved application state before continuing.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      }
    },
    "app.hud": {
      "description": "Display minimal human-readable recipe progress. The intent must explain the current agent goal; debug metadata and grouping labels are hidden unless explicitly opted in.",
      "examples": [
        {
          "action": "app.hud",
          "status": "running",
          "intent": "Show the current goal to the supervising human.",
          "progress": {
            "current": 12,
            "total": 19
          },
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "clear": {
            "type": "boolean"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": ["running", "pass", "fail"]
          },
          "node_id": {
            "type": "string"
          },
          "nodeId": {
            "type": "string"
          },
          "phase": {
            "type": "string"
          },
          "action_name": {
            "type": "string"
          },
          "recipe_action": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "detail": {
            "type": "string"
          },
          "error": {
            "type": "string"
          },
          "display": {
            "type": "object"
          },
          "progress": {
            "type": "object"
          }
        },
        "additionalProperties": false
      }
    },
    "cdp.target": {
      "description": "Probe the platform debug transport — Chrome CDP for extension, the React Native debug bridge for mobile — and report whether it is reachable.",
      "examples": [
        {
          "action": "cdp.target",
          "require_reachable": true,
          "intent": "Confirm the requested application target is available.",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "cdp_port": {
            "type": "number"
          },
          "metro_port": {
            "type": "number"
          },
          "watcher_port": {
            "type": "number"
          },
          "probe_timeout_ms": {
            "type": "number"
          },
          "cdp_timeout_ms": {
            "type": "number"
          },
          "timeout_ms": {
            "type": "number"
          },
          "require_reachable": {
            "type": "boolean"
          },
          "required": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      }
    },
    "metamask.wallet.fixture_status": {
      "description": "Report the on-disk wallet fixture status (accounts and password presence) without launching or mutating the app.",
      "schema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.wallet.fixture_status",
          "intent": "Check wallet fixture status",
          "next": "done"
        }
      ],
      "execution_capabilities": []
    },
    "metamask.wallet.validate_import": {
      "description": "Validate wallet recovery credentials and derive the expected primary address without launching or mutating the app.",
      "schema": {
        "type": "object",
        "properties": {
          "credential_source": {
            "type": "string",
            "enum": ["auto", "environment", "fixture"]
          },
          "srp_env": {
            "type": "string"
          },
          "password_env": {
            "type": "string"
          },
          "metametrics": {
            "type": "boolean"
          },
          "interests": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.wallet.validate_import",
          "credential_source": "auto",
          "intent": "Validate recovery credentials before resetting a wallet",
          "next": "done"
        }
      ],
      "execution_capabilities": [
        "host-read-export"
      ]
    },
    "metamask.wallet.setup": {
      "description": "Import the wallet fixture accounts and password so the app starts from a known signed-in state.",
      "schema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.wallet.setup",
          "intent": "Prepare the wallet fixture for recipe execution",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.wallet.import": {
      "description": "Make the wallet ready by reusing a fixture-backed profile or importing the primary mnemonic through visible onboarding UI.",
      "schema": {
        "type": "object",
        "properties": {
          "method": {
            "type": "string",
            "enum": ["auto", "profile", "ui"]
          },
          "credential_source": {
            "type": "string",
            "enum": ["auto", "environment", "fixture"]
          },
          "srp_env": {
            "type": "string"
          },
          "password_env": {
            "type": "string"
          },
          "metametrics": {
            "type": "boolean",
            "default": false,
            "description": "Enable MetaMetrics during visible onboarding."
          },
          "biometrics": {
            "type": "boolean",
            "enum": [false],
            "default": false,
            "description": "Biometric authentication is disabled because unattended recipes cannot satisfy the device prompt."
          },
          "notifications": {
            "type": "boolean",
            "default": false,
            "description": "Enable push notifications during Mobile onboarding; defaults off."
          },
          "skip_wallet_tour": {
            "type": "boolean",
            "default": true,
            "description": "Skip the Mobile wallet-home tour after onboarding; defaults on so recipes reach a usable wallet."
          },
          "interests": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["swap_tokens", "trade_perpetuals", "prediction_markets", "send_receive_crypto", "earn_and_spend", "use_other_crypto_apps"]
            },
            "default": [],
            "description": "Select optional onboarding interests; an empty list skips the questionnaire."
          },
          "timeout_ms": {
            "type": "number"
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.wallet.import",
          "method": "auto",
          "intent": "Use an existing fixture profile or import through onboarding",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.wallet.reset": {
      "description": "Delete the current wallet through the visible client reset flow and reach fresh onboarding.",
      "schema": {
        "type": "object",
        "properties": {
          "timeout_ms": {
            "type": "number"
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.wallet.reset",
          "intent": "Reset the wallet through visible UI before importing it again",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.wallet.ensure_unlocked": {
      "description": "Unlock the wallet with the fixture password when it is currently locked.",
      "schema": {
        "type": "object",
        "properties": {
          "target_timeout_ms": {
            "type": "number"
          },
          "unlock_timeout_ms": {
            "type": "number"
          },
          "stable_unlocked_ms": {
            "type": "number",
            "minimum": 0,
            "description": "How long the unlocked route must remain stable before the action succeeds; zero disables the extra stability window."
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.wallet.ensure_unlocked",
          "intent": "Ensure the wallet is unlocked before proof steps",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.wallet.lock": {
      "description": "Lock the Android Mobile wallet through the visible menu and confirm the login screen on development or opaque clients.",
      "schema": {
        "type": "object",
        "properties": {
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 30000 }
        },
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.wallet.lock",
        "intent": "Lock the wallet through visible native controls",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.wallet.select_account": {
      "description": "mobile action to select a wallet account by address, id, or display name.",
      "schema": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "description": "EVM address of the account to select."
          },
          "id": {
            "type": "string",
            "description": "Internal account id to select."
          },
          "name": {
            "type": "string",
            "description": "Display name of the account to select."
          },
          "cdp_timeout_ms": {
            "type": "number",
            "minimum": 1,
            "description": "Maximum time in milliseconds for the mobile CDP command."
          },
          "timeout_ms": {
            "type": "number",
            "minimum": 1,
            "description": "Maximum time in milliseconds to observe the requested account as selected."
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.wallet.select_account",
          "address": "0x8dc623e964475d4d669da601fd15ea9125469003",
          "intent": "Select the requested wallet account",
          "next": "done"
        },
        {
          "action": "metamask.wallet.select_account",
          "name": "dev1",
          "intent": "Select the requested wallet account",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.wallet.list_accounts": {
      "description": "List redacted wallet accounts and identify the selected account without mutating the app.",
      "schema": {
        "type": "object",
        "properties": {
          "scope": {
            "type": "string",
            "default": "named",
            "enum": ["selected", "named", "evm", "all"],
            "description": "Account scope. Defaults to named human-visible accounts; use selected for the active account, evm for EVM accounts, or all for the full inventory."
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.wallet.list_accounts",
          "intent": "Discover the available wallet accounts",
          "next": "done"
        }
      ],
      "execution_capabilities": []
    },
    "metamask.wallet.read_state": {
      "description": "Read the redacted wallet state (selected account, route, and device) from the running app.",
      "schema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.wallet.read_state",
          "intent": "Read wallet state needed for the proof",
          "next": "done"
        }
      ],
      "execution_capabilities": []
    },
    "metamask.assets.read_visible_state": {
      "description": "Read and assert bounded visible wallet assets from an opaque Mobile runtime through native accessibility.",
      "schema": {
        "type": "object",
        "properties": {
          "minimum_asset_count": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "minimum_price_change_count": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "minimum_without_price_change_count": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "require_symbols": {
            "type": "array",
            "items": { "type": "string" },
            "maxItems": 50
          },
          "require_fiat": {
            "type": "boolean",
            "default": false
          },
          "require_price_change_styling": {
            "type": "boolean",
            "default": false
          },
          "max_items": {
            "type": "integer",
            "minimum": 1,
            "default": 100
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.assets.read_visible_state",
          "minimum_asset_count": 2,
          "require_symbols": ["USDC", "BNB"],
          "require_fiat": true,
          "minimum_price_change_count": 1,
          "minimum_without_price_change_count": 1,
          "intent": "Assert live wallet assets through native accessibility",
          "next": "done"
        }
      ],
      "execution_capabilities": ["host-read-export"]
    },
    "metamask.assets.open_details": {
      "description": "Open one visible Mobile asset by symbol through native accessibility.",
      "schema": {
        "type": "object",
        "properties": {
          "symbol": { "type": "string" },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 30000 }
        },
        "required": ["symbol"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.assets.open_details",
        "symbol": "ETH",
        "intent": "Open the funded ETH details",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.assets.read_details": {
      "description": "Read and assert the visible Mobile token details surface through native accessibility.",
      "schema": {
        "type": "object",
        "properties": {
          "expected_symbol": { "type": "string" },
          "require_chart": { "type": "boolean", "default": false },
          "require_market_cap": { "type": "boolean", "default": false },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 30000 }
        },
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.assets.read_details",
        "expected_symbol": "ETH",
        "require_chart": true,
        "require_market_cap": true,
        "intent": "Prove current asset market data",
        "next": "done"
      }],
      "execution_capabilities": ["host-read-export"]
    },
    "metamask.assets.verify_sorting": {
      "description": "Select alphabetical and declining-fiat token sorting and assert the visible native row order.",
      "schema": {
        "type": "object",
        "properties": {
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 30000 }
        },
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.assets.verify_sorting",
        "intent": "Verify both token-list sort modes",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.assets.set_token_visibility": {
      "description": "Import or remove one Mobile token through visible native controls and verify the resulting state.",
      "schema": {
        "type": "object",
        "properties": {
          "query": { "type": "string" },
          "visible": { "type": "boolean" },
          "require_unchanged": { "type": "boolean", "default": false },
          "require_change": { "type": "boolean", "default": false },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 45000 }
        },
        "required": ["query", "visible"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.assets.set_token_visibility",
        "query": "DAI",
        "visible": true,
        "intent": "Import DAI through visible token search",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.assets.import_custom_token": {
      "description": "Import one ERC-20 on a selected Mobile network through the visible custom-token form and verify its row.",
      "schema": {
        "type": "object",
        "properties": {
          "network": { "type": "string" },
          "chain_id": { "type": "integer", "minimum": 1 },
          "address": { "type": "string" },
          "expected_symbol": { "type": "string" },
          "decimals": { "type": "integer", "minimum": 0 },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 60000 }
        },
        "required": ["network", "chain_id", "address", "expected_symbol"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.assets.import_custom_token",
        "network": "Arbitrum",
        "chain_id": 42161,
        "address": "0xDA10009cbd5D07dd0CeCc66161FC93D7c9000da1",
        "expected_symbol": "DAI",
        "decimals": 18,
        "intent": "Import Arbitrum DAI by contract address",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.networks.read_visible_state": {
      "description": "Read one Mobile network from visible network settings and prove it persists across a bounded settle window.",
      "schema": {
        "type": "object",
        "properties": {
          "network": { "type": "string" },
          "chain_id": { "type": "integer", "minimum": 1 },
          "settle_ms": { "type": "integer", "minimum": 0, "default": 0 },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 30000 }
        },
        "required": ["network", "chain_id"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.networks.read_visible_state",
        "network": "PulseChain",
        "chain_id": 369,
        "settle_ms": 1000,
        "intent": "Prove PulseChain remains in Mobile network settings",
        "next": "done"
      }],
      "execution_capabilities": ["host-read-export"]
    },
    "metamask.networks.add_custom": {
      "description": "Add or locate one custom Mobile network through visible native network settings.",
      "schema": {
        "type": "object",
        "properties": {
          "network": { "type": "string" },
          "rpc_url": { "type": "string" },
          "chain_id": { "type": "integer", "minimum": 1 },
          "symbol": { "type": "string" },
          "explorer_url": { "type": "string" },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 60000 }
        },
        "required": ["network", "rpc_url", "chain_id", "symbol"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.networks.add_custom",
        "network": "PulseChain",
        "rpc_url": "https://rpc.pulsechain.com",
        "chain_id": 369,
        "symbol": "PLS",
        "explorer_url": "https://scan.pulsechain.com",
        "intent": "Add PulseChain through Mobile network settings",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.networks.remove_custom": {
      "description": "Remove one custom Mobile network through visible native network settings.",
      "schema": {
        "type": "object",
        "properties": {
          "network": { "type": "string" },
          "chain_id": { "type": "integer", "minimum": 1 },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 30000 }
        },
        "required": ["network", "chain_id"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.networks.remove_custom",
        "network": "PulseChain",
        "chain_id": 369,
        "intent": "Remove PulseChain through Mobile network settings",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.swap_bridge.read_visible_state": {
      "description": "Read and assert the visible Swap surface from an opaque Mobile runtime through native accessibility.",
      "schema": {
        "type": "object",
        "properties": {
          "source_symbol": { "type": "string" },
          "destination_symbol": { "type": "string" },
          "require_amount_inputs": { "type": "boolean", "default": true },
          "require_settings": { "type": "boolean", "default": false },
          "require_quote": { "type": "boolean", "default": false },
          "expected_slippage": { "type": "number", "minimum": 0 }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.swap_bridge.read_visible_state",
          "require_amount_inputs": true,
          "require_settings": true,
          "intent": "Assert the visible Swap surface",
          "next": "done"
        }
      ],
      "execution_capabilities": ["host-read-export"]
    },
    "metamask.swap_bridge.set_slippage": {
      "description": "Set a custom Swap slippage percentage through native accessibility.",
      "schema": {
        "type": "object",
        "properties": {
          "percent": { "type": "number", "minimum": 0.01 },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 30000 }
        },
        "required": ["percent"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.swap_bridge.set_slippage",
        "percent": 3,
        "intent": "Set the release checklist custom slippage value",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.swap_bridge.submit_transaction": {
      "description": "Submit an explicitly authorized live Mobile Swap and prove its terminal post-trade status and visible Activity entry.",
      "schema": {
        "type": "object",
        "properties": {
          "source_symbol": { "type": "string" },
          "destination_symbol": { "type": "string" },
          "amount": { "type": ["string", "number"] },
          "confirm_live": { "type": "boolean", "default": false },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 300000 }
        },
        "required": ["source_symbol", "destination_symbol", "amount"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.swap_bridge.submit_transaction",
        "source_symbol": "ETH",
        "destination_symbol": "DAI",
        "amount": "0.00005",
        "confirm_live": true,
        "intent": "Submit the authorized release-check Swap and prove its Activity entry",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation", "external-mutation"]
    },
    "metamask.swap_bridge.set_max_amount": {
      "description": "Use the visible Swap Max control and wait for the derived live quote through native accessibility.",
      "schema": {
        "type": "object",
        "properties": {
          "wait_for_quote": { "type": "boolean", "default": true },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 60000 }
        },
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.swap_bridge.set_max_amount",
        "wait_for_quote": true,
        "intent": "Use the available token balance for the return Swap",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.swap_bridge.select_assets": {
      "description": "Select exact Swap source and destination assets through native accessibility.",
      "schema": {
        "type": "object",
        "properties": {
          "source_symbol": { "type": "string" },
          "destination_symbol": { "type": "string" },
          "source_chain": { "type": "string" },
          "destination_chain": { "type": "string" },
          "source_query": { "type": "string" },
          "destination_query": { "type": "string" },
          "source_asset_id": { "type": "string" },
          "destination_asset_id": { "type": "string" },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 60000 }
        },
        "required": ["source_symbol", "destination_symbol", "source_chain", "destination_chain"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.swap_bridge.select_assets",
        "source_symbol": "ETH",
        "destination_symbol": "WETH",
        "source_chain": "eip155:1",
        "destination_chain": "eip155:1",
        "intent": "Select the funded Swap pair",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.swap_bridge.set_amount": {
      "description": "Enter a positive Swap amount through native accessibility and wait for a quote or explicit no-route state.",
      "schema": {
        "type": "object",
        "properties": {
          "amount": { "type": "number", "minimum": 0.00000001 },
          "wait_for_quote": { "type": "boolean", "default": true },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 60000 }
        },
        "required": ["amount"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.swap_bridge.set_amount",
        "amount": 0.0001,
        "intent": "Enter a capped Swap amount and wait for the quote",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.perps.read_visible_state": {
      "description": "Read and assert bounded visible Perps UI state from an opaque Mobile runtime through native accessibility.",
      "schema": {
        "type": "object",
        "properties": {
          "surface": {
            "type": "string",
            "enum": ["auto", "home", "market-list", "market-details", "order-entry", "activity", "funds"],
            "default": "auto"
          },
          "market": {
            "type": "string",
            "description": "Optional market that must be present in the visible state."
          },
          "minimum_market_count": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "maximum_market_count": {
            "type": "integer",
            "minimum": 0,
            "default": 200
          },
          "minimum_position_count": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "maximum_position_count": {
            "type": "integer",
            "minimum": 0,
            "default": 200
          },
          "minimum_order_count": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "maximum_order_count": {
            "type": "integer",
            "minimum": 0,
            "default": 200
          },
          "minimum_activity_count": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "forbid_test_ids": {
            "type": "array",
            "items": { "type": "string" },
            "maxItems": 100
          },
          "require_test_ids": {
            "type": "array",
            "items": { "type": "string" },
            "maxItems": 100
          },
          "require_features": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["activity", "balance", "chart", "long-short", "market-list", "order-entry", "price", "price-change", "stats"]
            },
            "maxItems": 9
          },
          "include_offscreen": {
            "type": "boolean",
            "default": true
          },
          "max_items": {
            "type": "integer",
            "minimum": 1,
            "default": 100
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.read_visible_state",
          "surface": "market-details",
          "market": "ETH",
          "require_features": ["price", "stats", "long-short"],
          "intent": "Assert the selected live Perps market through native accessibility",
          "next": "done"
        }
      ],
      "execution_capabilities": ["host-read-export"]
    },
    "metamask.perps.search_markets": {
      "description": "Enter a Perps market query through native accessibility and prove visible results are returned.",
      "schema": {
        "type": "object",
        "properties": {
          "query": { "type": "string" },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 30000 }
        },
        "required": ["query"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.perps.search_markets",
        "query": "Bitcoin",
        "intent": "Filter the visible Perps market list",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.perps.set_market_favorite": {
      "description": "Converge one visible Perps market watchlist state through native accessibility.",
      "schema": {
        "type": "object",
        "properties": {
          "market": { "type": "string" },
          "favorite": { "type": "boolean" },
          "require_unchanged": { "type": "boolean", "default": false },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 30000 }
        },
        "required": ["market", "favorite"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.perps.set_market_favorite",
        "market": "BTC",
        "favorite": true,
        "intent": "Ensure BTC appears in the Perps watchlist",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.perps.read_positions": {
      "description": "mobile Read live Perps positions; without a selector, return all live positions.",
      "schema": {
        "type": "object",
        "properties": {
          "market": {
            "type": "string",
            "description": "Single market symbol, e.g. BTC or ETH. Alias: symbol."
          },
          "symbol": {
            "type": "string",
            "description": "Alias for market."
          },
          "markets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Explicit list of market symbols."
          },
          "symbols": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Alias for markets."
          },
          "mode": {
            "type": "string",
            "enum": ["matching", "all"],
            "description": "matching selects requested symbols; all selects every live item returned by the product."
          },
          "selector": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              }
            },
            "additionalProperties": false
          },
          "side": {
            "type": "string",
            "enum": ["long", "short"],
            "description": "Optional position/order side filter."
          },
          "timeout_ms": {
            "type": "number"
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.read_positions",
          "market": "BTC",
          "intent": "Read Perps positions needed for the proof",
          "next": "done"
        }
      ],
      "execution_capabilities": []
    },
    "metamask.perps.read_orders": {
      "description": "mobile Read live Perps open orders; without a selector, return all live orders.",
      "schema": {
        "type": "object",
        "properties": {
          "market": {
            "type": "string",
            "description": "Single market symbol, e.g. BTC or ETH. Alias: symbol."
          },
          "symbol": {
            "type": "string",
            "description": "Alias for market."
          },
          "markets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Explicit list of market symbols."
          },
          "symbols": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Alias for markets."
          },
          "mode": {
            "type": "string",
            "enum": ["matching", "all"],
            "description": "matching selects requested symbols; all selects every live item returned by the product."
          },
          "selector": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              }
            },
            "additionalProperties": false
          },
          "side": {
            "type": "string",
            "enum": ["long", "short"],
            "description": "Optional position/order side filter."
          },
          "timeout_ms": {
            "type": "number"
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.read_orders",
          "market": "BTC",
          "intent": "Read Perps open orders needed for the proof",
          "next": "done"
        }
      ],
      "execution_capabilities": []
    },
    "metamask.perps.close_positions": {
      "description": "mobile Default to testnet for Perps mutations; mainnet is read-only unless explicitly requested. Close selected live Perps positions. Use selector/mode params to close matching symbols or all positions.",
      "schema": {
        "type": "object",
        "properties": {
          "market": {
            "type": "string",
            "description": "Single market symbol, e.g. BTC or ETH. Alias: symbol."
          },
          "symbol": {
            "type": "string",
            "description": "Alias for market."
          },
          "markets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Explicit list of market symbols."
          },
          "symbols": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Alias for markets."
          },
          "mode": {
            "type": "string",
            "enum": ["matching", "all"],
            "description": "matching selects requested symbols; all selects every live item returned by the product."
          },
          "selector": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              }
            },
            "additionalProperties": false
          },
          "side": {
            "type": "string",
            "enum": ["long", "short"],
            "description": "Optional position/order side filter."
          },
          "timeout_ms": {
            "type": "number"
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.close_positions",
          "mode": "all",
          "intent": "Close selected Perps positions before continuing",
          "next": "done"
        },
        {
          "action": "metamask.perps.close_positions",
          "markets": ["BTC", "ETH"],
          "intent": "Close selected Perps positions before continuing",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation", "external-mutation"]
    },
    "metamask.perps.close_orders": {
      "description": "mobile Default to testnet for Perps mutations; mainnet is read-only unless explicitly requested. Cancel selected live Perps open orders. Use selector/mode params to cancel matching symbols or all orders.",
      "schema": {
        "type": "object",
        "properties": {
          "market": {
            "type": "string",
            "description": "Single market symbol, e.g. BTC or ETH. Alias: symbol."
          },
          "symbol": {
            "type": "string",
            "description": "Alias for market."
          },
          "markets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Explicit list of market symbols."
          },
          "symbols": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Alias for markets."
          },
          "mode": {
            "type": "string",
            "enum": ["matching", "all"],
            "description": "matching selects requested symbols; all selects every live item returned by the product."
          },
          "selector": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              }
            },
            "additionalProperties": false
          },
          "side": {
            "type": "string",
            "enum": ["long", "short"],
            "description": "Optional position/order side filter."
          },
          "timeout_ms": {
            "type": "number"
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.close_orders",
          "mode": "all",
          "intent": "Cancel selected Perps orders before continuing",
          "next": "done"
        },
        {
          "action": "metamask.perps.close_orders",
          "market": "BTC",
          "intent": "Cancel selected Perps orders before continuing",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation", "external-mutation"]
    },
    "metamask.perps.place_order": {
      "description": "mobile Place a Perps order through a supported app/API path. Default to testnet; mainnet order placement requires an explicit user request.",
      "schema": {
        "type": "object",
        "properties": {
          "market": {
            "type": "string",
            "description": "Single market symbol, e.g. BTC or ETH. Alias: symbol."
          },
          "symbol": {
            "type": "string",
            "description": "Alias for market."
          },
          "markets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Explicit list of market symbols."
          },
          "symbols": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Alias for markets."
          },
          "mode": {
            "type": "string",
            "enum": ["matching", "all"],
            "description": "matching selects requested symbols; all selects every live item returned by the product."
          },
          "selector": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              }
            },
            "additionalProperties": false
          },
          "side": {
            "type": "string",
            "enum": ["long", "short"],
            "description": "Required order direction."
          },
          "timeout_ms": {
            "type": "number"
          },
          "amount": {
            "type": ["string", "number"],
            "description": "USD amount/notional alias."
          },
          "notional": {
            "type": ["string", "number"],
            "description": "USD notional alias."
          },
          "size": {
            "type": "string",
            "description": "Base asset size when supported."
          },
          "leverage": {
            "type": "number",
            "default": 3
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.place_order",
          "market": "BTC",
          "side": "long",
          "notional": "10",
          "leverage": 2,
          "intent": "Place the requested Perps order",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation", "external-mutation"]
    },
    "metamask.perps.assert_positions": {
      "description": "mobile Assert live Perps positions are present or absent for an explicit market selection or mode=all.",
      "schema": {
        "type": "object",
        "properties": {
          "market": {
            "type": "string",
            "description": "Single market symbol, e.g. BTC or ETH. Alias: symbol."
          },
          "symbol": {
            "type": "string",
            "description": "Alias for market."
          },
          "markets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Explicit list of market symbols."
          },
          "symbols": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Alias for markets."
          },
          "mode": {
            "type": "string",
            "enum": ["matching", "all"],
            "description": "matching selects requested symbols; all selects every live item returned by the product."
          },
          "selector": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              }
            },
            "additionalProperties": false
          },
          "side": {
            "type": "string",
            "enum": ["long", "short"],
            "description": "Optional position/order side filter."
          },
          "timeout_ms": {
            "type": "number"
          },
          "state": {
            "type": "string",
            "enum": ["none", "absent", "closed", "open", "present"],
            "description": "Desired/expected selected collection state."
          }
        },
        "required": ["state"],
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.assert_positions",
          "state": "open",
          "market": "BTC",
          "intent": "Assert the expected Perps position state",
          "next": "done"
        }
      ],
      "execution_capabilities": []
    },
    "metamask.perps.assert_orders": {
      "description": "mobile Assert live Perps open orders are present or absent for an explicit market selection or mode=all.",
      "schema": {
        "type": "object",
        "properties": {
          "market": {
            "type": "string",
            "description": "Single market symbol, e.g. BTC or ETH. Alias: symbol."
          },
          "symbol": {
            "type": "string",
            "description": "Alias for market."
          },
          "markets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Explicit list of market symbols."
          },
          "symbols": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Alias for markets."
          },
          "mode": {
            "type": "string",
            "enum": ["matching", "all"],
            "description": "matching selects requested symbols; all selects every live item returned by the product."
          },
          "selector": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              }
            },
            "additionalProperties": false
          },
          "side": {
            "type": "string",
            "enum": ["long", "short"],
            "description": "Optional position/order side filter."
          },
          "timeout_ms": {
            "type": "number"
          },
          "state": {
            "type": "string",
            "enum": ["none", "absent", "closed", "open", "present"],
            "description": "Desired/expected selected collection state."
          }
        },
        "required": ["state"],
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.assert_orders",
          "state": "none",
          "market": "BTC",
          "intent": "Assert the expected Perps open order state",
          "next": "done"
        }
      ],
      "execution_capabilities": []
    },
    "metamask.perps.ensure_positions": {
      "description": "mobile Default to testnet for Perps mutations; mainnet is read-only unless explicitly requested. Higher-level wrapper that reads selected positions, closes or places when needed, then asserts final position state.",
      "schema": {
        "type": "object",
        "properties": {
          "market": {
            "type": "string",
            "description": "Single market symbol, e.g. BTC or ETH. Alias: symbol."
          },
          "symbol": {
            "type": "string",
            "description": "Alias for market."
          },
          "markets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Explicit list of market symbols."
          },
          "symbols": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Alias for markets."
          },
          "mode": {
            "type": "string",
            "enum": ["matching", "all"],
            "description": "matching selects requested symbols; all selects every live item returned by the product."
          },
          "selector": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              }
            },
            "additionalProperties": false
          },
          "side": {
            "type": "string",
            "enum": ["long", "short"],
            "description": "Required when state=open/present; otherwise filters selected positions."
          },
          "timeout_ms": {
            "type": "number"
          },
          "amount": {
            "type": ["string", "number"],
            "description": "Explicit USD notional used only when creating a missing open position. Alias: notional."
          },
          "notional": {
            "type": ["string", "number"],
            "description": "Alias for amount."
          },
          "state": {
            "type": "string",
            "enum": ["none", "absent", "closed", "open", "present"],
            "description": "Desired/expected selected collection state."
          }
        },
        "required": ["state"],
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.ensure_positions",
          "state": "none",
          "market": "BTC",
          "intent": "Converge Perps positions to the requested state",
          "next": "done"
        },
        {
          "action": "metamask.perps.ensure_positions",
          "state": "none",
          "mode": "all",
          "intent": "Converge Perps positions to the requested state",
          "next": "done"
        },
        {
          "action": "metamask.perps.ensure_positions",
          "market": "ETH",
          "side": "long",
          "state": "open",
          "notional": "10",
          "intent": "Converge ETH positions to one explicit testnet precondition",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation", "external-mutation"]
    },
    "metamask.perps.ensure_orders": {
      "description": "mobile Converge selected testnet orders to open or absent, then independently assert the final state. Creating an open state uses a resting limit order.",
      "schema": {
        "type": "object",
        "properties": {
          "market": {
            "type": "string",
            "description": "Single market symbol, e.g. BTC or ETH. Alias: symbol."
          },
          "symbol": {
            "type": "string",
            "description": "Alias for market."
          },
          "markets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Explicit list of market symbols."
          },
          "symbols": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Alias for markets."
          },
          "mode": {
            "type": "string",
            "enum": ["matching", "all"],
            "description": "matching selects requested symbols; all selects every live item returned by the product."
          },
          "selector": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              }
            },
            "additionalProperties": false
          },
          "side": {
            "type": "string",
            "enum": ["long", "short"],
            "description": "Required when state=open/present; otherwise filters selected orders."
          },
          "timeout_ms": {
            "type": "number"
          },
          "amount": {
            "type": ["string", "number"],
            "description": "Explicit USD notional used only when creating a missing open order. Alias: notional."
          },
          "notional": {
            "type": ["string", "number"],
            "description": "Alias for amount."
          },
          "leverage": {
            "type": "number",
            "default": 3,
            "description": "Testnet leverage used only when creating a missing open order."
          },
          "state": {
            "type": "string",
            "enum": ["none", "absent", "closed", "open", "present"],
            "description": "Desired/expected selected collection state."
          }
        },
        "required": ["state"],
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.ensure_orders",
          "state": "none",
          "mode": "all",
          "intent": "Converge Perps orders to the requested state",
          "next": "done"
        },
        {
          "action": "metamask.perps.ensure_orders",
          "market": "ETH",
          "side": "short",
          "state": "open",
          "notional": 10,
          "leverage": 2,
          "intent": "Converge ETH open orders to one deterministic testnet precondition",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation", "external-mutation"]
    },
    "metamask.perps.capture_performance": {
      "description": "Capture a bounded app-console window, summarize production [PerpsLoadProof]/WebSocket milestones, and optionally parse detailed [PerpsPerf]/[StartupPerf] records when a build emits them.",
      "schema": {
        "type": "object",
        "properties": {
          "phase": {
            "type": "string",
            "enum": ["start", "end"]
          },
          "source_path": {
            "type": "string"
          },
          "artifact_prefix": {
            "type": "string"
          },
          "wait_for_stage": {
            "type": "string",
            "description": "For phase=end, optionally poll until this detailed PerpsPerf stage exists before writing artifacts."
          },
          "wait_for_source": {
            "type": "string"
          },
          "wait_for_lifecycle": {
            "type": "string"
          },
          "wait_for_content_variant": {
            "type": "string"
          },
          "wait_timeout_ms": {
            "type": "number",
            "minimum": 1
          },
          "wait_poll_interval_ms": {
            "type": "number",
            "minimum": 10
          },
          "require_records": {
            "type": "boolean"
          },
          "required_stages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "required_startup_stages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "require_perps_bootstrap_start_before_demand": {
            "type": "boolean",
            "description": "Require the first Perps surface demand to occur after a captured PerpsLoadProof perps_bootstrap_start boundary."
          },
          "required_live_streams": {
            "type": "array",
            "description": "Require app-emitted [PerpsLoadProof] values_ready records from fresh_socket with one complete session, lifecycle, account, context, and connection-generation identity.",
            "items": {
              "type": "string",
              "enum": ["prices", "positions", "orders", "account"]
            }
          },
          "required_lifecycles": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "required_fresh_lifecycles": {
            "type": "array",
            "description": "Require a demand in each named lifecycle to reach a correlated fresh visible frame; prevents another lifecycle's socket records from satisfying the proof.",
            "items": {
              "type": "string"
            }
          },
          "required_sources": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "required_fresh_content_variants": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "require_cache_before_fresh": {
            "type": "boolean"
          },
          "first_fresh_delivery_requirements": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "stream": { "type": "string" },
                "lifecycle": { "type": "string" },
                "subscriber_throttle_ms": { "type": "number", "minimum": 0 },
                "max_socket_to_subscriber_ms": {
                  "type": "number",
                  "minimum": 0
                }
              },
              "required": [
                "stream",
                "subscriber_throttle_ms",
                "max_socket_to_subscriber_ms"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": ["phase"],
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.capture_performance",
          "phase": "start",
          "intent": "Start the Perps Homepage performance evidence window",
          "next": "exercise-flow"
        },
        {
          "action": "metamask.perps.capture_performance",
          "phase": "end",
          "require_records": true,
          "required_live_streams": ["positions", "orders", "account"],
          "intent": "Preserve production Perps loading and live-stream evidence emitted during this run",
          "next": "done"
        }
      ],
      "execution_capabilities": []
    },
    "metamask.perps.measure_homepage_visible": {
      "description": "Confirm the existing wallet is usable, then measure Wallet-ready to visible Perps content in one direct-CDP action so recipe-runner gaps are excluded.",
      "schema": {
        "type": "object",
        "properties": {
          "target_timeout_ms": { "type": "number", "minimum": 1 },
          "unlock_timeout_ms": { "type": "number", "minimum": 1 },
          "stable_unlocked_ms": { "type": "number", "minimum": 0 },
          "scroll_test_id": { "type": "string" },
          "from_test_id": { "type": "string" },
          "offset": { "type": "number" },
          "poll_interval_ms": { "type": "number", "minimum": 16 },
          "visible_event_stage": { "type": "string" },
          "visible_event_grace_ms": { "type": "number", "minimum": 0 },
          "animated": { "type": "boolean" },
          "target_test_id": { "type": "string" },
          "target_text": { "type": "string" },
          "required_present_test_id": { "type": "string" },
          "timeout_ms": { "type": "number", "minimum": 1 }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.measure_homepage_visible",
          "target_test_id": "homepage-section-title-perps",
          "required_present_test_id": "homepage-perps-positions",
          "intent": "Measure Wallet-ready to meaningful Perps content without runner timing",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.perps.prepare_local_snapshot_endpoint": {
      "description": "Prepare the configurable local Terminal snapshot endpoint for physical Android with adb reverse; iOS Simulator requires no mapping.",
      "schema": {
        "type": "object",
        "properties": {
          "port": { "type": "number", "minimum": 1 }
        },
        "required": ["port"],
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.prepare_local_snapshot_endpoint",
          "port": 3000,
          "intent": "Make the configured local Terminal snapshot endpoint reachable",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.perps.clear_performance_caches": {
      "description": "mobile Clear only persisted Perps market/user performance caches in the development app before a cold-no-cache validation run.",
      "schema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.clear_performance_caches",
          "intent": "Prepare a deterministic cold process start without Perps cache hydration",
          "next": "restart-app"
        }
      ],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.perps.ensure_mode": {
      "description": "Ensure the viewport-visible Perps market-detail root is Lite or Pro. The action presses the active mode control at most once and fails closed if that press opens another chooser or does not converge directly.",
      "schema": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "enum": ["lite", "pro"]
          },
          "timeout_ms": { "type": "integer", "minimum": 1000, "default": 30000 }
        },
        "required": ["mode"],
        "additionalProperties": false
      },
      "examples": [{
        "action": "metamask.perps.ensure_mode",
        "mode": "pro",
        "intent": "Reach Pro through the visible market-detail mode control",
        "next": "done"
      }],
      "execution_capabilities": ["app-mutation"]
    },
    "metamask.perps.start_state": {
      "description": "mobile Default to testnet for Perps mutations; mainnet is read-only unless explicitly requested. Recommended configurable Perps start state that first restores the fixture-backed unlocked wallet, then composes reusable domain operations before the proof window.",
      "schema": {
        "type": "object",
        "properties": {
          "profile": {
            "type": "string",
            "description": "Optional profile such as clean_market_testnet, open_position_testnet, open_order_testnet, or provider_mainnet_readonly."
          },
          "target_timeout_ms": {
            "type": "number",
            "minimum": 1,
            "description": "Bound for the pinned Mobile bridge target to become available before Perps state setup."
          },
          "unlock_timeout_ms": {
            "type": "number",
            "minimum": 1,
            "description": "Bound for the fixture-backed wallet unlock within Perps state setup."
          },
          "account": {
            "type": "string"
          },
          "provider": {
            "type": "string",
            "description": "Requested Perps provider, e.g. hyperliquid."
          },
          "network": {
            "type": "string",
            "enum": ["testnet", "mainnet"]
          },
          "market": {
            "type": "string"
          },
          "symbol": {
            "type": "string"
          },
          "markets": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "symbols": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "page": {
            "description": "Initial Perps page target; omit it to use the profile or market default, or set false without market/symbol to preserve the current route.",
            "type": ["string", "boolean"],
            "enum": [false, "home", "perps", "perps_home", "market", "market_details"]
          },
          "positions": {
            "type": ["object", "boolean"],
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              },
              "state": {
                "type": "string",
                "enum": ["none", "closed", "absent", "open", "present"]
              },
              "amount": {
                "type": ["string", "number"]
              },
              "notional": {
                "type": ["string", "number"]
              },
              "size": {
                "type": ["string", "number"]
              },
              "leverage": {
                "type": "number"
              },
              "order_type": {
                "type": "string"
              },
              "orderType": {
                "type": "string"
              },
              "limit_price": {
                "type": "number"
              },
              "limitPrice": {
                "type": "number"
              },
              "offset_pct": {
                "type": "number"
              },
              "offsetPct": {
                "type": "number"
              },
              "current_price": {
                "type": "number"
              },
              "currentPrice": {
                "type": "number"
              },
              "max_slippage_bps": {
                "type": "number"
              },
              "maxSlippageBps": {
                "type": "number"
              },
              "close_attempts": {
                "type": "integer"
              },
              "close_retry_delay_ms": {
                "type": "integer"
              },
              "timeout_ms": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "orders": {
            "type": ["object", "boolean"],
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              },
              "state": {
                "type": "string",
                "enum": ["none", "closed", "absent", "open", "present"]
              },
              "amount": {
                "type": ["string", "number"]
              },
              "notional": {
                "type": ["string", "number"]
              },
              "size": {
                "type": ["string", "number"]
              },
              "leverage": {
                "type": "number"
              },
              "order_type": {
                "type": "string"
              },
              "orderType": {
                "type": "string"
              },
              "limit_price": {
                "type": "number"
              },
              "limitPrice": {
                "type": "number"
              },
              "offset_pct": {
                "type": "number"
              },
              "offsetPct": {
                "type": "number"
              },
              "current_price": {
                "type": "number"
              },
              "currentPrice": {
                "type": "number"
              },
              "max_slippage_bps": {
                "type": "number"
              },
              "maxSlippageBps": {
                "type": "number"
              },
              "close_attempts": {
                "type": "integer"
              },
              "close_retry_delay_ms": {
                "type": "integer"
              },
              "timeout_ms": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "hud": {
            "type": "object",
            "properties": {},
            "additionalProperties": false
          },
          "timeout_ms": {
            "type": "number"
          },
          "side": {
            "type": "string",
            "enum": ["long", "short"]
          },
          "account_name": {
            "type": "string"
          },
          "readyToTrade": {
            "type": "boolean"
          },
          "balance": {
            "type": "object",
            "properties": {
              "minWithdrawableUsd": {
                "type": "number"
              },
              "minUsd": {
                "type": "number"
              },
              "minSpendableUsd": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "mode": {
            "type": "string",
            "enum": ["matching", "all"]
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.start_state",
          "profile": "clean_market_testnet",
          "market": "BTC",
          "positions": {
            "state": "none"
          },
          "orders": {
            "state": "none"
          },
          "intent": "Prepare the Perps start state for the proof",
          "network": "testnet",
          "next": "done"
        },
        {
          "action": "metamask.perps.start_state",
          "profile": "open_position_testnet",
          "market": "ETH",
          "side": "long",
          "positions": {
            "state": "open",
            "notional": "10",
            "leverage": 2
          },
          "intent": "Prepare the Perps start state for the proof",
          "network": "testnet",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation", "external-mutation"]
    },
    "metamask.perps.teardown_state": {
      "description": "mobile Recommended configurable Perps teardown state that restores the selected environment after proof.",
      "schema": {
        "type": "object",
        "properties": {
          "profile": {
            "type": "string",
            "description": "Optional profile such as clean_market_testnet, open_position_testnet, open_order_testnet, or provider_mainnet_readonly."
          },
          "account": {
            "type": "string"
          },
          "provider": {
            "type": "string",
            "description": "Requested Perps provider, e.g. hyperliquid."
          },
          "network": {
            "type": "string",
            "enum": ["testnet", "mainnet"]
          },
          "market": {
            "type": "string"
          },
          "symbol": {
            "type": "string"
          },
          "markets": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "symbols": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "page": {
            "description": "Final page target; false skips navigation for teardown.",
            "type": ["string", "boolean"],
            "enum": [
              "home",
              "perps",
              "perps_home",
              "market",
              "market_details",
              false
            ]
          },
          "positions": {
            "type": ["object", "boolean"],
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              },
              "state": {
                "type": "string",
                "enum": ["none", "closed", "absent", "open", "present"]
              },
              "amount": {
                "type": ["string", "number"]
              },
              "notional": {
                "type": ["string", "number"]
              },
              "size": {
                "type": ["string", "number"]
              },
              "leverage": {
                "type": "number"
              },
              "order_type": {
                "type": "string"
              },
              "orderType": {
                "type": "string"
              },
              "limit_price": {
                "type": "number"
              },
              "limitPrice": {
                "type": "number"
              },
              "offset_pct": {
                "type": "number"
              },
              "offsetPct": {
                "type": "number"
              },
              "current_price": {
                "type": "number"
              },
              "currentPrice": {
                "type": "number"
              },
              "max_slippage_bps": {
                "type": "number"
              },
              "maxSlippageBps": {
                "type": "number"
              },
              "close_attempts": {
                "type": "integer"
              },
              "close_retry_delay_ms": {
                "type": "integer"
              },
              "timeout_ms": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "orders": {
            "type": ["object", "boolean"],
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["matching", "all"]
              },
              "market": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              },
              "markets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "symbols": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "side": {
                "type": "string",
                "enum": ["long", "short"]
              },
              "state": {
                "type": "string",
                "enum": ["none", "closed", "absent", "open", "present"]
              },
              "amount": {
                "type": ["string", "number"]
              },
              "notional": {
                "type": ["string", "number"]
              },
              "size": {
                "type": ["string", "number"]
              },
              "leverage": {
                "type": "number"
              },
              "order_type": {
                "type": "string"
              },
              "orderType": {
                "type": "string"
              },
              "limit_price": {
                "type": "number"
              },
              "limitPrice": {
                "type": "number"
              },
              "offset_pct": {
                "type": "number"
              },
              "offsetPct": {
                "type": "number"
              },
              "current_price": {
                "type": "number"
              },
              "currentPrice": {
                "type": "number"
              },
              "max_slippage_bps": {
                "type": "number"
              },
              "maxSlippageBps": {
                "type": "number"
              },
              "close_attempts": {
                "type": "integer"
              },
              "close_retry_delay_ms": {
                "type": "integer"
              },
              "timeout_ms": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "hud": {
            "type": "object",
            "properties": {},
            "additionalProperties": false
          },
          "timeout_ms": {
            "type": "number"
          },
          "side": {
            "type": "string",
            "enum": ["long", "short"]
          },
          "account_name": {
            "type": "string"
          },
          "readyToTrade": {
            "type": "boolean"
          },
          "balance": {
            "type": "object",
            "properties": {
              "minWithdrawableUsd": {
                "type": "number"
              },
              "minUsd": {
                "type": "number"
              },
              "minSpendableUsd": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "mode": {
            "type": "string",
            "enum": ["matching", "all"]
          }
        },
        "additionalProperties": false
      },
      "examples": [
        {
          "action": "metamask.perps.teardown_state",
          "market": "BTC",
          "positions": {
            "state": "none"
          },
          "orders": {
            "state": "none"
          },
          "page": "home",
          "intent": "Restore Perps state after the proof",
          "next": "done"
        },
        {
          "action": "metamask.perps.teardown_state",
          "market": "BTC",
          "intent": "Restore Perps state after the proof",
          "next": "done"
        }
      ],
      "execution_capabilities": ["app-mutation", "external-mutation"]
    },
    "metamask.deeplink.open": {
      "description": "Open an HTTPS deeplink through the selected Android device or iOS simulator so Mobile owns parsing and destination navigation.",
      "execution_capabilities": ["app-mutation"],
      "examples": [
        {
          "action": "metamask.deeplink.open",
          "url": "https://link.metamask.io/home",
          "intent": "Open the deeplink through external device navigation",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "Absolute HTTPS deeplink URL."
          },
          "timeout_ms": {
            "type": "number",
            "description": "Maximum time for the external navigation. Default 15000."
          }
        },
        "required": ["url"],
        "additionalProperties": false
      }
    },
    "metamask.analytics.start_capture": {
      "description": "mobile Start capturing MetaMetrics events at the Segment transport and return a cursor to bracket later reads.",
      "execution_capabilities": ["arbitrary-code"],
      "examples": [
        {
          "action": "metamask.analytics.start_capture",
          "intent": "Begin capturing analytics before driving the flow",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "port": {
            "type": "integer",
            "description": "Collector port. Defaults to cdp_port + 1000, else 9090. The client build must point its Segment host here (extension SEGMENT_HOST, mobile SEGMENT_PROXY_URL)."
          },
          "cdp_port": {
            "type": "integer"
          }
        },
        "additionalProperties": false
      }
    },
    "metamask.analytics.read_events": {
      "description": "mobile Read MetaMetrics events captured since a cursor, as [{ event, properties, ts }].",
      "execution_capabilities": ["host-read-export"],
      "examples": [
        {
          "action": "metamask.analytics.read_events",
          "since": 0,
          "intent": "Inspect which analytics events the flow emitted",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "since": {
            "type": "number",
            "description": "Cursor (epoch ms) from start_capture. Omit to read everything captured."
          },
          "event": {
            "type": "string",
            "description": "Optional exact event-name filter."
          }
        },
        "additionalProperties": false
      }
    },
    "metamask.analytics.assert_events": {
      "description": "mobile Assert MetaMetrics event names, property values and counts. Counts are the point: an exact count catches a double emit that a presence check cannot.",
      "execution_capabilities": ["host-read-export"],
      "examples": [
        {
          "action": "metamask.analytics.assert_events",
          "expect": [
            {
              "event": "Perp Order Cancel Transaction",
              "count": 1
            }
          ],
          "intent": "Assert the cancel event was emitted exactly once",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "since": {
            "type": "number",
            "description": "Cursor from start_capture; brackets the assertion to this flow."
          },
          "exact": {
            "type": "boolean",
            "description": "When true, any captured event not named in expect is a failure."
          },
          "timeout_ms": {
            "type": "number",
            "description": "How long to wait for the lower bounds to be met. Default 15000."
          },
          "settle_ms": {
            "type": "number",
            "description": "Extra wait after the bounds are met, before judging. Default 1500. Required to catch a duplicate that arrives after the expected event."
          },
          "expect": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "event": {
                  "type": "string",
                  "description": "Exact event name."
                },
                "count": {
                  "type": "integer",
                  "description": "Exact number of matching events. Mutually exclusive with min/max."
                },
                "min": {
                  "type": "integer",
                  "description": "Lower bound on matching events. Default 1."
                },
                "max": {
                  "type": "integer",
                  "description": "Upper bound on matching events."
                },
                "properties": {
                  "type": "object",
                  "description": "Subset match on event properties; values may be exact or use $exists, $type, and $gt predicates."
                }
              },
              "required": ["event"],
              "additionalProperties": false
            }
          }
        },
        "required": ["expect"],
        "additionalProperties": false
      }
    },
    "metamask.analytics.set_consent": {
      "description": "mobile Set MetaMetrics consent flags through the Security & Privacy controls so events reach the Segment transport.",
      "execution_capabilities": ["app-mutation"],
      "examples": [
        {
          "action": "metamask.analytics.set_consent",
          "intent": "Opt in before capturing analytics",
          "next": "done"
        }
      ],
      "schema": {
        "type": "object",
        "properties": {
          "participate": {
            "type": "boolean",
            "description": "MetaMetrics optedIn state. Default true."
          },
          "marketing": {
            "type": "boolean",
            "description": "dataCollectionForMarketing. Default true. Required for utm_* properties to survive."
          },
          "timeout_ms": {
            "type": "number",
            "description": "Maximum time to navigate to Settings, apply each consent toggle, and read back state. Default 15000."
          }
        },
        "additionalProperties": false
      }
    }
  },
  "observers": [
    {
      "ref": "ui.screen",
      "default_for": [
        "metamask.deeplink.open",
        "ui.navigate",
        "ui.press",
        "ui.swipe",
        "ui.pan",
        "ui.drag",
        "ui.long_press",
        "ui.screenshot",
        "ui.capture_surface",
        "ui.scroll",
        "ui.set_input",
        "ui.wait_for"
      ]
    },
    {
      "ref": "ui.visible",
      "default_for": [
        "metamask.deeplink.open",
        "ui.navigate",
        "ui.press",
        "ui.swipe",
        "ui.pan",
        "ui.drag",
        "ui.long_press",
        "ui.screenshot",
        "ui.capture_surface",
        "ui.scroll",
        "ui.set_input",
        "ui.wait_for"
      ]
    }
  ]
}
