pj_source batch: provider-contract promotions, packaged test fixtures, provider guide (0.31.0) - #194
Merged
Merged
Conversation
…, provider guide (0.31.0)
The descriptor_import_support component grows and renames to pj_source
(PJ::sdk::source, plotjuggler_sdk::source) with a one-release deprecated
alias (forwarding headers + namespace alias + INTERFACE target + Conan
component). No C-ABI surface changes: protocol headers, vtable sizes and
ABI sentinels are untouched.
Promoted from the two cloud provider plugins (write once, review once):
- limits: envLimit()/minNonzero() fail-safe env ceilings (strict
full-string parse via PJ::parseNumber; unparsable = safe default,
never off).
- parseDecimalNs: int64-safe decimal-nanosecond wire parse.
- validateSchemelessOrigin: strict lowercase host:port charset validator
(schemes/userinfo/path/query/fragment/IPv6 rejected by construction).
- presentation: the host Load-Layout contract — unpadded
base64url(identity) settings group; C0/C1, zero-width, bidi, ALM,
word-joiner stripping; 200 UTF-16-unit cap without splitting pairs.
- IngestOutcomeLedger: per-topic outcomes -> truthful whole-request
terminal (+ATTESTS_EMPTY_TOPICS), pure logic, caller-owned locking.
- record_envelope: the attach_source_record acceptance envelope as a
public versioned contract ({kind, v, request, label?}) with the
credential-key denylist folded into SourceDescriptorPolicy::denied_keys
(opt-in, default empty) inside the existing single recursive walk;
refusal messages byte-compatible with the PJ4 host implementation;
the flat pre-envelope shape is a pinned REJECTED vector.
- stop_bridge: StopPoller (observe a live ingest context's stop flag,
cancel once, join before context release) + the documented
cancel-before-join contract.
- time_format + slider_window (pj_base proper): the byte-identical
286-line time formatter hardened through combineSecondsAndNanos, and
overflow-safe slider<->time conversion with its regression tests.
- RollingTransferRate: monotonic 5-second byte-rate window.
- pj_plugins/testing/delegated_ingest_fixture.hpp: merged fake host pair
(attachment/completion/Stop/discard evidence through the SDK's own
copyIngestCompletion; double-fetch + anchor lifetime; truncated
vtables; cancel during blocked ingest).
- Packaged example/mock plugin fixture sources under
share/plotjuggler_sdk/test_fixtures/ with the exported
pj_add_sdk_test_fixture() helper (single PJ_SDK_TEST_FIXTURES list
feeds both the helper and the install rule) — PJ4 can drop its second
FetchContent of the release tarball.
- docs/provider-guide.md: the full provider-contract walkthrough.
The metadata query language deliberately does NOT ship here: it moved to
pj-official-plugins common/ (maintainer decision 2026-09-06) so its
syntax can evolve without SDK compatibility events; docs/BACKLOG.md
records the decision.
Pipeline: Codex implementation, independent session review, and a
4-angle simplify pass (lexer/API/dedup cleanups; internal consumers
de-aliased off the deprecated names).
Tests: 95/95 (115 cases added); test_sdk_install.sh (real Conan
package + consumer + per-component find_package smoke) PASSED.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTJvEsHX26rG4cHmqppvQg
…parsing
Codex time-helper audit applied: the copied Hinnant civil-calendar
algorithms are replaced by portable C++20 core chrono (year_month_day /
sys_days / hh_mm_ss — supported on every toolchain in the matrix incl.
GCC 11 and Emscripten, unlike chrono format/parse which stay hand-rolled);
padded output goes through the SDK's existing private fmt from the
extracted fields (never fmt's time-point formatter, whose gmtime path
rejects pre-1970 on Windows) which also removes the global-locale
grouping hazard; the ISO offset grammar now rejects a colon without
minutes ('+05:'); and the two widget time-span readers drop unchecked
stoll for the strict PJ::parseNumber ('123junk' now refused, signed
values preserved). Regression tests: -1 ns, INT64_MIN, grouping locale,
offset grammar, junk-suffix readers. fmt stays out of installed headers.
Production -44 lines, tests +81. 95/95 suites, pre-commit clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTJvEsHX26rG4cHmqppvQg
Moved to pj-official-plugins common/transfer_rate with its test — same placement rule that kept the query language out of the SDK: pure UI helpers with no host contract stay with the dialogs that show them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TTJvEsHX26rG4cHmqppvQg
…watchdog test
Full-tree documentation audit applied (agent lens: find the existing
symbol before reimplementing it, at minimal token cost):
- docs/sdk-utilities.md: the task->symbol->header lookup table (incl.
pointers to the query language and RollingTransferRate in
pj-official-plugins common/, so neither is reimplemented here);
linked from root CLAUDE.md, README, both module CLAUDE.md files, the
plugin skill and the top of the provider guide; shipped with the Conan
package together with the provider guide (docs/ exported; installed
under share/plotjuggler_sdk/docs/).
- Root CLAUDE.md: conditional reading order ('before implementing a
helper, consult sdk-utilities.md'), trimmed to navigation (1,357 -> 624
words); agent entry path to the utilities index is now ~1,340 words.
- Fixed guide examples that taught duplication: message-parser guide's
strtod -> PJ::parseNumber; data-source guide's manual handoff ->
DrainQueue; dialog guide's invented formatDate -> a real SDK formatter.
- Provider guide front-loaded (required machinery named up top; host
capture-cache identity disambiguated); header doc-comment gaps closed
(time_format contracts incl. no-fraction/no-Z output and floor
semantics; outcome_ledger outcome semantics; StopPoller throw
conditions; provider_job gate wording; parseDecimalNs 'overflow'
grep keyword).
- Staleness sweep across ~12 documents: wrong namespaces (PJ::sdk::getEnv,
PJ::okStatus), nonexistent paths/symbols, the ARCHITECTURE claim that
empty-topic attestation does not exist, plot-marker docs contradicting
the shipped codec, V4_STORE's missing toolbox object-write surface,
parser-module counts, BACKLOG scope brought current.
- Prose-clarity pass over 17 documents (-492 words; code blocks and
tables byte-identical; meaning-critical sentences left verbatim).
Deflake: ProviderJobTest.WatchdogFiresOnceWhenTheBodyOverruns widens the
body overrun 120ms -> 400ms — the recurring loaded-macOS-runner flake
where the 20ms watchdog thread starts too late; fire-once semantics
unchanged.
95/95 suites; test_sdk_install.sh (incl. installed-docs comparison)
PASSED; pre-commit clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTJvEsHX26rG4cHmqppvQg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SDK 0.31.0 — the ratified
pj_sourcebatch (spec:docs/BACKLOG.md). Everything the two cloud provider plugins were each hand-rolling for the M3 source-capture contract, promoted once. No C-ABI changes: protocol headers, vtable sizes and ABI sentinels untouched.The rename
descriptor_import_supportgrows intopj_source(PJ::sdk::source,plotjuggler_sdk::source) with a full one-release compatibility layer: forwarding headers,namespace descriptor_import = source, an INTERFACE target under the old export name, and a Conan compatibility component.pj_cloudstays reserved for real connection code.Promoted
envLimit()/minNonzero()fail-safe env ceilings (byte-identical copies existed in both plugins).host:portcharset validator.ATTESTS_EMPTY_TOPICS; pure logic, three review rounds of hardening inherited from the Mosaico implementation.attach_source_recordacceptance envelope as a public versioned contract, replacing PJ4's private convention; credential denylist folded intoSourceDescriptorPolicy::denied_keys(opt-in) inside the existing single recursive walk; refusal messages byte-compatible with the PJ4 host; the flat pre-envelope shape is a pinned REJECTED vector (mcap_cloud migrates via an explicit reshape-or-adapter decision, never silent re-wrapping).StopPoller+ the documented cancel-before-join contract (both plugins had independently built both halves).pj_baseproper) — the shared time formatter and overflow-safe slider↔time conversion. Refactored on review: the copied civil-calendar algorithms are replaced by portable C++20 core chrono (year_month_day/sys_days/hh_mm_ss— verified on GCC 11 and Emscripten; chrono format/parse deliberately NOT used, unavailable across the toolchain matrix), padded output goes through the SDK's existing private fmt from extracted fields (avoids fmt's Windows pre-1970gmtimepath and the global-locale grouping hazard), the ISO offset grammar rejects+05:, and the widget time-span readers use strictPJ::parseNumberinstead of uncheckedstoll.pj_plugins/testing) — merged fake host pair: attachment/completion/Stop/discard evidence through the SDK's owncopyIngestCompletion, double-fetch + anchor lifetime, truncated vtables, cancel during blocked ingest.share/plotjuggler_sdk/test_fixtures/+ exportedpj_add_sdk_test_fixture()) — PJ4 can delete its second FetchContent of the release tarball, the last acquire-outside-Conan path.Deliberately not here
common/query(maintainer decision: its syntax should evolve without SDK compatibility events).common/transfer_rateby the same rule — a pure dialog readout with no host contract is not SDK surface.pj_cloudremain outside per the ratified scope.date, fmt) concluded core chrono + the already-shipped private fmt cover everything;date's Conan default even drags libcurl via its tz half.Pipeline
Codex implementation → independent session review → 4-angle /simplify pass (query-lexer/API dedup, internal consumers de-aliased off the deprecated names, credential check moved to the right altitude) → Codex time-helper audit applied.
Verification
./build.sh --debug && ./test.sh: 95/95 suites.test_sdk_install.sh(real Conan package + consumer build + per-componentfind_packagesmoke): PASSED. Pre-commit clean. fmt verified absent from installed exports.🤖 Generated with Claude Code
https://claude.ai/code/session_01TTJvEsHX26rG4cHmqppvQg