diff --git a/urc_msgs/CMakeLists.txt b/urc_msgs/CMakeLists.txt
index b072d6e6..32e5fbd6 100644
--- a/urc_msgs/CMakeLists.txt
+++ b/urc_msgs/CMakeLists.txt
@@ -14,12 +14,14 @@ find_package(nav_msgs REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/BatteryInfo.msg"
+ "msg/DetectionBoundingBox.msg"
"msg/StatusLightCommand.msg"
"msg/Waypoint.msg"
"msg/GridLocation.msg"
"msg/OrientationPoses.msg"
"srv/GeneratePlan.srv"
"msg/RoverPoses.msg"
+ "action/ExecuteAutonomousMission.action"
"action/NavigateToWaypoint.action"
DEPENDENCIES
diff --git a/urc_msgs/README.md b/urc_msgs/README.md
index 7b5ad6e0..7c8082da 100644
--- a/urc_msgs/README.md
+++ b/urc_msgs/README.md
@@ -8,6 +8,7 @@ contains no runtime nodes.
| Interface | Purpose |
| --- | --- |
| `BatteryInfo` | Battery voltage, charge, current, temperature, and per-cell telemetry |
+| `DetectionBoundingBox` | Timestamped YOLO detection, confidence, image size, and pixel bounds |
| `GridLocation` | Unsigned grid-cell coordinates |
| `OrientationPoses` | Header and named pose collection |
| `RoverPoses` | Header and named rover-pose collection |
@@ -19,13 +20,56 @@ contains no runtime nodes.
| Interface | Purpose |
| --- | --- |
| `GeneratePlan` service | Requests a path between start and goal poses and returns a `nav_msgs/Path` with a success or failure code |
+| `ExecuteAutonomousMission` action | Navigates to a waypoint and optionally performs a YOLO or ArUco search while retaining mission context across replans |
| `NavigateToWaypoint` action | Follows a supplied path or plans to a goal, with optional final-heading enforcement and progress feedback |
+## Autonomous mission contract
+
+`ExecuteAutonomousMission` is the mission-level interface consumed by the
+navigation coordinator. Its `search_mode` has these behaviors:
+
+| Search mode | Behavior after reaching the initial waypoint |
+| --- | --- |
+| `SEARCH_NONE` | Complete without starting a search |
+| `SEARCH_YOLO` | Spiral-search until the requested object is detected, then return its bounding box |
+| `SEARCH_ARUCO_1` | Search for ArUco 1 using its 5-10 m detection profile, then navigate to a safe goal within 2 m of the marker |
+| `SEARCH_ARUCO_2` | Search for ArUco 2 using its 10-20 m detection profile, then navigate to a safe goal within 2 m of the marker |
+
+Requests supply a `waypoint`; an omitted/default `search_mode` is
+`SEARCH_NONE` (0), preserving ordinary A* navigation without search. A blank
+search selection means NONE, not a blank waypoint or a string value. The
+coordinator must reject unsupported modes before starting navigation; a rejected
+ROS action goal has no result. Runtime enforcement is part of ROB-42.
+
+Feedback reports the mission state, distance to the current navigation goal in
+meters, and that navigation leg's replan count. A successful result uses
+`SUCCESS`: NONE has no detection payload, YOLO returns `bounding_box`, and ArUco
+returns `aruco_pose` after the approach succeeds. Read each payload only when its
+`has_*` flag is true; pose frames and timestamps come from their headers.
+
+Accepted missions return one terminal result. Failures use `INVALID_REQUEST`
+for invalid request data found after acceptance, `NAVIGATION_FAILED` for initial
+navigation failure, `SEARCH_FAILED` for search errors, `TARGET_NOT_FOUND` for a
+search ending without a target, or `APPROACH_FAILED` for ArUco approach failure.
+Cancellation uses `CANCELED`; `message` provides diagnostic detail.
+
+The coordinator owns the mission action and retains its waypoint and search mode
+for the action's entire lifetime. `NavigateToWaypoint` owns each individual
+navigation leg and may call `GeneratePlan` repeatedly when it needs to replan.
+Neither `NavigateToWaypoint` nor `GeneratePlan` interprets the mission search
+mode.
+
+An ArUco approach is a second internal `NavigateToWaypoint` goal within the
+original mission. It does not create another mission or start another spiral
+search.
+
The definitions under `msg/`, `srv/`, and `action/` are authoritative for field
types, constants, and result codes. Inspect an installed interface with:
```bash
ros2 interface show urc_msgs/action/NavigateToWaypoint
+ros2 interface show urc_msgs/action/ExecuteAutonomousMission
+ros2 interface show urc_msgs/msg/DetectionBoundingBox
```
Changes to these files affect every producer and consumer. Rebuild the workspace
diff --git a/urc_msgs/action/ExecuteAutonomousMission.action b/urc_msgs/action/ExecuteAutonomousMission.action
new file mode 100644
index 00000000..42b06a93
--- /dev/null
+++ b/urc_msgs/action/ExecuteAutonomousMission.action
@@ -0,0 +1,38 @@
+# Goal
+# The search mode belongs to the complete mission and must persist across
+# navigation replans.
+uint8 SEARCH_NONE=0
+uint8 SEARCH_YOLO=1
+uint8 SEARCH_ARUCO_1=2
+uint8 SEARCH_ARUCO_2=3
+
+geometry_msgs/PoseStamped waypoint
+uint8 search_mode
+---
+# Result
+uint16 SUCCESS=0
+uint16 INVALID_REQUEST=1
+uint16 NAVIGATION_FAILED=2
+uint16 SEARCH_FAILED=3
+uint16 TARGET_NOT_FOUND=4
+uint16 APPROACH_FAILED=5
+uint16 CANCELED=6
+
+uint16 error_code
+string message
+
+bool has_bounding_box
+urc_msgs/DetectionBoundingBox bounding_box
+
+bool has_aruco_pose
+geometry_msgs/PoseStamped aruco_pose
+---
+# Feedback
+uint8 STATE_NAVIGATING=0
+uint8 STATE_SEARCHING=1
+uint8 STATE_PLANNING_APPROACH=2
+uint8 STATE_APPROACHING=3
+
+uint8 mission_state
+float32 distance_to_goal
+uint16 replan_count
diff --git a/urc_msgs/msg/DetectionBoundingBox.msg b/urc_msgs/msg/DetectionBoundingBox.msg
new file mode 100644
index 00000000..6398e07a
--- /dev/null
+++ b/urc_msgs/msg/DetectionBoundingBox.msg
@@ -0,0 +1,13 @@
+# Image-space detection returned by an autonomous perception mission.
+std_msgs/Header header
+
+string class_name
+float32 confidence
+
+uint32 image_width
+uint32 image_height
+
+uint32 x_min
+uint32 y_min
+uint32 x_max
+uint32 y_max
diff --git a/urc_msgs/package.xml b/urc_msgs/package.xml
index b4953b5e..a3cadb82 100644
--- a/urc_msgs/package.xml
+++ b/urc_msgs/package.xml
@@ -17,6 +17,7 @@
std_msgs
builtin_interfaces
geometry_msgs
+ nav_msgs
ament_lint_auto
ament_lint_common
@@ -26,4 +27,4 @@
ament_cmake
-
\ No newline at end of file
+