topicforge 0.4.0__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {topicforge-0.4.0 → topicforge-0.5.0}/.gitignore +6 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/CHANGELOG.md +163 -2
- {topicforge-0.4.0 → topicforge-0.5.0}/PKG-INFO +24 -21
- {topicforge-0.4.0 → topicforge-0.5.0}/README.md +22 -20
- {topicforge-0.4.0 → topicforge-0.5.0}/docs/DDS_QUICKSTART.md +30 -21
- topicforge-0.5.0/docs/MIGRATION_v0.3_to_v0.4.md +242 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/docs/TESTING.md +12 -3
- topicforge-0.5.0/docs/TROUBLESHOOTING.md +245 -0
- topicforge-0.5.0/examples/README.md +30 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/pyproject.toml +2 -1
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/__init__.py +1 -1
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/common/dds_helpers.py +15 -5
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/dds_cyclone/adapter.py +13 -3
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/dds_fast/adapter.py +9 -2
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/services/bag_service.py +10 -3
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/services/inspector.py +6 -5
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_bag_service.py +41 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_dds_helpers.py +22 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/LICENSE +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/docs/MIGRATION_v0.1_to_v0.2.md +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/docs/MIGRATION_v0.2_to_v0.3.md +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/docs/dds-interop-matrix.md +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/docs/pro.md +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/docs/product-plan.md +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/scripts/integration/README.md +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/__main__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/base.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/common/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/common/cdr_decoder.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/common/lifecycle.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/common/metrics_buffer.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/common/qos_analyzer.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/common/xtypes.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/composite.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/dds_cyclone/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/dds_dust/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/dds_dust/adapter.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/dds_fast/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/dds_opendds/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/dds_opendds/adapter.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/ros2_live/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/ros2_live/adapter.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/ros2_mock/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/ros2_mock/adapter.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/adapters/ros2_mock/fixtures.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/config/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/config/settings.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/models/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/models/schemas.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/server/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/server/app.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/services/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/services/constants.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/services/factory.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/services/health.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/telemetry/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/telemetry/client.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/tools/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/src/topicforge/tools/handlers.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/conftest.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/fixtures/csv_echo_imu.txt +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/fixtures/csv_echo_pose_multi.txt +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/integration/__init__.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/integration/conftest.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/integration/scenarios/lifecycle_tracking.json +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/integration/scenarios/multi_vendor_basic.json +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/integration/scenarios/qos_mismatch_detection.json +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/integration/scenarios/topic_metrics_frequency.json +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/integration/scenarios/topic_metrics_sequence_gaps.json +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/integration/scenarios/xtypes_decode.json +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/integration/test_real_bus.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/integration/test_scenarios_schema.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_analyze_bag_multi_format.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_cdr_decoder.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_composite_adapter.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_config.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_cyclone_adapter.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_dds_cross_vendor.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_dds_schemas.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_dust_adapter.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_factory.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_fast_adapter.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_health.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_inspector.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_lifecycle_buffer.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_live_adapter_parse.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_live_adapter_subprocess.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_metrics_buffer.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_mock_adapter.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_opendds_adapter.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_peek_bag_samples.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_pro_hook.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_qos_analyzer.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_telemetry.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_tools_integration.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_topic_metrics.py +0 -0
- {topicforge-0.4.0 → topicforge-0.5.0}/tests/test_xtypes.py +0 -0
|
@@ -217,6 +217,12 @@ CLAUDE*.md
|
|
|
217
217
|
# remain reproducible. Tracked, not part of sdist.
|
|
218
218
|
!/docs/projet-file/references/
|
|
219
219
|
!/docs/projet-file/references/**
|
|
220
|
+
# Archive of superseded strategic artifacts (old audit reports, dated
|
|
221
|
+
# launch-post drafts). Kept in git so the historical context survives
|
|
222
|
+
# but tucked away so the active `projet-file/` folder stays focused on
|
|
223
|
+
# what is currently load-bearing.
|
|
224
|
+
!/docs/projet-file/archive/
|
|
225
|
+
!/docs/projet-file/archive/**
|
|
220
226
|
/docs/assets/screencast-raw/
|
|
221
227
|
|
|
222
228
|
|
|
@@ -5,7 +5,166 @@ All notable changes to TopicForge are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.5.0] - 2026-05-21
|
|
11
|
+
|
|
12
|
+
### Sprint v0.5.0 — Polish + validation (pre-marketing-publication)
|
|
13
|
+
|
|
14
|
+
> Branch `feat/v0.5.0-polish-and-validation`. Three sub-milestones
|
|
15
|
+
> (5.1 real validation, 5.2 audit closure + error polish, 5.3 docs +
|
|
16
|
+
> examples + repo polish). No new MCP tool, no schema change. Last
|
|
17
|
+
> sprint before marketing publication ; the next version bump is
|
|
18
|
+
> the maintainer's manual `release` commit + tag.
|
|
19
|
+
|
|
20
|
+
#### Changed (sub-milestone 5.1 — Real validation)
|
|
21
|
+
|
|
22
|
+
- **CI matrix expanded** (`.github/workflows/ci.yml`) from
|
|
23
|
+
`ubuntu-latest × {3.11, 3.12}` to `{ubuntu-latest, windows-latest} ×
|
|
24
|
+
{3.11, 3.12, 3.13}` (6 cells, `fail-fast: false`). Windows-latest
|
|
25
|
+
coverage closes the largest unverified surface — TopicForge's primary
|
|
26
|
+
dev environment is Windows per `CLAUDE.md §7` and was previously only
|
|
27
|
+
hand-validated. Python 3.13 added now that wheels are stable across
|
|
28
|
+
the dependency footprint.
|
|
29
|
+
- **`pyproject.toml` classifiers** widened with `Programming Language ::
|
|
30
|
+
Python :: 3.13`.
|
|
31
|
+
|
|
32
|
+
#### Changed (sub-milestone 5.2 — AdapterError polish)
|
|
33
|
+
|
|
34
|
+
- **`DDS_ONLY_ERROR_MSG`** (`adapters/common/dds_helpers.py`) rewritten
|
|
35
|
+
with the v0.4.0 `CompositeAdapter` remediation path explicit, and
|
|
36
|
+
with every affected ROS2 tool name listed inline. Substring
|
|
37
|
+
`"DDS observability only"`, `"TOPICFORGE_DDS_BACKEND"`,
|
|
38
|
+
`"TOPICFORGE_MODE"` preserved — existing `pytest.raises(match=...)`
|
|
39
|
+
contracts honored. New token assertions added :
|
|
40
|
+
`"CompositeAdapter"`, the 4 affected tool names.
|
|
41
|
+
- **CycloneDDS adapter errors** (`adapters/dds_cyclone/adapter.py`)
|
|
42
|
+
enriched with the underlying exception type, the active domain id,
|
|
43
|
+
the topic name (where relevant), and common-cause diagnostic hints
|
|
44
|
+
(`CYCLONEDDS_URI` misconfiguration, multicast firewall, domain
|
|
45
|
+
mismatch). Three sites : participant discovery, endpoint discovery,
|
|
46
|
+
sample peek.
|
|
47
|
+
- **Fast DDS participant-init error** (`adapters/dds_fast/adapter.py`)
|
|
48
|
+
enriched with an ABI-mismatch diagnostic — Fast DDS 2.6.x Python
|
|
49
|
+
binding wheels frequently desynchronize with system-installed Fast
|
|
50
|
+
DDS native libraries, and the v0.4.0 wording masked the cause behind
|
|
51
|
+
a bare `"returned None"`. New message points at the pyproject pin
|
|
52
|
+
(`fastdds>=2.6.1,<3`) and the `FastDDS_DEFAULT_PROFILES_FILE` env
|
|
53
|
+
var as the two likely culprits.
|
|
54
|
+
- **`BagService` IO errors** (`services/bag_service.py`) wrap the
|
|
55
|
+
rosbags-side exception class name into the AdapterError message so
|
|
56
|
+
the LLM caller can pivot on `PermissionError` / `IsADirectoryError`
|
|
57
|
+
/ etc. without inspecting `__cause__`.
|
|
58
|
+
- **`_ROSBAGS_REQUIRED_MSG`** rewording — clarifies that `analyze_bag`
|
|
59
|
+
has a v0.3.0 text-parse fallback while `peek_bag_samples` does not.
|
|
60
|
+
|
|
61
|
+
#### Closed (sub-milestone 5.2 — audit triage)
|
|
62
|
+
|
|
63
|
+
- **`docs/projet-file/audit-followup-triage-v0.2.0.md` refreshed**
|
|
64
|
+
against the current tree (was last touched pre-v0.3.0). Strict
|
|
65
|
+
B-class : 3 items now CLOSED (B6 in v0.2.0, B9 in v0.3.0, B10 in
|
|
66
|
+
v0.5.0). 6 items remain DEFER (B1-B5 hosted-context security
|
|
67
|
+
hardening ; B7, B8 wire-contract decisions for v0.6+).
|
|
68
|
+
- **`TODO(roadmap, audit-2026-05-14)` at `services/inspector.py:76`
|
|
69
|
+
retired as WONT-FIX-by-design** — the `list_topics` Inspector gate
|
|
70
|
+
is intentionally empty (no MCP-level args to validate). The comment
|
|
71
|
+
block is now a permanent design note rather than a roadmap pointer.
|
|
72
|
+
|
|
73
|
+
#### Added (sub-milestone 5.2 — regression tests)
|
|
74
|
+
|
|
75
|
+
- **5 new tests** in `tests/test_dds_helpers.py` and
|
|
76
|
+
`tests/test_bag_service.py` (regex-token assertions, not exact
|
|
77
|
+
wording) — pin the polished message contract without locking the
|
|
78
|
+
exact prose. Baseline grows from 394 to 399 passed ; 24 skipped
|
|
79
|
+
unchanged ; ruff clean.
|
|
80
|
+
|
|
81
|
+
#### Changed (sub-milestone 5.3 — Documentation cascade)
|
|
82
|
+
|
|
83
|
+
- **`README.md`** — CI badge added ; tagline refreshed from "v0.3.0"
|
|
84
|
+
to "v0.4.0" framing emphasising observability + bag analysis ; the
|
|
85
|
+
3-row DDS tool mini-table grew into a 6-row table listing every
|
|
86
|
+
DDS / observability tool with its sub-milestone of origin ;
|
|
87
|
+
`peek_dds_samples` scope rewritten around `_decode_status` (full /
|
|
88
|
+
partial / raw) ; telemetry contract field description switched from
|
|
89
|
+
"five MVP tools" to "eleven MCP tools" ; `TOPICFORGE_DDS_BACKEND`
|
|
90
|
+
Literal values listed in the config reference ; Roadmap section
|
|
91
|
+
pruned of items that shipped in v0.4.0 (Composite adapter, XTypes
|
|
92
|
+
Cyclone push).
|
|
93
|
+
- **`docs/DDS_QUICKSTART.md`** — header bumped to v0.4.0+ ; §4
|
|
94
|
+
"Single-adapter limitation (v0.3.0)" replaced by "Composite adapter
|
|
95
|
+
(v0.4.0 Phase 1+)" with the new routing table ; §5 documents the
|
|
96
|
+
v0.4.0 Phase 1.5 best-effort XTypes story (no more
|
|
97
|
+
`AdapterError` on user topics) ; §6 "What's next" pruned of shipped
|
|
98
|
+
items ; §7 Troubleshooting updated.
|
|
99
|
+
- **`docs/TESTING.md`** — "five MCP tools" → "eleven MCP tools" in the
|
|
100
|
+
three documented occurrences ("Pick your path" table row, the lead
|
|
101
|
+
paragraph, Path 1 header). New v0.4.0 tool-surface callout above
|
|
102
|
+
the path picker.
|
|
103
|
+
|
|
104
|
+
#### Added (sub-milestone 5.3 — new docs and examples)
|
|
105
|
+
|
|
106
|
+
- **`docs/MIGRATION_v0.3_to_v0.4.md`** (new, sibling to the existing
|
|
107
|
+
`MIGRATION_v0.2_to_v0.3.md`). 8 sections : new tools, env vars and
|
|
108
|
+
extras, soft-breaking schema widening (`ParticipantInfo` +4 fields,
|
|
109
|
+
`BagAnalysis` +4 fields, `HealthReport.ros_backend`, `dds_backend`
|
|
110
|
+
widening, `AdapterName` widening, new `TopicMetrics` /
|
|
111
|
+
`ParticipantEvent` schemas), `CompositeAdapter`, `peek_dds_samples`
|
|
112
|
+
user-topic story, protocol expansions, plus a quick checklist.
|
|
113
|
+
- **`docs/TROUBLESHOOTING.md`** (new). One section per polished
|
|
114
|
+
AdapterError message, plus the cross-cutting "ROS2 CLI not found on
|
|
115
|
+
PATH" / `auto` fallback to mock case. Each section quotes the
|
|
116
|
+
message and lists the diagnostics in order.
|
|
117
|
+
- **`examples/`** (new). 4 mock-mode-runnable walkthroughs covering
|
|
118
|
+
the headline value props :
|
|
119
|
+
- `01-discover-ros2-stack.md` — `health_check` + `list_topics` +
|
|
120
|
+
`get_topic_info` + `sample_messages`
|
|
121
|
+
- `02-debug-qos-mismatch.md` — `list_participants` +
|
|
122
|
+
`detect_qos_mismatches` + `peek_dds_samples` (canonical
|
|
123
|
+
Reliability mismatch story)
|
|
124
|
+
- `03-analyze-recording.md` — `analyze_bag` + `peek_bag_samples`
|
|
125
|
+
post-mortem inspection
|
|
126
|
+
- `04-monitor-topic-frequency.md` — `topic_metrics` +
|
|
127
|
+
`participant_events` with the opportunistic-fill caveat
|
|
128
|
+
Each example pairs an MCP-client prompt with the expected tool
|
|
129
|
+
calls and a short LLM-facing synthesis.
|
|
130
|
+
|
|
131
|
+
#### Added (sub-milestone 5.3 — repo polish)
|
|
132
|
+
|
|
133
|
+
- **`CONTRIBUTING.md`** (new). What contributions land easily vs hard,
|
|
134
|
+
development setup, the `make check` contract, mock-first
|
|
135
|
+
development convention, layer separation, pure-parser convention,
|
|
136
|
+
commit conventions.
|
|
137
|
+
- **`SECURITY.md`** (new). Local-trust threat model, the
|
|
138
|
+
read-only-by-architecture stance, vulnerability disclosure email,
|
|
139
|
+
response SLAs, supported version policy.
|
|
140
|
+
- **`.github/ISSUE_TEMPLATE/bug_report.yml`** (new) — structured form
|
|
141
|
+
with version, mode, OS, Python, repro, env vars, troubleshooting
|
|
142
|
+
check.
|
|
143
|
+
- **`.github/ISSUE_TEMPLATE/feature_request.yml`** (new) —
|
|
144
|
+
problem-first framing, tier disambiguation (OSS / Pro), explicit
|
|
145
|
+
read-only-by-architecture acknowledgment.
|
|
146
|
+
- **`.github/ISSUE_TEMPLATE/config.yml`** (new) — disables blank
|
|
147
|
+
issues, links to `SECURITY.md`, `docs/TROUBLESHOOTING.md`,
|
|
148
|
+
`docs/DDS_QUICKSTART.md`.
|
|
149
|
+
- **`.github/PULL_REQUEST_TEMPLATE.md`** (new) — summary, test plan,
|
|
150
|
+
backward-compatibility checklist (covers the 11-tool cap, schema
|
|
151
|
+
additive-only invariant, telemetry 6-field contract, env var docs,
|
|
152
|
+
public API removal flag).
|
|
153
|
+
|
|
154
|
+
#### Notes
|
|
155
|
+
|
|
156
|
+
- **Backward compat preserved.** Zero schema changes, zero new tools,
|
|
157
|
+
zero env-var renames. The `DDS_ONLY_ERROR_MSG` substring tokens
|
|
158
|
+
pinned by existing tests (`"DDS observability only"`,
|
|
159
|
+
`"TOPICFORGE_DDS_BACKEND"`, `"TOPICFORGE_MODE"`) are preserved
|
|
160
|
+
intact ; v0.4.0 producers and clients keep working byte-for-byte.
|
|
161
|
+
- **CHANGELOG entry deferred to release time.** This branch leaves
|
|
162
|
+
`pyproject.toml` at `0.4.0`, `__version__` at `"0.4.0"`, and the
|
|
163
|
+
`## [Unreleased]` heading populated with the polish notes above.
|
|
164
|
+
The version bump and `v0.5.0` tag are the maintainer's manual
|
|
165
|
+
steps after final review.
|
|
166
|
+
|
|
167
|
+
## [0.4.0] - 2026-05-15
|
|
9
168
|
|
|
10
169
|
### Sprint v0.4.0 — Phase 3 (bag analysis multi-format)
|
|
11
170
|
|
|
@@ -554,7 +713,9 @@ Initial MVP release of TopicForge — ROS Topic Inspector & Bag Analyzer MCP ser
|
|
|
554
713
|
- The write path (publishing, commanding robots) is intentionally out of scope for the MVP.
|
|
555
714
|
- `analyze_bag` in live mode parses `ros2 bag info` text output; deeper anomaly detection remains mock-only for now.
|
|
556
715
|
|
|
557
|
-
[Unreleased]: https://github.com/yaniswav/TopicForge/compare/v0.
|
|
716
|
+
[Unreleased]: https://github.com/yaniswav/TopicForge/compare/v0.5.0...HEAD
|
|
717
|
+
[0.5.0]: https://github.com/yaniswav/TopicForge/compare/v0.4.0...v0.5.0
|
|
718
|
+
[0.4.0]: https://github.com/yaniswav/TopicForge/compare/v0.3.0...v0.4.0
|
|
558
719
|
[0.3.0]: https://github.com/yaniswav/TopicForge/compare/v0.2.0...v0.3.0
|
|
559
720
|
[0.2.0]: https://github.com/yaniswav/TopicForge/compare/v0.1.2...v0.2.0
|
|
560
721
|
[0.1.2]: https://github.com/yaniswav/TopicForge/compare/v0.1.1...v0.1.2
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: topicforge
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: ROS Topic Inspector & Bag Analyzer MCP server for AI agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/yaniswav/TopicForge
|
|
6
6
|
Project-URL: Repository, https://github.com/yaniswav/TopicForge
|
|
@@ -37,6 +37,7 @@ Classifier: Operating System :: OS Independent
|
|
|
37
37
|
Classifier: Programming Language :: Python :: 3
|
|
38
38
|
Classifier: Programming Language :: Python :: 3.11
|
|
39
39
|
Classifier: Programming Language :: Python :: 3.12
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
40
41
|
Requires-Python: >=3.11
|
|
41
42
|
Requires-Dist: mcp>=1.0.0
|
|
42
43
|
Requires-Dist: pydantic>=2.6
|
|
@@ -69,11 +70,12 @@ Description-Content-Type: text/markdown
|
|
|
69
70
|
# TopicForge
|
|
70
71
|
|
|
71
72
|
[](https://pypi.org/project/topicforge/)
|
|
73
|
+
[](https://github.com/yaniswav/TopicForge/actions/workflows/ci.yml)
|
|
72
74
|
[](https://pypi.org/project/topicforge/)
|
|
73
75
|
[](https://github.com/yaniswav/TopicForge/blob/main/LICENSE)
|
|
74
76
|
[](https://github.com/yaniswav/TopicForge#security-model)
|
|
75
77
|
|
|
76
|
-
> **The safety-first read-only MCP for ROS2 robotics —
|
|
78
|
+
> **The safety-first read-only MCP for ROS2 robotics — observability + multi-vendor OMG DDS-RTPS (v0.4.0).** TopicForge lets AI agents inspect your ROS2 graph, recorded bag files, and the raw DDS layer beneath ROS — without ever publishing back to the bus. **Eleven typed read-only tools** (5 ROS2 graph + 3 DDS + 3 observability/bag) share a single Pydantic envelope so an LLM caller reads one schema across the whole stack. v0.4.0 adds participant lifecycle tracking (`participant_events`), temporal metrics (`topic_metrics`), and post-mortem bag sample peek (`peek_bag_samples`) on top of v0.3.0's two OSS Python DDS participants — Eclipse CycloneDDS and eProsima Fast DDS — each observing **every conformant vendor on the wire** (RTI Connext, OpenDDS, CoreDX, Dust DDS in Rust, etc.) via the OMG protocol guarantee. See [`docs/dds-interop-matrix.md`](docs/dds-interop-matrix.md) for the canonical multi-vendor positioning and the OMG May 2025 interop reference.
|
|
77
79
|
|
|
78
80
|
TopicForge is a production-minded MCP (Model Context Protocol) server that lets AI agents — such as Claude — inspect ROS2 topics, analyze ROS bag files, and (since v0.2.0) observe the raw DDS layer through a clean, structured tool interface. It is read-only by **architecture**, not by configuration: there is no write path to misconfigure, no permission system to audit, no liability conversation to have. The MCP client can see the robot stack; it cannot touch it.
|
|
79
81
|
|
|
@@ -239,21 +241,24 @@ CoreDX, InterCOM) ship under the optional `topicforge-pro` package with
|
|
|
239
241
|
BYO vendor license. See [`docs/pro.md`](docs/pro.md) for the early-access
|
|
240
242
|
slot and pricing terms ; nothing is collected today.
|
|
241
243
|
|
|
242
|
-
|
|
244
|
+
Six DDS / observability tools (in addition to the five ROS2 tools above) :
|
|
243
245
|
|
|
244
|
-
| Tool | Purpose
|
|
245
|
-
| ----------------------- |
|
|
246
|
-
| `list_participants` | DDS participants discovered on a domain, with vendor and
|
|
247
|
-
| `detect_qos_mismatches` | Reader/writer QoS incompatibilities preventing communication on a topic
|
|
248
|
-
| `peek_dds_samples` | Recent samples on a raw DDS topic (distinct from `sample_messages` on ROS2 graph)|
|
|
246
|
+
| Tool | Since | Purpose |
|
|
247
|
+
| ----------------------- | ------- | -------------------------------------------------------------------------------------------------------------- |
|
|
248
|
+
| `list_participants` | v0.2.0 | DDS participants discovered on a domain, with vendor, hostname, and (v0.4.0) lifecycle fields |
|
|
249
|
+
| `detect_qos_mismatches` | v0.2.0 | Reader/writer QoS incompatibilities preventing communication on a topic |
|
|
250
|
+
| `peek_dds_samples` | v0.2.0 | Recent samples on a raw DDS topic — v0.4.0 adds best-effort XTypes user-topic decode (distinct from `sample_messages` on ROS2 graph) |
|
|
251
|
+
| `participant_events` | v0.4.0 | Lifecycle stream — `discovered` / `lost` participant events over a configurable window |
|
|
252
|
+
| `topic_metrics` | v0.4.0 | Temporal metrics — observed frequency, sequence gaps, latency p50/p95/p99 over a sliding window |
|
|
253
|
+
| `peek_bag_samples` | v0.4.0 | Post-mortem inspection — decoded samples from a recorded `.mcap` / `.db3` / `.bag` file |
|
|
249
254
|
|
|
250
|
-
**Composite adapter (v0.4.0 Phase 1+).** When `TOPICFORGE_MODE=live` is paired with a DDS backend (`cyclone`, `fast`, …), TopicForge instantiates **both** a ROS2 CLI adapter and the chosen DDS adapter and routes per-tool category — the 5 ROS2 tools hit the CLI, the
|
|
255
|
+
**Composite adapter (v0.4.0 Phase 1+).** When `TOPICFORGE_MODE=live` is paired with a DDS backend (`cyclone`, `fast`, …), TopicForge instantiates **both** a ROS2 CLI adapter and the chosen DDS adapter and routes per-tool category — the 5 ROS2 tools hit the CLI, the DDS / observability tools hit the DDS backend. ROS2-only or DDS-only setups still work — the missing half is skipped and the present half serves what it can. The mock backend continues to expose all 11 tools against deterministic fixtures for local development.
|
|
251
256
|
|
|
252
|
-
|
|
257
|
+
**`peek_dds_samples` payload shape (v0.4.0 Phase 1.5).** Full-fidelity on the 4 builtin DCPS topics (`DCPSParticipant`, `DCPSSubscription`, `DCPSPublication`). Arbitrary user topics return best-effort decoded samples with a `_decode_status` annotation : `"full"` (every IDL field decoded — currently a v0.4.0+ Cyclone XTypes path), `"partial"` (some fields decoded, others opaque), or `"raw"` (binding could not resolve the dynamic XTypes — bytes preserved as hex in `_raw_bytes_hex`). The diagnostic key `_decode_note` carries a short explanation when the status is non-`full`. The wire shape is identical across Cyclone and Fast backends.
|
|
253
258
|
|
|
254
259
|
**`RTI Connext`** is v0.4.0+ Pro tier (BYO license — see `docs/pro.md`).
|
|
255
260
|
|
|
256
|
-
**Full 5-minute walkthrough** — backend selection, the canonical QoS-mismatch debugging scenario, troubleshooting — lives in [`docs/DDS_QUICKSTART.md`](docs/DDS_QUICKSTART.md). Migration
|
|
261
|
+
**Full 5-minute walkthrough** — backend selection, the canonical QoS-mismatch debugging scenario, troubleshooting — lives in [`docs/DDS_QUICKSTART.md`](docs/DDS_QUICKSTART.md). Migration history : [v0.2 → v0.3](docs/MIGRATION_v0.2_to_v0.3.md), [v0.3 → v0.4](docs/MIGRATION_v0.3_to_v0.4.md).
|
|
257
262
|
|
|
258
263
|
### Configure with Claude Desktop
|
|
259
264
|
|
|
@@ -308,7 +313,7 @@ make check # both, plus tests (CI bundle)
|
|
|
308
313
|
| `TOPICFORGE_LOG_LEVEL` | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR` |
|
|
309
314
|
| `TOPICFORGE_ROS2_BIN` | `ros2` | Name (or path) of the ROS2 CLI binary |
|
|
310
315
|
| `TOPICFORGE_TELEMETRY` | `off` | Opt-in anonymous usage telemetry. See [Telemetry](#telemetry). |
|
|
311
|
-
| `TOPICFORGE_DDS_BACKEND` | `mock` | DDS module backend: `mock`, `cyclone`, `fast`, `rti`, or `auto`.
|
|
316
|
+
| `TOPICFORGE_DDS_BACKEND` | `mock` | DDS module backend: `mock`, `cyclone`, `fast`, `rti`, `opensplice`, `coredx`, `intercom`, `opendds`, `dust`, or `auto`. The v0.4.0 Phase 1.5 auto-detect chain resolves to: `rti > opensplice > coredx > intercom` (Pro tier, if installed) `> opendds > fast > cyclone > dust > mock`. See [Multi-vendor DDS support](#multi-vendor-dds-support-v030). |
|
|
312
317
|
| `TOPICFORGE_DDS_DOMAIN_ID` | `0` | DDS domain id observed (0..232) when a DDS backend is active. |
|
|
313
318
|
|
|
314
319
|
See [`.env.example`](.env.example).
|
|
@@ -336,7 +341,7 @@ When telemetry is on, each MCP tool call emits a single event with **only** thes
|
|
|
336
341
|
|
|
337
342
|
| Field | Example | Notes |
|
|
338
343
|
| ----------------- | ---------------- | ---------------------------------------------------------------------- |
|
|
339
|
-
| `tool_name` | `"list_topics"` | One of the
|
|
344
|
+
| `tool_name` | `"list_topics"` | One of the eleven MCP tools — never argument values. |
|
|
340
345
|
| `latency_ms` | `12.34` | Wall-clock duration of the handler, rounded to 2 decimals. |
|
|
341
346
|
| `mode` | `"mock"` | Effective runtime mode: `mock` or `live`. |
|
|
342
347
|
| `version` | `"0.1.2"` | TopicForge server version. |
|
|
@@ -382,16 +387,14 @@ See [`docs/product-plan.md`](docs/product-plan.md) for the full product trajecto
|
|
|
382
387
|
|
|
383
388
|
Near-term additions on the bench:
|
|
384
389
|
|
|
385
|
-
- `rclpy`-backed live adapter for faster & richer sampling
|
|
386
|
-
-
|
|
387
|
-
-
|
|
388
|
-
-
|
|
389
|
-
-
|
|
390
|
-
- URDF inspector / validator MCP tools
|
|
391
|
-
- Bag anomaly detection (clock jumps, gaps, dropped frames, TF tree health)
|
|
390
|
+
- `rclpy`-backed live adapter for faster & richer sampling (per-message rmw receive timestamps, windowed sampling) — gated on external user demand
|
|
391
|
+
- Extended QoS coverage (Liveliness, Ownership, Partition, TimeBasedFilter, LatencyBudget) — v0.5.x patch
|
|
392
|
+
- Real `RtiConnextAdapter` in the Pro tier (BYO RTI Connext license, gated by `TOPICFORGE_LICENSE_KEY`) — the v0.4.0 Phase 1.5 framework is in place ; production binding pending Pro tier launch
|
|
393
|
+
- URDF inspector / validator MCP tools (Pro tier)
|
|
394
|
+
- Bag anomaly detection (clock jumps, gaps, dropped frames, TF tree health) — Pro tier
|
|
392
395
|
- Dataset export helpers (rosbag → COCO / HF Datasets)
|
|
393
396
|
- Synthetic data pipeline controller (Blender, Gazebo, Isaac Sim)
|
|
394
|
-
- Hosted MCP endpoint with auth
|
|
397
|
+
- Hosted MCP endpoint with auth (Phase 3 — depends on Pro tier traction)
|
|
395
398
|
|
|
396
399
|
## Project layout
|
|
397
400
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# TopicForge
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/topicforge/)
|
|
4
|
+
[](https://github.com/yaniswav/TopicForge/actions/workflows/ci.yml)
|
|
4
5
|
[](https://pypi.org/project/topicforge/)
|
|
5
6
|
[](https://github.com/yaniswav/TopicForge/blob/main/LICENSE)
|
|
6
7
|
[](https://github.com/yaniswav/TopicForge#security-model)
|
|
7
8
|
|
|
8
|
-
> **The safety-first read-only MCP for ROS2 robotics —
|
|
9
|
+
> **The safety-first read-only MCP for ROS2 robotics — observability + multi-vendor OMG DDS-RTPS (v0.4.0).** TopicForge lets AI agents inspect your ROS2 graph, recorded bag files, and the raw DDS layer beneath ROS — without ever publishing back to the bus. **Eleven typed read-only tools** (5 ROS2 graph + 3 DDS + 3 observability/bag) share a single Pydantic envelope so an LLM caller reads one schema across the whole stack. v0.4.0 adds participant lifecycle tracking (`participant_events`), temporal metrics (`topic_metrics`), and post-mortem bag sample peek (`peek_bag_samples`) on top of v0.3.0's two OSS Python DDS participants — Eclipse CycloneDDS and eProsima Fast DDS — each observing **every conformant vendor on the wire** (RTI Connext, OpenDDS, CoreDX, Dust DDS in Rust, etc.) via the OMG protocol guarantee. See [`docs/dds-interop-matrix.md`](docs/dds-interop-matrix.md) for the canonical multi-vendor positioning and the OMG May 2025 interop reference.
|
|
9
10
|
|
|
10
11
|
TopicForge is a production-minded MCP (Model Context Protocol) server that lets AI agents — such as Claude — inspect ROS2 topics, analyze ROS bag files, and (since v0.2.0) observe the raw DDS layer through a clean, structured tool interface. It is read-only by **architecture**, not by configuration: there is no write path to misconfigure, no permission system to audit, no liability conversation to have. The MCP client can see the robot stack; it cannot touch it.
|
|
11
12
|
|
|
@@ -171,21 +172,24 @@ CoreDX, InterCOM) ship under the optional `topicforge-pro` package with
|
|
|
171
172
|
BYO vendor license. See [`docs/pro.md`](docs/pro.md) for the early-access
|
|
172
173
|
slot and pricing terms ; nothing is collected today.
|
|
173
174
|
|
|
174
|
-
|
|
175
|
+
Six DDS / observability tools (in addition to the five ROS2 tools above) :
|
|
175
176
|
|
|
176
|
-
| Tool | Purpose
|
|
177
|
-
| ----------------------- |
|
|
178
|
-
| `list_participants` | DDS participants discovered on a domain, with vendor and
|
|
179
|
-
| `detect_qos_mismatches` | Reader/writer QoS incompatibilities preventing communication on a topic
|
|
180
|
-
| `peek_dds_samples` | Recent samples on a raw DDS topic (distinct from `sample_messages` on ROS2 graph)|
|
|
177
|
+
| Tool | Since | Purpose |
|
|
178
|
+
| ----------------------- | ------- | -------------------------------------------------------------------------------------------------------------- |
|
|
179
|
+
| `list_participants` | v0.2.0 | DDS participants discovered on a domain, with vendor, hostname, and (v0.4.0) lifecycle fields |
|
|
180
|
+
| `detect_qos_mismatches` | v0.2.0 | Reader/writer QoS incompatibilities preventing communication on a topic |
|
|
181
|
+
| `peek_dds_samples` | v0.2.0 | Recent samples on a raw DDS topic — v0.4.0 adds best-effort XTypes user-topic decode (distinct from `sample_messages` on ROS2 graph) |
|
|
182
|
+
| `participant_events` | v0.4.0 | Lifecycle stream — `discovered` / `lost` participant events over a configurable window |
|
|
183
|
+
| `topic_metrics` | v0.4.0 | Temporal metrics — observed frequency, sequence gaps, latency p50/p95/p99 over a sliding window |
|
|
184
|
+
| `peek_bag_samples` | v0.4.0 | Post-mortem inspection — decoded samples from a recorded `.mcap` / `.db3` / `.bag` file |
|
|
181
185
|
|
|
182
|
-
**Composite adapter (v0.4.0 Phase 1+).** When `TOPICFORGE_MODE=live` is paired with a DDS backend (`cyclone`, `fast`, …), TopicForge instantiates **both** a ROS2 CLI adapter and the chosen DDS adapter and routes per-tool category — the 5 ROS2 tools hit the CLI, the
|
|
186
|
+
**Composite adapter (v0.4.0 Phase 1+).** When `TOPICFORGE_MODE=live` is paired with a DDS backend (`cyclone`, `fast`, …), TopicForge instantiates **both** a ROS2 CLI adapter and the chosen DDS adapter and routes per-tool category — the 5 ROS2 tools hit the CLI, the DDS / observability tools hit the DDS backend. ROS2-only or DDS-only setups still work — the missing half is skipped and the present half serves what it can. The mock backend continues to expose all 11 tools against deterministic fixtures for local development.
|
|
183
187
|
|
|
184
|
-
|
|
188
|
+
**`peek_dds_samples` payload shape (v0.4.0 Phase 1.5).** Full-fidelity on the 4 builtin DCPS topics (`DCPSParticipant`, `DCPSSubscription`, `DCPSPublication`). Arbitrary user topics return best-effort decoded samples with a `_decode_status` annotation : `"full"` (every IDL field decoded — currently a v0.4.0+ Cyclone XTypes path), `"partial"` (some fields decoded, others opaque), or `"raw"` (binding could not resolve the dynamic XTypes — bytes preserved as hex in `_raw_bytes_hex`). The diagnostic key `_decode_note` carries a short explanation when the status is non-`full`. The wire shape is identical across Cyclone and Fast backends.
|
|
185
189
|
|
|
186
190
|
**`RTI Connext`** is v0.4.0+ Pro tier (BYO license — see `docs/pro.md`).
|
|
187
191
|
|
|
188
|
-
**Full 5-minute walkthrough** — backend selection, the canonical QoS-mismatch debugging scenario, troubleshooting — lives in [`docs/DDS_QUICKSTART.md`](docs/DDS_QUICKSTART.md). Migration
|
|
192
|
+
**Full 5-minute walkthrough** — backend selection, the canonical QoS-mismatch debugging scenario, troubleshooting — lives in [`docs/DDS_QUICKSTART.md`](docs/DDS_QUICKSTART.md). Migration history : [v0.2 → v0.3](docs/MIGRATION_v0.2_to_v0.3.md), [v0.3 → v0.4](docs/MIGRATION_v0.3_to_v0.4.md).
|
|
189
193
|
|
|
190
194
|
### Configure with Claude Desktop
|
|
191
195
|
|
|
@@ -240,7 +244,7 @@ make check # both, plus tests (CI bundle)
|
|
|
240
244
|
| `TOPICFORGE_LOG_LEVEL` | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR` |
|
|
241
245
|
| `TOPICFORGE_ROS2_BIN` | `ros2` | Name (or path) of the ROS2 CLI binary |
|
|
242
246
|
| `TOPICFORGE_TELEMETRY` | `off` | Opt-in anonymous usage telemetry. See [Telemetry](#telemetry). |
|
|
243
|
-
| `TOPICFORGE_DDS_BACKEND` | `mock` | DDS module backend: `mock`, `cyclone`, `fast`, `rti`, or `auto`.
|
|
247
|
+
| `TOPICFORGE_DDS_BACKEND` | `mock` | DDS module backend: `mock`, `cyclone`, `fast`, `rti`, `opensplice`, `coredx`, `intercom`, `opendds`, `dust`, or `auto`. The v0.4.0 Phase 1.5 auto-detect chain resolves to: `rti > opensplice > coredx > intercom` (Pro tier, if installed) `> opendds > fast > cyclone > dust > mock`. See [Multi-vendor DDS support](#multi-vendor-dds-support-v030). |
|
|
244
248
|
| `TOPICFORGE_DDS_DOMAIN_ID` | `0` | DDS domain id observed (0..232) when a DDS backend is active. |
|
|
245
249
|
|
|
246
250
|
See [`.env.example`](.env.example).
|
|
@@ -268,7 +272,7 @@ When telemetry is on, each MCP tool call emits a single event with **only** thes
|
|
|
268
272
|
|
|
269
273
|
| Field | Example | Notes |
|
|
270
274
|
| ----------------- | ---------------- | ---------------------------------------------------------------------- |
|
|
271
|
-
| `tool_name` | `"list_topics"` | One of the
|
|
275
|
+
| `tool_name` | `"list_topics"` | One of the eleven MCP tools — never argument values. |
|
|
272
276
|
| `latency_ms` | `12.34` | Wall-clock duration of the handler, rounded to 2 decimals. |
|
|
273
277
|
| `mode` | `"mock"` | Effective runtime mode: `mock` or `live`. |
|
|
274
278
|
| `version` | `"0.1.2"` | TopicForge server version. |
|
|
@@ -314,16 +318,14 @@ See [`docs/product-plan.md`](docs/product-plan.md) for the full product trajecto
|
|
|
314
318
|
|
|
315
319
|
Near-term additions on the bench:
|
|
316
320
|
|
|
317
|
-
- `rclpy`-backed live adapter for faster & richer sampling
|
|
318
|
-
-
|
|
319
|
-
-
|
|
320
|
-
-
|
|
321
|
-
-
|
|
322
|
-
- URDF inspector / validator MCP tools
|
|
323
|
-
- Bag anomaly detection (clock jumps, gaps, dropped frames, TF tree health)
|
|
321
|
+
- `rclpy`-backed live adapter for faster & richer sampling (per-message rmw receive timestamps, windowed sampling) — gated on external user demand
|
|
322
|
+
- Extended QoS coverage (Liveliness, Ownership, Partition, TimeBasedFilter, LatencyBudget) — v0.5.x patch
|
|
323
|
+
- Real `RtiConnextAdapter` in the Pro tier (BYO RTI Connext license, gated by `TOPICFORGE_LICENSE_KEY`) — the v0.4.0 Phase 1.5 framework is in place ; production binding pending Pro tier launch
|
|
324
|
+
- URDF inspector / validator MCP tools (Pro tier)
|
|
325
|
+
- Bag anomaly detection (clock jumps, gaps, dropped frames, TF tree health) — Pro tier
|
|
324
326
|
- Dataset export helpers (rosbag → COCO / HF Datasets)
|
|
325
327
|
- Synthetic data pipeline controller (Blender, Gazebo, Isaac Sim)
|
|
326
|
-
- Hosted MCP endpoint with auth
|
|
328
|
+
- Hosted MCP endpoint with auth (Phase 3 — depends on Pro tier traction)
|
|
327
329
|
|
|
328
330
|
## Project layout
|
|
329
331
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# DDS quickstart — TopicForge v0.
|
|
1
|
+
# DDS quickstart — TopicForge v0.4.0+
|
|
2
2
|
|
|
3
3
|
A 5-minute tour of TopicForge's multi-vendor DDS observability module. Both backends — Eclipse CycloneDDS and eProsima Fast DDS — join the bus as **read-only DDS-RTPS participants** and observe every conformant vendor on the wire via the OMG protocol guarantee. The `MiddlewareAdapter` protocol does not expose a write method, so the MCP client cannot publish back to the bus on any backend.
|
|
4
4
|
|
|
@@ -99,25 +99,25 @@ The analyzer covers the four MVP policies — **Reliability**, **Durability**, *
|
|
|
99
99
|
|
|
100
100
|
---
|
|
101
101
|
|
|
102
|
-
## 4.
|
|
102
|
+
## 4. Composite adapter (v0.4.0 Phase 1+)
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
v0.4.0 Phase 1 lifted the v0.3.0 single-adapter limitation. When `TOPICFORGE_MODE=live` is paired with a DDS backend, TopicForge instantiates **both** a `Ros2CliAdapter` and the chosen DDS adapter behind a `CompositeAdapter` and routes per-tool category — the 5 ROS2 graph tools hit the CLI, the 6 DDS / observability tools (`list_participants`, `detect_qos_mismatches`, `peek_dds_samples`, `participant_events`, `topic_metrics`, `peek_bag_samples`) hit the DDS half. The `name` collapses to `"ros2_cli+cyclone"` or `"ros2_cli+fast"` ; `effective_mode` reports `"live"` whenever either half is live.
|
|
105
105
|
|
|
106
|
-
| `TOPICFORGE_MODE` | `TOPICFORGE_DDS_BACKEND` | Active adapter
|
|
107
|
-
| ----------------- | ------------------------ |
|
|
108
|
-
| `mock` | (any) | `MockAdapter`
|
|
109
|
-
| `live` / `auto` | `mock` (default) | `Ros2CliAdapter`
|
|
110
|
-
| `live` / `auto` | `cyclone` | `
|
|
111
|
-
| `live` / `auto` | `fast` | `
|
|
112
|
-
| `live` / `auto` | `rti` | falls back to
|
|
106
|
+
| `TOPICFORGE_MODE` | `TOPICFORGE_DDS_BACKEND` | Active adapter | ROS2 tools | DDS / observability tools |
|
|
107
|
+
| ----------------- | ------------------------ | ----------------------------- | -------------------------------- | ----------------------------------- |
|
|
108
|
+
| `mock` | (any) | `MockAdapter` | work (fixtures) | work (fixtures) |
|
|
109
|
+
| `live` / `auto` | `mock` (default) | `Ros2CliAdapter` | work | raise with remediation |
|
|
110
|
+
| `live` / `auto` | `cyclone` | `CompositeAdapter(ros2_cli + cyclone)` | work (CLI) | work (real CycloneDDS) |
|
|
111
|
+
| `live` / `auto` | `fast` | `CompositeAdapter(ros2_cli + fast)` | work (CLI) | work (real Fast DDS) |
|
|
112
|
+
| `live` / `auto` | `rti` | falls back to `Ros2CliAdapter` | work (CLI) | raise (v0.4.0+ Pro tier — BYO license) |
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
**Graceful degradation paths preserved.** DDS binding missing → ROS2-CLI-only (the v0.3.0 behavior). ROS2 CLI missing on PATH → DDS-only adapter with a clear `DDS_ONLY_ERROR_MSG` on the 5 ROS2 methods. Neither available → MockAdapter (auto mode only).
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
`HealthReport` reports both halves via the `ros_backend` and `dds_backend` fields, so a downstream client can introspect which half of a composite is live without guessing.
|
|
117
117
|
|
|
118
118
|
---
|
|
119
119
|
|
|
120
|
-
## 5. v0.
|
|
120
|
+
## 5. v0.4.0 scope of `peek_dds_samples`
|
|
121
121
|
|
|
122
122
|
`peek_dds_samples` is full-fidelity on the 4 builtin DCPS topics with both backends :
|
|
123
123
|
|
|
@@ -127,18 +127,26 @@ peek_dds_samples(topic="DCPSSubscription", count=10)
|
|
|
127
127
|
peek_dds_samples(topic="DCPSPublication", count=10)
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
Arbitrary user topics
|
|
130
|
+
**Arbitrary user topics (v0.4.0 Phase 1.5+).** The v0.3.0 `AdapterError` is retired. The tool now returns best-effort decoded samples annotated with a `_decode_status` field :
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
- `"full"` — every IDL field decoded (currently the Cyclone XTypes path, structurally in place ; real-bus validation pending user feedback)
|
|
133
|
+
- `"partial"` — some fields decoded, others opaque (mixed-success path)
|
|
134
|
+
- `"raw"` — the binding could not resolve the dynamic XTypes ; the serialized payload is preserved as hex in `_raw_bytes_hex` (capped at 4096 hex chars ; `_raw_bytes_truncated=True` flags clipping)
|
|
135
|
+
|
|
136
|
+
The diagnostic key `_decode_note` carries a short explanation when the status is non-`full`. The wire shape is identical across Cyclone and Fast DDS — the analyzer doesn't need to know which backend produced the sample.
|
|
137
|
+
|
|
138
|
+
Fast DDS 2.6.x exposes only a partial dynamic XTypes Python surface today, so the `"raw"` fallback is the common path on Fast DDS user topics — the structural plumbing is identical to Cyclone, the upstream binding completion is the gating factor.
|
|
139
|
+
|
|
140
|
+
The other DDS tools — `list_participants`, `detect_qos_mismatches`, `participant_events`, `topic_metrics` — work end-to-end on any user-topic deployment ; they don't depend on payload deserialization.
|
|
133
141
|
|
|
134
142
|
---
|
|
135
143
|
|
|
136
144
|
## 6. What's next
|
|
137
145
|
|
|
138
|
-
- **v0.
|
|
139
|
-
- **v0.
|
|
140
|
-
- **v0.
|
|
141
|
-
- **v0.4.0
|
|
146
|
+
- **v0.5.x patch** — Fast DDS XTypes binding completion to lift `"raw"` → `"full"` for arbitrary user-topic peek on Fast.
|
|
147
|
+
- **v0.5.x patch** — Extended QoS coverage : Liveliness, Ownership, Partition, TimeBasedFilter, LatencyBudget.
|
|
148
|
+
- **v0.5.x patch** — Real-bus validation of the Cyclone XTypes pipeline (the v0.4.0 Phase 1.5 structural pipeline awaits user feedback on real domains).
|
|
149
|
+
- **v0.4.0+ Pro tier** — Real `RtiConnextAdapter` (BYO RTI Connext license, gated by `TOPICFORGE_LICENSE_KEY`). Scaffolded but not yet shipped.
|
|
142
150
|
|
|
143
151
|
Full strategic roadmap lives in [`docs/product-plan.md`](product-plan.md) and the DDS module spec at [`docs/projet-file/mcp-02-spec.md`](projet-file/mcp-02-spec.md).
|
|
144
152
|
|
|
@@ -149,8 +157,9 @@ Full strategic roadmap lives in [`docs/product-plan.md`](product-plan.md) and th
|
|
|
149
157
|
- **`pip install topicforge[dds-cyclone]` fails on Windows / macOS Python 3.13+** — `cyclonedds` wheels are typically published for Python 3.8 to 3.12. Pin Python 3.11 or 3.12 for the install host.
|
|
150
158
|
- **`pip install topicforge[dds-cyclone]` fails with `CYCLONEDDS_HOME`** — pip is trying to build `cyclonedds` from source because no wheel matches your platform/Python combination. Either switch to a supported Python (3.11/3.12) or install the native CycloneDDS C library first (see Eclipse CycloneDDS releases).
|
|
151
159
|
- **`pip install topicforge[dds-fast]` fails** — eProsima Fast DDS Python bindings (`fastdds>=2.6.1,<3`) currently ship wheels for Linux first. Windows wheels lag ; consult fast-dds.docs.eprosima.com for the current matrix.
|
|
152
|
-
- **DDS tool returns
|
|
153
|
-
- **DDS tool returns "DDS module is not active" error** — your `TOPICFORGE_DDS_BACKEND` is `mock` while `TOPICFORGE_MODE` is `live` (the ROS2 CLI
|
|
160
|
+
- **DDS tool returns samples with `_decode_status="raw"`** — the binding could not resolve the dynamic XTypes for this user topic. Inspect `_decode_note` for the cause and `_raw_bytes_hex` for the serialized payload. On Fast DDS this is the common path until 2.6.x dynamic XTypes binding completion. On Cyclone, ensure the publisher uses XTypes-discoverable types and re-run.
|
|
161
|
+
- **DDS tool returns "DDS module is not active" error** — your `TOPICFORGE_DDS_BACKEND` is `mock` while `TOPICFORGE_MODE` is `live` (the ROS2 CLI half of the composite is the only one selected). Set `TOPICFORGE_DDS_BACKEND=cyclone` or `=fast` explicitly to enable the DDS half — the `CompositeAdapter` will then serve both surfaces.
|
|
162
|
+
- **DDS tool returns "DDS observability only" with a long remediation message** — the inverse case: a DDS-only adapter is active (the ROS2 CLI is missing on PATH) and you called a ROS2 graph tool. Install ROS2 and source the workspace so `ros2` is on PATH ; the `CompositeAdapter` will pick up both halves on the next run.
|
|
154
163
|
- **`auto` selects the wrong backend** — `auto` prefers Fast > Cyclone > Mock. If you want Cyclone explicitly, set `TOPICFORGE_DDS_BACKEND=cyclone` rather than relying on `auto`.
|
|
155
164
|
|
|
156
165
|
Report issues at https://github.com/yaniswav/TopicForge/issues.
|