Skip to content

feat(sdk): dataset-qualified series name contract + shared split helper (0.26.0) - #183

Closed
Alvvalencia wants to merge 2 commits into
mainfrom
feat/dataset-qualified-names
Closed

feat(sdk): dataset-qualified series name contract + shared split helper (0.26.0)#183
Alvvalencia wants to merge 2 commits into
mainfrom
feat/dataset-qualified-names

Conversation

@Alvvalencia

Copy link
Copy Markdown
Contributor

Why

pj.data_processors.v1 addresses input series by bare topic/field names, and the contract never said what a name means when several loaded datasets share topic names. Conforming hosts filled that gap incompatibly: in PJ4 the transform path refuses a duplicated name while the marker path silently bound the first-loaded dataset (fixed by PlotJuggler/PJ4#619). The parser for the qualified form also exists twice today — in PJ4's pj_runtime and in a plugin — kept identical only by discipline.

What

  • Normative contract in the PJ_data_processors_host_vtable_t doc block (DATASET-QUALIFIED NAMES): a series' full identity is (dataset, topic, field), and an input MAY carry the qualifier dataset_source:topic/field — the same form hosts print as a series identity, so displayed names round-trip as inputs. The qualifier is matched against the loaded source names (longest match wins), never split blindly at :, so source names like [stream] UDP Server need no escaping. The host MUST treat an unknown qualifier as an error (no fallback to the bare reading), MUST refuse a bare name that exists in several datasets by reporting the qualified candidates (never resolve by load order), and MUST require all qualified inputs of one processor to agree on a single dataset. Marker per-series output keys accept the qualifier the same way; transform outputs name new topics and are never qualified.
  • New installed header pj_base/sdk/dataset_qualified_name.hpp: splitDatasetQualifier / qualifiedSeriesName, header-only and std-only — the shared parser/composer.
  • Doc pointers from DataProcessorsHostView::create/createTransform/createMarkers and pj_plugins/docs/ARCHITECTURE.md.
  • Tests: pj_base/tests/dataset_qualified_name_test.cpp.
  • VERSION 0.25.0 → 0.26.0 — MINOR: a new installed public header. No ABI change; abi/baseline.abi untouched, additions only.

Verification

  • ./build.sh --debug && ./test.sh: 83/84 locally. The one failure (PluginCatalogTest.DependencySearchExcludesCwdAndPath) is environment-dependent dlopen search; nothing in this PR is in that test binary's dependency closure, and CI on main is green on the same code.
  • Host-side proof against the reference implementation: PJ4's fix/dataset-qualified-inputs branch was locally rewired so its resolver delegates to this header — all of its dataset-qualification tests pass unchanged, and a GUI end-to-end with two datasets sharing an identical topic layout (a plugin creating markers on run_b.mcap:/sensor/temperature/data) landed on the correct dataset, with region count and covered time matching an independent decode of the file (7 regions, ~12.9 s; the first-loaded dataset would have produced ~7.7 s).

Follow-ups (separate changes, once 0.26.0 is picked up)

  • PJ4 drops its private copy of the splitter and includes this header.
  • Plugin-side callers do the same and start emitting the qualified form on creates.
  • Addressing two datasets that share one source name stays out of contract (ambiguous → error); a typed dataset id would be a tail-appended ABI addition if ever needed.

…er (0.26.0)

pj.data_processors.v1 addressed input series by bare topic/field names and never
said what a name means when several loaded datasets share topic names, so
conforming hosts filled the gap incompatibly (PJ4's transform path refused
duplicates while its marker path silently bound the first-loaded dataset).

The contract is now explicit in the PJ_data_processors_host_vtable_t doc block
(DATASET-QUALIFIED NAMES), and the new installed header
pj_base/sdk/dataset_qualified_name.hpp ships the shared parser/composer
(splitDatasetQualifier / qualifiedSeriesName) so hosts and plugins use one
implementation instead of the two copies that exist today.

MINOR bump to 0.26.0: new installed public header, no ABI change.
@Alvvalencia
Alvvalencia marked this pull request as draft September 1, 2026 09:58
Alvvalencia added a commit that referenced this pull request Sep 1, 2026
Tail-appended MINOR, additions only. Numbered assuming #183 (0.26.0) merges
first; renumber at release if the two land in the other order.
Alvvalencia added a commit that referenced this pull request Sep 3, 2026
The dataset-qualified naming contract (formerly #183, 0.26.0 → 0.27.0 after
GridMap took 0.26.0) and the playback/viewport/plot-tabs services (formerly
claiming 0.28.0 on top of it) are one deliverable for one consumer, so they
ship as one MINOR: 0.27.0, one CHANGELOG section with both parts.
@Alvvalencia

Copy link
Copy Markdown
Contributor Author

Folded into #184: the naming contract and the host services are one deliverable for one consumer (the Assistant Agent toolbox), so they ship as one MINOR (0.27.0) with one review. This branch stays as reference until #184 merges.

@Alvvalencia Alvvalencia closed this Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant