changedInput schema / properties / path / description
Previous value: -"Path to a bag: a file ending in `.mcap` or `.db3`, or a `rosbag2_*` directory. `peek_bag_samples` also reads ROS 1 `.bag` files; `analyze_bag` does not (`ros2 bag info` cannot open them). Leading/trailing whitespace is stripped. Null bytes and otherwise malformed filesystem paths are rejected. Existence and bag format are validated by the live adapter (mock mode accepts any well-formed path)."New value: +"Bag path: a `.mcap` or `.db3` file or a `rosbag2_*` directory (`peek_bag_samples` also reads ROS 1 `.bag`; `analyze_bag` does not). Existence and format are checked live; mock accepts any well-formed path."
removedInput schema / properties / path / title
Removed value: -"Path"
removedInput schema / title
Removed value: -"analyze_bagArguments"
removedOutput schema / $defs / BagTopicStats / description
Removed value: -"Per-topic statistics inside a bag analysis result."
changedOutput schema / $defs / BagTopicStats / properties / first_timestamp_ns / description
Previous value: -"Recorded time of the first message on this topic, in nanoseconds (bag receive time, normally epoch). `null` when the bag was summarized from `ros2 bag info` text only, or the topic has no messages."New value: +"Recorded ns of the first message; `null` for text-only summaries or no messages."
removedOutput schema / $defs / BagTopicStats / properties / first_timestamp_ns / title
Removed value: -"First Timestamp Ns"
changedOutput schema / $defs / BagTopicStats / properties / frequency_basis / description
Previous value: -"How `frequency_hz` was computed: `topic_span` (per-topic first and last message times, the accurate one) or `bag_duration` (count divided by whole-bag duration, used when per-topic times could not be read). `null` when there is no rate."New value: +"`topic_span` (accurate) or `bag_duration` (count over the whole bag, understates late topics); `null` without a rate."
removedOutput schema / $defs / BagTopicStats / properties / frequency_basis / title
Removed value: -"Frequency Basis"
changedOutput schema / $defs / BagTopicStats / properties / frequency_hz / description
Previous value: -"Average publish rate in Hz. With `frequency_basis` `topic_span` it is `(message_count - 1) / (last - first message time)` for this topic; with `bag_duration` it is `message_count / bag duration`, which understates the rate of a topic that started late or stopped early. `null` when fewer than 2 messages, a zero time span, or the topic is `latched` and all its messages fall within 1 second (a start-up burst, not a rate). A latched topic published over a longer span keeps its rate. Not a periodic rate for event-driven topics such as `/parameter_events`."New value: +"Average Hz: (count - 1) over the topic's own time span (see `frequency_basis`); `null` under 2 messages, a zero span, or a latched start-up burst (all within 1 s)."
removedOutput schema / $defs / BagTopicStats / properties / frequency_hz / title
Removed value: -"Frequency Hz"
addedOutput schema / $defs / BagTopicStats / properties / kind
Added value: +{
+ "default": "user",
+ "description": "`user` (data, incl. `/tf` and `/clock`), `rosbag2_internal` or `ros_builtin` (e.g. `/rosout`).",
+ "enum": [
+ "user",
+ "rosbag2_internal",
+ "ros_builtin"
+ ],
+ "type": "string"
+}
changedOutput schema / $defs / BagTopicStats / properties / last_timestamp_ns / description
Previous value: -"Recorded time of the last message on this topic; same rules as `first_timestamp_ns`."New value: +"Recorded ns of the last message; same rules."
removedOutput schema / $defs / BagTopicStats / properties / last_timestamp_ns / title
Removed value: -"Last Timestamp Ns"
changedOutput schema / $defs / BagTopicStats / properties / latched / description
Previous value: -"True when a publisher recorded this topic with transient_local durability (late joiners get the last samples, e.g. `/tf_static`, `/rosout`). Such a topic often publishes a start-up burst; when all its messages fall within 1 second `frequency_hz` is `null`. `false` when every recorded publisher was volatile; `null` when the bag carries no QoS information (ROS 1 bags report their latching flag)."New value: +"True if recorded with transient_local durability, false if volatile, `null` without QoS information."
removedOutput schema / $defs / BagTopicStats / properties / latched / title
Removed value: -"Latched"
removedOutput schema / $defs / BagTopicStats / properties / message_count / title
Removed value: -"Message Count"
removedOutput schema / $defs / BagTopicStats / properties / message_type / description
Removed value: -"ROS2 message type recorded for this topic."
removedOutput schema / $defs / BagTopicStats / properties / message_type / title
Removed value: -"Message Type"
removedOutput schema / $defs / BagTopicStats / properties / name / description
Removed value: -"Fully qualified topic name as recorded in the bag."
removedOutput schema / $defs / BagTopicStats / properties / name / title
Removed value: -"Name"
removedOutput schema / $defs / BagTopicStats / title
Removed value: -"BagTopicStats"
removedOutput schema / $defs / ParticipantInfo
Removed value: -{
- "additionalProperties": false,
- "description": "DDS participant discovered on the configured domain.\n\nCarries identity (`guid`, `name`, `vendor`) plus lifecycle fields\n(`first_seen_ns`, `last_seen_ns`, `status`, `seen_count`).",
- "properties": {
- "announced_ns": {
- "anyOf": [
- {
- "minimum": 0,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Nanoseconds since epoch (DDS source timestamp of the participant's most recent announcement, taken from the announcing side's clock; the local clock when the announcer sent none). `None` when the backend does not expose it. Distinct from `first_seen_ns` / `last_seen_ns`, which are TopicForge's own local clock.",
- "title": "Announced Ns"
- },
- "domain_id": {
- "description": "DDS domain id the participant is bound to.",
- "maximum": 232,
- "minimum": 0,
- "title": "Domain Id",
- "type": "integer"
- },
- "first_seen_ns": {
- "anyOf": [
- {
- "minimum": 0,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Wall-clock timestamp (nanoseconds since epoch) of the **first** discovery sample TopicForge observed for this participant. `None` when the adapter does not track lifecycle.",
- "title": "First Seen Ns"
- },
- "guid": {
- "description": "DDS Global Unique Identifier of the participant: hex string, stable across discovery events within a single deployment.",
- "title": "Guid",
- "type": "string"
- },
- "hostname": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Hostname announced in discovery (Cyclone `__Hostname` property). `None` when the vendor does not announce it.",
- "title": "Hostname"
- },
- "is_observer": {
- "default": false,
- "description": "True for TopicForge's own read-only observer participant, which joins the domain to watch it and appears in this list; false for every other participant.",
- "title": "Is Observer",
- "type": "boolean"
- },
- "last_seen_ns": {
- "anyOf": [
- {
- "minimum": 0,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Wall-clock timestamp (nanoseconds since epoch) of the **most recent** discovery sample observed. Used by `participant_events` to distinguish currently-active participants from those that left the bus. `None` when the adapter does not track lifecycle.",
- "title": "Last Seen Ns"
- },
- "lost_ns": {
- "anyOf": [
- {
- "minimum": 0,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Nanoseconds since epoch of the moment the participant left, once `status` is `left`; `None` while it is active. How precise it is depends on `lost_time_source`. It is an upper bound of when the participant died: after a clean shutdown it is the exact leave time, after a crash it is when the lease expired, and the two cannot be told apart. The process died at or before `lost_ns`, and at most one lease earlier (10 s Cyclone default, 20 s Fast, 100 s RTI).",
- "title": "Lost Ns"
- },
- "lost_time_source": {
- "anyOf": [
- {
- "enum": [
- "dds_source_timestamp",
- "observed_local"
- ],
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Where `lost_ns` comes from: `dds_source_timestamp` (timestamp carried by the discovery dispose) or `observed_local` (the moment TopicForge noticed, the weakest). `None` while active.",
- "title": "Lost Time Source"
- },
- "mode_effective": {
- "description": "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`.",
- "enum": [
- "mock",
- "live"
- ],
- "title": "Mode Effective",
- "type": "string"
- },
- "name": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Participant name the application announced through the standard DDS EntityName QoS (PID_ENTITY_NAME in RTPS discovery), for example `lidar_driver`. `None` when the application did not set one (Dust DDS cannot) or the backend does not expose it.",
- "title": "Name"
- },
- "seen_count": {
- "default": 1,
- "description": "Number of distinct discovery samples observed for this participant across all calls to `list_participants` during this server's lifetime. Starts at 1 and increments on each observation.",
- "minimum": 1,
- "title": "Seen Count",
- "type": "integer"
- },
- "status": {
- "default": "unknown",
- "description": "Lifecycle status. `active` means TopicForge has a recent discovery sample for this GUID and the bus has not signalled removal. `left` means the participant was observed earlier but has since disappeared (a Fast DDS `REMOVED` callback or a Cyclone polling delta). `unknown` when the adapter does not track lifecycle.",
- "enum": [
- "active",
- "left",
- "unknown"
- ],
- "title": "Status",
- "type": "string"
- },
- "vendor": {
- "description": "DDS implementation that announced this participant, decoded from the OMG-RTPS `vendor_id` field on the discovery sample. `cyclone` (Eclipse Cyclone DDS), `fast` (eProsima Fast DDS), `rti` (RTI Connext), `rti_micro` (RTI Connext Micro), `opensplice` (ADLink OpenSplice), `opendds` (OCI OpenDDS), `coredx` (Twin Oaks CoreDX), `intercom` (Kongsberg InterCOM), `dust` (S2E Dust DDS). `mock` is reserved for synthetic fixtures. `unknown` means the vendor could not be determined: TopicForge reads it from the vendor prefix of the participant GUID, and some vendors (for example Dust DDS and RTI Connext) do not put their vendor id there, while the Cyclone Python binding does not expose the RTPS header vendor id. The participant is still reported; see `vendor_source`. Any conformant DDS-RTPS participant should appear through standard discovery; Cyclone DDS and Dust DDS have been observed on a live bus. See `docs/dds-interop-matrix.md`.",
- "enum": [
- "cyclone",
- "fast",
- "rti",
- "rti_micro",
- "opensplice",
- "opendds",
- "coredx",
- "intercom",
- "dust",
- "mock",
- "unknown"
- ],
- "title": "Vendor",
- "type": "string"
- },
- "vendor_source": {
- "default": "none",
- "description": "Where `vendor` came from: `guid_prefix` when it was read from the vendor prefix of the participant GUID, `none` when the vendor is unknown (or synthetic in mock mode).",
- "enum": [
- "guid_prefix",
- "none"
- ],
- "title": "Vendor Source",
- "type": "string"
- }
- },
- "required": [
- "guid",
- "vendor",
- "domain_id",
- "mode_effective"
- ],
- "title": "ParticipantInfo",
- "type": "object"
-}
changedOutput schema / description
Previous value: -"Structured summary of a ROS2 bag.\n\nThe fields `bag_format`, `samples_decoded_count`,\n`recording_duration_ns` and `participants_recorded` are populated only\nwhen the `rosbags`-backed reader runs; the `ros2 bag info` path leaves\nthem at their defaults."New value: +"Structured summary of a ROS2 bag."
changedOutput schema / properties / anomalies / description
Previous value: -"Human-readable notes about gaps, clock jumps, or other oddities. Populated in mock mode only; live mode does not detect anomalies."New value: +"Notes on gaps or clock jumps; mock mode only."
removedOutput schema / properties / anomalies / title
Removed value: -"Anomalies"
changedOutput schema / properties / bag_format / description
Previous value: -"Concrete bag container format detected by the reader: `mcap` (Foxglove MCAP), `db3` (ROS2 rosbag2 SQLite), `bag` (ROS1 legacy chunked), or `unknown` when the reader could not classify. `None` when the bag was summarized from `ros2 bag info` text, which carries no format information."New value: +"Detected container: `mcap`, `db3`, `bag` or `unknown`; `None` for `ros2 bag info` text."
removedOutput schema / properties / bag_format / title
Removed value: -"Bag Format"
addedOutput schema / properties / duration_s
Added value: +{
+ "description": "Bag duration in seconds.",
+ "minimum": 0,
+ "type": "number"
+}
removedOutput schema / properties / duration_seconds
Removed value: -{
- "description": "Total bag duration, in seconds (wall clock between first and last message).",
- "minimum": 0,
- "title": "Duration Seconds",
- "type": "number"
-}
removedOutput schema / properties / message_count / title
Removed value: -"Message 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 the result is less detailed than usual, for example per-topic rates computed over the whole bag duration because the bag was too large to read per-topic message times. `None` when there is nothing to add."New value: +"Why the result is less detailed than usual (e.g. rates over the whole bag duration); else `None`."
removedOutput schema / properties / note / title
Removed value: -"Note"
removedOutput schema / properties / participants_recorded
Removed value: -{
- "description": "DDS participants recorded in the bag when the container format embeds participant metadata. MCAP can carry it via channel metadata records; ROS2 `.db3` and ROS1 `.bag` generally do not. Empty list when not available, which is the common case.",
- "items": {
- "$ref": "#/$defs/ParticipantInfo"
- },
- "title": "Participants Recorded",
- "type": "array"
-}
changedOutput schema / properties / path / description
Previous value: -"Path to the analyzed bag, as supplied by the caller. May point to a file (`.mcap`, `.db3`, or ROS 1 `.bag` for `peek_bag_samples`) or to a `rosbag2_*` directory."New value: +"Bag path as supplied."
removedOutput schema / properties / path / title
Removed value: -"Path"
removedOutput schema / properties / recording_duration_ns
Removed value: -{
- "anyOf": [
- {
- "minimum": 0,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "default": null,
- "description": "Recording duration in nanoseconds when readable from the bag's index. `None` when only `ros2 bag info` text was parsed; `duration_seconds` (float) is the always-populated fallback that downstream LLM consumers should prefer when this is `None`.",
- "title": "Recording Duration Ns"
-}
removedOutput schema / properties / samples_decoded_count
Removed value: -{
- "default": 0,
- "description": "Total decoded sample count across all topics produced by the bag reader. `0` when the reader only parsed metadata or when `rosbags` is not installed on the host. Use `peek_bag_samples` to pull the actual sample payloads for a specific topic.",
- "minimum": 0,
- "title": "Samples Decoded Count",
- "type": "integer"
-}
removedOutput schema / properties / storage_format / title
Removed value: -"Storage Format"
removedOutput schema / properties / topics / title
Removed value: -"Topics"
changedOutput schema / required
Previous value: -[
- "path",
- "duration_seconds",
- "message_count",
- "topics",
- "mode_effective"
-]New value: +[
+ "path",
+ "duration_s",
+ "message_count",
+ "topics",
+ "mode_effective"
+]