Skip to content

feat(sdk)!: PlotMarkers builtin + unify markers/transforms into pj.data_processors.v1 (kind discriminator)#135

Open
Alvvalencia wants to merge 14 commits into
mainfrom
feature/plot-markers
Open

feat(sdk)!: PlotMarkers builtin + unify markers/transforms into pj.data_processors.v1 (kind discriminator)#135
Alvvalencia wants to merge 14 commits into
mainfrom
feature/plot-markers

Conversation

@Alvvalencia

@Alvvalencia Alvvalencia commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

What

Unifies the two parallel whole-series host services into onepj.data_processors.v1
with a string kind discriminator, so a plugin chooses markers / transform (and future
engines) from the same create call. Also lands the canonical PlotMarkers builtin
object + codec.

This supersedes the interim pj.generators.v1 that earlier revisions of this branch added:
that service is removed; its markers backend now lives under kind="markers" on Pablo's
existing pj.data_processors.v1.

ABI / API changes

  • PJ_data_processors_host_vtable_t.create_data_processor generalized with
    kind / language / flags / out_topics (the resolved sink names).
  • Ephemeral preview is now the PJ_DATA_PROCESSOR_FLAG_EPHEMERAL flag on create_data_processor
    (the separate create_data_processor_ephemeral slot is removed).
  • validate_data_processor_script gains a leading kind argument.
  • Removed pj.generators.v1 entirely (vtable, host_t, GeneratorsHostService, GeneratorsHostView).
  • DataProcessorsHostView = unified create(kind, …) + thin convenience shims
    createTransform / createEphemeralTransform (Status return, signatures unchanged) /
    createMarkers.
  • generators_api_test.cpp folded into data_processors_api_test.cpp (transform + markers).

Versioning

Stays 0.13.0: no public tag has carried pj.data_processors.v1 yet, so no released plugin
breaks. The first public release that carries the unified pj.data_processors.v1 must be
tagged 1.0.0
(pre-1.0 break rule).

⚠️ Coordination with the transform-editor work (Pablo)

This changes the create_data_processor / validate_data_processor_script ABI signatures, so
the host that IMPLEMENTS the service (DataProcessorsRuntimeHost, PJ4 #234) must adopt the
new vtable fill. Callers keep working via the C++ shims; only validateScript call-sites
gain a leading kind ("transform"). Merge this SDK first (it is the bottom layer); PJ4 / plugins
then bump to it. The kind="transform" engine routing is owned by the transform-editor PRs.

Verification

  • ./build.sh (RelWithDebInfo) + ./build.sh --debug (ASAN) green; ./test.sh 48/48 pass.
  • Verified end-to-end in the PJ4 GUI: the Anomaly Detector toolbox renders markers through the
    unified service (host + plugin both built against this ABI).

🤖 Generated with Claude Code

Alvvalencia and others added 12 commits June 16, 2026 13:53
New SDK builtin type for time-series plot markers (findings), the
foundation of the anomaly-detection pipeline feature.

- PlotMarkers (kPlotMarkers = 18): homogeneous, id-less marker records
  (Region / Event / ValueBand / Label) with shared semantic fields
  (status, severity, category, label, description, color, metadata) +
  a PlotMarkers list container. No id/source/scope by design — identity
  is owned by the host marker store; location carries provenance/reach.
- Hand-written PJ.PlotMarkers wire codec following the
  image_annotations_codec idiom; PlotMarkers.proto contract.
- Registered in C++ + C-ABI builtin enums, name()/parse()/typeOf(), and
  the ABI layout sentinel (static_assert id == 18).
- Round-trip codec tests; full pj_base suite green (32/32) under ASAN.
- Design (use-cases, architecture) + wire-format docs.

ColorRGBA reused via image_annotations.hpp per the existing house
convention (mesh3d / scene_entities do the same).

abi/baseline.abi refresh + SDK MINOR version bump deferred to the
release-cut step (additions-only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The plugin-facing contract for plot markers, mirroring the object
read/write host pattern.

- C vtable PJ_marker_store_host_vtable_t + fat pointer + an owning
  PJ_marker_query_handle_t (plugin_data_api.h): add / remove / query /
  query_bytes / release_query. Markers cross as serialized PJ.PlotMarkers
  bytes; ids cross as uint64.
- C++ MarkerStoreHostView (plugin_data_api.hpp) wrapping the codec so
  callers work in typed sdk::PlotMarker; add(single|batch) -> ids,
  remove(id), query -> [{id, marker}]. + MarkerEntry.
- MarkerStoreService trait (service_traits.hpp), "pj.marker_store.v1".

ABI is additive (new service); abi/baseline.abi refresh deferred to the
release-cut step.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ox slot

Markers become a builtin object published to the ObjectStore via the generic object-write surface; the producer republishes the whole PlotMarkers set (last-writer-publish). The dedicated pj.marker_store.v1 service (vtable, MarkerStoreHostView, service trait) is removed.

Add a tail-appended, idempotent toolbox-host slot register_object_topic_on_dataset(DatasetId, ...) so a toolbox can annotate an existing dataset (the object-write path was previously source-scoped). Add marker object-topic naming helpers (markerObjectTopicName / kGlobalMarkerTopic) to plot_markers.hpp. Update the ABI layout sentinel (88->96) and the two mock vtables.

The PlotMarkers type + codec are unchanged. Docs (plot_markers_*) updated to the ObjectStore + republish model. MINOR bump + abi/baseline.abi refresh deferred to release.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…retention toolbox ABI slots

Dialog protocol: add the MarkerTimeline custom widget (TimelineMark setters/event/parser/callback) for an editable multi-marker strip, with a single shared TimelineMark<->JSON codec used by all four sites.

Toolbox host ABI (tail-appended, struct_size-gated): lookup_topic_on_dataset on the object-read vtable (dataset-scoped topic resolution; the name-only lookup is ambiguous across datasets) and set_object_topic_retention on the write vtable (keep-latest-N so a republishing producer's snapshots don't accumulate). Toolbox-host vtable 96->104; sentinels + mock vtables updated.

Add sdk::markerSeriesKey (single-slash join tolerating a leading-'/' field) so producer and overlay build the per-series key identically. Doc refresh.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Additive dialog-protocol surface (ABI-safe, no version bump):
- setSaveFilePicker / isSaveFilePicker — a native "Save As" picker (getSaveFileName)
  so a not-yet-existing file can be created; reported via the existing onFileSelected.
- ChartMarker + setChartMarkers / chartMarkers — overlay markers (events/regions/
  value-bands) on a chart preview, alongside setChartSeries.
- Fix a stale comment that referenced QLineSeries (the preview is Qwt, not Qt Charts).

Cleanup: decodeMarker now drives the shared builtin_wire::parseFields loop like the
sibling codecs, replacing the hand-rolled continue/break/skip control flow. Behavior
and wire format are unchanged (codec round-trip tests pass).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RcygzPWUrHf9jHGGwzEzZo
Reconcile builtin-object ABI: VoxelGrid keeps slot 18 (released in 0.10.0),
PlotMarkers moves to slot 19. SDK 0.8.0 -> 0.10.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BeoYQHmF6ixvYv9KXXgyVh
Adding the PlotMarkers canonical builtin (slot 19) is a MINOR addition over
main's 0.11.0, so the merged SDK is a distinct 0.12.0 — not the upstream 0.11.0
(which lacks PlotMarkers). Keeps version identity clean for downstream pins.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BeoYQHmF6ixvYv9KXXgyVh
… ephemeral preview)

The whole-series analog of pj.data_processors.v1: a plugin submits a marker
generator by data (script + input series + an output marker-topic + params) and
the HOST runs it over the whole series and publishes the resulting PlotMarkers to
the ObjectStore. Nothing executable crosses the boundary.

- PJ_markers_host_vtable_t (plugin_data_api.h): create/remove/list/config +
  tail-appended set_marker_preview / clear_marker_preview for a live, ephemeral
  (non-persisted) preview generator read back through the object surface.
- MarkersHostView (sdk/plugin_data_api.hpp) + MarkersHostService trait.
- params_json {"scope":"all"} makes a global generator publish across every
  dataset; absent = the active dataset only.
- markers_api_test.cpp: fake-host ABI test (forwarding, count-then-fill,
  borrowed-string lifetime, binary-safe payload, preview slots).

Single output_marker_topic (not an outputs[] array): a generator writes exactly
one marker topic (global or per-series).

NOTE: MINOR version bump (conanfile.py / PJ_PACKAGE_VERSION / recipe.yaml) and the
abidiff baseline refresh are pending pre-merge — this commit adds API on a feature
branch (WIP) and does not bump the release version yet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsY1SE2yBsX2qXvkgEnX8U
Bring v0.11.0 SDK work (voxel grid, data-processors API, RangeSlider
markers) into the markers feature branch. Resolved widget_data.hpp
additively: kept the feature's ChartMarker/TimelineMark + MarkerTimeline
setters AND main's RangeSliderMarker + setRangeSliderMarkers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rh6GtzBNRVXXBUhFWhXEam
Unify the whole-series host-driven service under one SDK contract,
PJ_generators_host_vtable_t / GeneratorsHostService ("pj.generators.v1"),
with a string `kind` discriminator:

- kind="markers" (objects -> ObjectStore) is implemented; shared `language`
  param, compile-only validate_script, ephemeral-preview flag, and out_topics
  return apply across kinds.
- kind="transform" (per-sample timeseries -> DerivedEngine) is RESERVED, not
  implemented; its end-state home is decided when the transform-editor work merges.

Removes PJ_markers_host_vtable_t / MarkersHostService (the old pj.markers.v1) and
markers_api_test; adds generators_api_test. A speculative kind="field" that briefly
existed on this branch was dropped (zero consumers, violated the object/timeseries
engine split); it changed no ABI struct since `kind` is a runtime string.

Versioning: API removal, normally MAJOR. Ships as 0.13.0 because no public tag ever
carried pj.markers.v1 (no released plugin breaks). The first public release carrying
pj.generators.v1 MUST be tagged 1.0.0 -- recorded in CHANGELOG.md + a comment by
`version` in conanfile.py.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013N1nzqco4Y9AQhnQgXo5tQ
…ta_processors.v1

Brings origin/main (#134 data-processors script API) into feature/plot-markers and
collapses the two parallel whole-series host services into ONE: Pablo's
`pj.data_processors.v1`, now carrying a string `kind` discriminator so a plugin chooses
`markers`/`transform` (and future engines) from the SAME `create` call.

SDK changes:
- Generalized `PJ_data_processors_host_vtable_t.create_data_processor` with
  kind/language/flags/out_topics; ephemeral preview is now the
  PJ_DATA_PROCESSOR_FLAG_EPHEMERAL flag (removed the separate ephemeral slot);
  validate_data_processor_script gains `kind`.
- Removed the interim `pj.generators.v1` entirely (vtable, host_t,
  GeneratorsHostService, GeneratorsHostView).
- DataProcessorsHostView = unified `create(kind,…)` + thin shims
  createTransform/createEphemeralTransform (Status, signatures unchanged) / createMarkers.
- Folded generators_api_test.cpp into data_processors_api_test.cpp (transform+markers).
- CHANGELOG/conanfile reworded; stays 0.13.0 (no public tag carried the service yet;
  first public unified release MUST be 1.0.0).

Builds green (RelWithDebInfo + debug/ASAN); 48/48 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHPK8VduUcoenjL8AtoSVd
@Alvvalencia Alvvalencia changed the title feat(sdk): PlotMarkers builtin + unified pj.generators.v1 service (kind discriminator) feat(sdk)!: PlotMarkers builtin + unify markers/transforms into pj.data_processors.v1 (kind discriminator) Jun 27, 2026
@Alvvalencia Alvvalencia marked this pull request as ready for review June 27, 2026 08:16
Alvvalencia and others added 2 commits June 27, 2026 10:20
Applies the pre-commit clang-format pass that the merge commit (bf7eb0f) skipped
via --no-verify. Formatting only — no semantic change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHPK8VduUcoenjL8AtoSVd
Completes the formatting pass over the full PR diff (PlotMarkers.proto column
alignment + dialog_plugin_typed.hpp signature wrap) that the narrowly-scoped
previous pass missed. Formatting only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHPK8VduUcoenjL8AtoSVd
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