changedInput schema / properties / count / description
Previous value: -"Maximum number of recent messages to return. Defaults to 5; silently clamped to 50 (the hard cap that keeps tool output bounded; read it from `health_check.max_sample_count`). Negative values raise an error. The returned `SampleResult.count` reflects the actual number of samples produced: it can be lower than the request (empty topic, timeout, mock fixture shorter than requested)."New value: +"Messages to return, default 5, at most 50 (`health_check.max_sample_count`): more is capped to 50, negative raises an error. The result's `count` may be lower."
removedInput schema / properties / count / title
Removed value: -"Count"
changedInput schema / properties / topic / description
Previous value: -"DDS topic name. Bare DDS names such as `scan` are valid, as are ROS 2 mangled names such as `rt/scan` and the builtin discovery topics `DCPSParticipant`, `DCPSSubscription`, `DCPSPublication`. Letters, digits, `_`, `/` and `::` are allowed; anything else is rejected."New value: +"DDS topic name: bare (`scan`), ROS 2 mangled (`rt/scan`) or a builtin discovery topic (`DCPSParticipant`, `DCPSSubscription`, `DCPSPublication`). Letters, digits, `_`, `/` and `::` only."
removedInput schema / properties / topic / title
Removed value: -"Topic"
removedInput schema / title
Removed value: -"peek_dds_samplesArguments"
addedOutput schema / $defs / ImageSummary
Added value: +{
+ "additionalProperties": false,
+ "properties": {
+ "data_length": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Pixel buffer size in bytes (see `data_length_basis`)."
+ },
+ "data_length_basis": {
+ "anyOf": [
+ {
+ "enum": [
+ "payload",
+ "step_x_height"
+ ],
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "`payload` (counted) or `step_x_height` (array cut, so step times height)."
+ },
+ "encoding": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Pixel encoding, e.g. `rgb8`."
+ },
+ "frame_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "`header.frame_id` of the camera."
+ },
+ "height": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Pixels."
+ },
+ "is_bigendian": {
+ "anyOf": [
+ {
+ "type": "boolean"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Big-endian pixels."
+ },
+ "note": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "One sentence when partial; else `null`."
+ },
+ "step": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Row length, bytes."
+ },
+ "summary_type": {
+ "const": "image",
+ "type": "string"
+ },
+ "width": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Pixels."
+ }
+ },
+ "required": [
+ "summary_type",
+ "frame_id",
+ "width",
+ "height",
+ "encoding",
+ "step",
+ "is_bigendian",
+ "data_length",
+ "data_length_basis"
+ ],
+ "type": "object"
+}
addedOutput schema / $defs / ImuSummary
Added value: +{
+ "additionalProperties": false,
+ "properties": {
+ "angular_velocity_norm": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Norm of `angular_velocity`, rad/s."
+ },
+ "frame_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "`header.frame_id` of the IMU."
+ },
+ "linear_acceleration_norm": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Norm of `linear_acceleration`, m/s^2."
+ },
+ "note": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "One sentence when a value is unusable; else `null`."
+ },
+ "orientation_valid": {
+ "description": "False when the IMU gives no orientation: `roll`, `pitch`, `yaw` are `null`.",
+ "type": "boolean"
+ },
+ "pitch": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Rotation about y, radians."
+ },
+ "roll": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Rotation about x, radians."
+ },
+ "summary_type": {
+ "const": "imu",
+ "type": "string"
+ },
+ "yaw": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Rotation about z, radians."
+ }
+ },
+ "required": [
+ "summary_type",
+ "frame_id",
+ "orientation_valid",
+ "roll",
+ "pitch",
+ "yaw",
+ "angular_velocity_norm",
+ "linear_acceleration_norm"
+ ],
+ "type": "object"
+}
addedOutput schema / $defs / LaserScanSummary
Added value: +{
+ "additionalProperties": false,
+ "properties": {
+ "angle_increment": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Angle between beams, rad."
+ },
+ "angle_max": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Bearing of the last beam, rad."
+ },
+ "angle_min": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Bearing of beam 0, rad."
+ },
+ "beam_count": {
+ "description": "Beams in `ranges`.",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "closest_obstacle": {
+ "anyOf": [
+ {
+ "$ref": "#/$defs/ScanReturn"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Closest valid return of the scan; `null` with `note`."
+ },
+ "finite_count": {
+ "description": "Beams with a finite range.",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "frame_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "`header.frame_id`; every angle is in this sensor frame, not the base frame."
+ },
+ "inf_count": {
+ "description": "Beams at `+inf`.",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "nan_count": {
+ "description": "Beams at `nan`.",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "neg_inf_count": {
+ "description": "Beams at `-inf`.",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "note": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "One sentence when the summary is partial; else `null`."
+ },
+ "out_of_range_count": {
+ "description": "Finite ranges outside `range_min`..`range_max` (not valid).",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "range_max": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Largest valid range, m."
+ },
+ "range_min": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Smallest valid range, m."
+ },
+ "sectors": {
+ "$ref": "#/$defs/ScanSectors",
+ "description": "Closest valid return per sector."
+ },
+ "summary_type": {
+ "const": "laser_scan",
+ "type": "string"
+ }
+ },
+ "required": [
+ "summary_type",
+ "frame_id",
+ "beam_count",
+ "angle_min",
+ "angle_max",
+ "angle_increment",
+ "range_min",
+ "range_max",
+ "finite_count",
+ "inf_count",
+ "neg_inf_count",
+ "nan_count",
+ "out_of_range_count",
+ "closest_obstacle",
+ "sectors"
+ ],
+ "type": "object"
+}
removedOutput schema / $defs / MessageSample / description
Removed value: -"A single sampled message on a topic."
removedOutput schema / $defs / MessageSample / properties / message_type / description
Removed value: -"ROS2 message type of this sample, e.g. `geometry_msgs/msg/Twist`."
removedOutput schema / $defs / MessageSample / properties / message_type / title
Removed value: -"Message Type"
changedOutput schema / $defs / MessageSample / properties / payload / description
Previous value: -"Message fields as nested named values, e.g. `{\"header\": {\"stamp\": {\"sec\": 12, \"nanosec\": 5}, \"frame_id\": \"base_laser\"}, \"ranges\": [1.0, 1.001]}`. Non-finite floats are the strings `nan`, `inf`, `-inf`. Live `sample_messages` adds `_truncated_fields` (dotted paths of arrays, strings or bytes cut at `max_array_length`; a string of exactly that length plus `...` that was not cut is listed too) when something was cut, and `_raw_text` (the unparsed output) only when a message could not be parsed. With `arrays_summary_only` an array is a string like `<sequence type: float, length: 541>`. Large messages may be dropped to keep tool output bounded."New value: +"Message fields as nested values; `nan`/`inf` are strings. Live `sample_messages` adds `_truncated_fields` (cut paths) and `_raw_text` (unparsable output)."
removedOutput schema / $defs / MessageSample / properties / payload / title
Removed value: -"Payload"
changedOutput schema / $defs / MessageSample / properties / received_ns / description
Previous value: -"Wall-clock nanoseconds since epoch at which the `ros2` CLI printed this message, after it deserialized and formatted it: not the network receive time, and it lags more for large messages. Accurate to a fraction of a second. Live `sample_messages` only; `None` otherwise."New value: +"Wall-clock ns when the `ros2` CLI printed the message (live `sample_messages` only)."
removedOutput schema / $defs / MessageSample / properties / received_ns / title
Removed value: -"Received Ns"
changedOutput schema / $defs / MessageSample / properties / recorded_ns / description
Previous value: -"Nanoseconds at which the recorder wrote this message into the bag (the bag's own record time, wall clock unless the recorder ran on simulated time). `peek_bag_samples` only; `None` for live samples, where `received_ns` plays that role."New value: +"Bag record time in ns (`peek_bag_samples` only)."
removedOutput schema / $defs / MessageSample / properties / recorded_ns / title
Removed value: -"Recorded Ns"
removedOutput schema / $defs / MessageSample / properties / stamp_source / anyOf
Removed value: -[
- {
- "enum": [
- "header",
- "none",
- "recorded"
- ],
- "type": "string"
- },
- {
- "type": "null"
- }
-]
removedOutput schema / $defs / MessageSample / properties / stamp_source / default
Removed value: -null
changedOutput schema / $defs / MessageSample / properties / stamp_source / description
Previous value: -"Where `timestamp_ns` comes from: `header` (the message's `header.stamp`), `none` (headerless live message, `timestamp_ns` is 0) or `recorded` (headerless message from a bag, `timestamp_ns` is the bag record time). `None` when the backend does not say."New value: +"Origin of `timestamp_ns`: `header`, `payload`, `recorded` (bag record time), `dds_source` or `none` (0)."
addedOutput schema / $defs / MessageSample / properties / stamp_source / enum
Added value: +[
+ "header",
+ "payload",
+ "recorded",
+ "dds_source",
+ "none"
+]
removedOutput schema / $defs / MessageSample / properties / stamp_source / title
Removed value: -"Stamp Source"
addedOutput schema / $defs / MessageSample / properties / stamp_source / type
Added value: +"string"
addedOutput schema / $defs / MessageSample / properties / summary
Added value: +{
+ "anyOf": [
+ {
+ "discriminator": {
+ "mapping": {
+ "image": "#/$defs/ImageSummary",
+ "imu": "#/$defs/ImuSummary",
+ "laser_scan": "#/$defs/LaserScanSummary",
+ "odometry": "#/$defs/OdometrySummary",
+ "point_cloud2": "#/$defs/PointCloud2Summary"
+ },
+ "propertyName": "summary_type"
+ },
+ "oneOf": [
+ {
+ "$ref": "#/$defs/LaserScanSummary"
+ },
+ {
+ "$ref": "#/$defs/OdometrySummary"
+ },
+ {
+ "$ref": "#/$defs/ImuSummary"
+ },
+ {
+ "$ref": "#/$defs/ImageSummary"
+ },
+ {
+ "$ref": "#/$defs/PointCloud2Summary"
+ }
+ ]
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Condensed reading of the whole message (see `summary_type`); `null` for other types and DDS peeks."
+}
changedOutput schema / $defs / MessageSample / properties / timestamp_ns / description
Previous value: -"Nanoseconds from the message's own top-level `header.stamp` (`stamp_source` `header`), or 0 when the message has no header (`stamp_source` `none`, e.g. `std_msgs/String`, `geometry_msgs/Twist`). It is the publisher's clock, not the arrival time: on simulated time it is sim time since the simulation started (a few seconds, not a date) and 0 is a valid value. From `peek_bag_samples` a message without a header gets the bag record time instead (`stamp_source` `recorded`), also given in `recorded_ns`. Use `received_ns` for when the CLI printed the message. Mock samples with a header carry synthetic increasing values."New value: +"Publisher-clock ns: `header.stamp`, else the time in the body of `Clock`, `TFMessage` or `Log`, else 0 (see `stamp_source`); not the arrival time."
removedOutput schema / $defs / MessageSample / properties / timestamp_ns / title
Removed value: -"Timestamp Ns"
removedOutput schema / $defs / MessageSample / properties / topic / description
Removed value: -"Fully qualified topic name the sample was taken from, e.g. `/cmd_vel`."
removedOutput schema / $defs / MessageSample / properties / topic / title
Removed value: -"Topic"
changedOutput schema / $defs / MessageSample / required
Previous value: -[
- "topic",
- "message_type",
- "timestamp_ns"
-]New value: +[
+ "topic",
+ "message_type",
+ "timestamp_ns",
+ "stamp_source"
+]
removedOutput schema / $defs / MessageSample / title
Removed value: -"MessageSample"
addedOutput schema / $defs / OdometrySummary
Added value: +{
+ "additionalProperties": false,
+ "properties": {
+ "angular_z": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "`twist.twist.angular.z`, rad/s."
+ },
+ "child_frame_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "`child_frame_id` (frame of the twist)."
+ },
+ "frame_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "`header.frame_id` (frame of the pose)."
+ },
+ "linear_speed": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Norm of `twist.twist.linear`, m/s."
+ },
+ "note": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "One sentence when a value is missing; else `null`."
+ },
+ "position_x": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "`pose.pose.position.x`, m."
+ },
+ "position_y": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "`pose.pose.position.y`, m."
+ },
+ "position_z": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "`pose.pose.position.z`, m."
+ },
+ "summary_type": {
+ "const": "odometry",
+ "type": "string"
+ },
+ "yaw": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Heading from the pose quaternion, radians."
+ }
+ },
+ "required": [
+ "summary_type",
+ "frame_id",
+ "child_frame_id",
+ "linear_speed",
+ "angular_z",
+ "position_x",
+ "position_y",
+ "position_z",
+ "yaw"
+ ],
+ "type": "object"
+}
addedOutput schema / $defs / PointCloud2Summary
Added value: +{
+ "additionalProperties": false,
+ "properties": {
+ "fields": {
+ "description": "Point layout.",
+ "items": {
+ "$ref": "#/$defs/PointFieldSummary"
+ },
+ "type": "array"
+ },
+ "frame_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "`header.frame_id` of the cloud."
+ },
+ "height": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Rows (1: unorganized)."
+ },
+ "is_dense": {
+ "anyOf": [
+ {
+ "type": "boolean"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "True when no point is invalid."
+ },
+ "note": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "One sentence when partial; else `null`."
+ },
+ "point_count": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "`width` times `height`."
+ },
+ "point_step": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Bytes per point."
+ },
+ "row_step": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Bytes per row."
+ },
+ "summary_type": {
+ "const": "point_cloud2",
+ "type": "string"
+ },
+ "width": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Points per row."
+ }
+ },
+ "required": [
+ "summary_type",
+ "frame_id",
+ "width",
+ "height",
+ "point_count",
+ "point_step",
+ "row_step",
+ "is_dense",
+ "fields"
+ ],
+ "type": "object"
+}
addedOutput schema / $defs / PointFieldSummary
Added value: +{
+ "additionalProperties": false,
+ "properties": {
+ "count": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Elements per point."
+ },
+ "datatype": {
+ "description": "Element type, e.g. `FLOAT32`.",
+ "type": "string"
+ },
+ "name": {
+ "description": "Field name, e.g. `x`.",
+ "type": "string"
+ },
+ "offset": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Byte offset in a point."
+ }
+ },
+ "required": [
+ "name",
+ "datatype",
+ "offset",
+ "count"
+ ],
+ "type": "object"
+}
addedOutput schema / $defs / ScanReturn
Added value: +{
+ "additionalProperties": false,
+ "properties": {
+ "beam_index": {
+ "description": "Index in `ranges`.",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "bearing": {
+ "description": "Beam direction in radians, sensor frame: 0 is +x, counter-clockwise positive.",
+ "type": "number"
+ },
+ "range": {
+ "description": "Distance, meters.",
+ "type": "number"
+ }
+ },
+ "required": [
+ "range",
+ "bearing",
+ "beam_index"
+ ],
+ "type": "object"
+}
addedOutput schema / $defs / ScanSector
Added value: +{
+ "additionalProperties": false,
+ "properties": {
+ "beam_count": {
+ "description": "Beams inside the sector (0: not covered).",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "closest": {
+ "anyOf": [
+ {
+ "$ref": "#/$defs/ScanReturn"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Closest valid return in the sector; `null` with `note`."
+ },
+ "note": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Why `closest` is `null`; `null` when it is set."
+ }
+ },
+ "required": [
+ "beam_count",
+ "closest"
+ ],
+ "type": "object"
+}
addedOutput schema / $defs / ScanSectors
Added value: +{
+ "additionalProperties": false,
+ "properties": {
+ "front": {
+ "$ref": "#/$defs/ScanSector",
+ "description": "Bearings within +-45 degrees of +x."
+ },
+ "left": {
+ "$ref": "#/$defs/ScanSector",
+ "description": "Bearings from 45 to 135 degrees."
+ },
+ "rear": {
+ "$ref": "#/$defs/ScanSector",
+ "description": "Bearings beyond +-135 degrees."
+ },
+ "right": {
+ "$ref": "#/$defs/ScanSector",
+ "description": "Bearings from -135 to -45 degrees."
+ }
+ },
+ "required": [
+ "front",
+ "left",
+ "right",
+ "rear"
+ ],
+ "type": "object"
+}
addedOutput schema / $defs / TopicRate
Added value: +{
+ "additionalProperties": false,
+ "properties": {
+ "basis": {
+ "description": "Clock the rate is measured on: `received_ns` (live) or `recorded_ns` (bag).",
+ "enum": [
+ "received_ns",
+ "recorded_ns"
+ ],
+ "type": "string"
+ },
+ "interval_cv": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Interval standard deviation over mean; `null` under 2 messages."
+ },
+ "interval_median_s": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Median interval; `null` under 2 messages."
+ },
+ "max_gap_s": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Longest interval; `null` under 2 messages."
+ },
+ "mean_interval_s": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Mean interval; `null` under 2 messages."
+ },
+ "message_count": {
+ "description": "Messages the rate is computed from.",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "observed_frequency_hz": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Messages per second on `basis`, drain excluded; the rate the caller received. `null` under 2 messages."
+ },
+ "sim_frequency_hz": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Same rate on the messages' own stamps (publisher clock); `null` without advancing stamps."
+ },
+ "startup_burst_count": {
+ "description": "Leading messages set aside as a start-up drain (live only); still in `message_count`.",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "trailing_gap_s": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "Time from the last message to the end of a live observation; else `null`."
+ },
+ "verdict": {
+ "description": "First match: `silent` (none), `insufficient` (under 5), `intermittent` (an interval over 3x the median), `stable` (cv < 0.2), `jittery` (< 0.5), `erratic`. Describes this window, not a diagnosis.",
+ "enum": [
+ "silent",
+ "insufficient",
+ "intermittent",
+ "stable",
+ "jittery",
+ "erratic"
+ ],
+ "type": "string"
+ },
+ "verdict_note": {
+ "description": "The verdict in plain words.",
+ "type": "string"
+ },
+ "window_s": {
+ "description": "Observation length, seconds.",
+ "minimum": 0,
+ "type": "number"
+ }
+ },
+ "required": [
+ "basis",
+ "message_count",
+ "startup_burst_count",
+ "window_s",
+ "mean_interval_s",
+ "interval_median_s",
+ "max_gap_s",
+ "interval_cv",
+ "observed_frequency_hz",
+ "sim_frequency_hz",
+ "trailing_gap_s",
+ "verdict",
+ "verdict_note"
+ ],
+ "type": "object"
+}
changedOutput schema / description
Previous value: -"Envelope returned by the `sample_messages` tool."New value: +"Samples returned by `sample_messages`, `peek_dds_samples` and `peek_bag_samples`."
changedOutput schema / properties / count / description
Previous value: -"Number of samples actually returned. May be 0 (no publisher active in live mode, or empty mock fixture), less than the requested count (topic yielded fewer messages within the timeout), or capped by the the silent maximum of 50: request `count > 50` and you will receive at most 50 without warning."New value: +"Number of samples in `samples`: fewer than requested when the topic gave fewer, never more than 50 (a larger request is capped to 50)."
removedOutput schema / properties / count / title
Removed value: -"Count"
changedOutput schema / properties / mode_effective / description
Previous value: -"Runtime mode the adapter served this response in: `live` (real ROS2 introspection) or `mock` (deterministic fixtures). Lets a caller tell a real graph from a demo one without calling `health_check`."New value: +"`live` or `mock` (fixtures)."
removedOutput schema / properties / mode_effective / title
Removed value: -"Mode Effective"
changedOutput schema / properties / note / description
Previous value: -"Why `samples` is empty or limited, when the cause is not obvious (for example payload decoding is disabled for DDS user topics). `None` when there is nothing to add."New value: +"Why `samples` is empty or limited, when not obvious; else `None`."
removedOutput schema / properties / note / title
Removed value: -"Note"
addedOutput schema / properties / rate
Added value: +{
+ "anyOf": [
+ {
+ "$ref": "#/$defs/TopicRate"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "How the topic delivered the messages, with a verdict; `null` for `peek_dds_samples`. Use `count` >= 10."
+}
changedOutput schema / properties / samples / description
Previous value: -"The sampled messages, ordered as received from the backend."New value: +"The samples, in backend order."
removedOutput schema / properties / samples / title
Removed value: -"Samples"
removedOutput schema / properties / topic / description
Removed value: -"Topic the samples were taken from, echoed from the request."
removedOutput schema / properties / topic / title
Removed value: -"Topic"