# Unfragile — robots.md

> The same tool search, from a ROS 2 node or a companion computer.
> Plain HTTP, compact JSON, no keys. Every result labelled. Robot work here is early and says so.

Generated: 2026-11-01T09:47:41.454Z
Human page: https://unfragile.ai/robots

## 1. One call over HTTP

Leave `answer=1` off inside a control loop: the search answers from our GPU in well under a second; the language-model answer adds seconds.

```sh
curl "https://unfragile.ai/api/v1/find?q=arm+the+drone+and+take+off+to+10+metres&k=5"
```

Each result: `name`, `action`, `description`, `tier` (verified | official | checked | found-in-code | demo | failed), `label`, `verification_score`, `url` (signed passport for verified records, null otherwise).

## 2. From a ROS 2 node

```python
# ROS 2 (rclpy) — example node: asks Unfragile which action does a task and
# publishes the top result's name. Adapt the topic and the task to your stack.
import json, urllib.parse, urllib.request
import rclpy
from rclpy.node import Node
from std_msgs.msg import String

class FindAction(Node):
    def __init__(self):
        super().__init__("unfragile_find")
        self.pub = self.create_publisher(String, "unfragile/top_action", 10)
        task = "move the arm to its home position"
        q = urllib.parse.quote(task)
        # k=5, no answer layer: the box answers in well under a second; the
        # language-model answer adds seconds and belongs outside control loops.
        with urllib.request.urlopen(f"https://unfragile.ai/api/v1/find?q={q}&k=5", timeout=5) as r:
            data = json.load(r)
        for row in data["results"]:
            self.get_logger().info(f'{row["label"]:32} {row["name"]} · {row["action"]}')
        top = data["results"][0] if data["results"] else None
        if top and top["tier"] in ("verified", "official"):
            self.pub.publish(String(data=f'{top["name"]}:{top["action"]}'))
        else:
            self.get_logger().warn("no verified action; not publishing")

def main():
    rclpy.init(); n = FindAction(); rclpy.spin_once(n, timeout_sec=0.1); n.destroy_node(); rclpy.shutdown()
```

## 3. Verify before you load a new package

```python
# Companion computer (any Python) — before loading a new MAVLink or ROS package,
# ask for its verdict. Never load a flagged one.
import json, urllib.request
req = urllib.request.Request(
    "https://unfragile.ai/api/v1/verify",
    data=json.dumps({"target": "pypi:pymavlink"}).encode(),
    headers={"Content-Type": "application/json"},
)
v = json.load(urllib.request.urlopen(req, timeout=5))
print(v["verdict"], "-", v["reason"])        # trusted | caution | unverified | flagged
assert v["verdict"] != "flagged"
```

## 4. The rules for robots

1. Only act on `verified` or `official`. A result found in code, not yet checked, exists in source but has not answered our checks; read it before it touches a motor.
2. Never load a `failed` or `flagged` package.
3. Time-bound every call. On 503 the service is down and nothing is guessed. Do not block a loop on us.
4. An empty result is an answer. Fall back to your own defaults; do not improvise a command.

## 5. Still being built for robots

- A ROS 2 client package, so the call above is a service, not a snippet.
- A latency budget published per endpoint, measured, not promised.
- The neutral router, so a robot's question can reach sources beyond this index.

## Links

- API reference: https://unfragile.ai/docs
- For agents: https://unfragile.ai/agents · https://unfragile.ai/agents.md
- How we check: https://unfragile.ai/how
- Live index numbers: https://unfragile.ai/api/v1/stats
