Skip to content

Wave-5 design freeze: SDK DeviceSpec shape, quality hook, default_signal_ids contract (G3/G5/P5) #48

Description

@CameronBrooks11

Part of the Pre-Wave-5 consistency reconciliation pass (Tier-0 gates G3, G5 + contract P5). Paper decisions that extend the Wave-5 design addendum (D1–D3) with three shapes the audit found D1–D3 don't cover. No code until these are frozen.

G3 — SDK DeviceSpec shape (impedance mismatch)

The config-layer device spec diverges in shape, not just naming:

  • ezo / bread — typed I2C identity: type enum + numeric address, with cross-device dup-id/dup-address std::set enforcement (ezo config/provider_config.hpp:16-37, bread :25-41).
  • sim — opaque std::map<std::string, YAML::Node> subtree, dup-id only (config.hpp:42-46), because sim devices have free-form, device-type-specific schemas validated downstream.

A too-narrow SDK DeviceSpec (assuming numeric address) breaks sim; a too-loose one (opaque map) loses ezo/bread's dup-address + range validation.

  • Decide: spine = {id, label, optional address, type-as-string} + opaque extra subtree; providers layer their typed enum (ezo/bread) or consume the subtree (sim). Resolve on paper before any config code moves — else it forces a second SDK breaking change.

G5 — quality / staleness hook

ezo's read path centralizes quality/staleness/metadata computation in populate_signal_value (src/core/handlers.cpp:304-332): derives QUALITY_OK/STALE/FAULT/UNKNOWN from available/has_value/last_read_ok/age_ms vs stale_after_ms, and packs age_ms/reason/success+failure counts into SignalValue.metadata. sim and bread have no analog (both hard-code QUALITY_OK: sim device_common.hpp:105, bread adapter_helpers.hpp:180).

The D1 SignalSampleSignalValue migration would delete this if done as a naive type swap. This is the real reason D1 is "the highest-risk single step."

  • Decide: keep ezo's quality machinery as an SDK-provided helper quality_from(available, has_value, last_read_ok, age, stale_after) → (QualityCode, metadata) (so all providers can opt in), or keep it inside the ezo adapter. Design before/with the ezo D1 cut.

P5 — §7.2 default_signal_ids contract

The default-signal-set (§7.2) is satisfied at three different layers: ezo at the handler (default_signal_ids, handlers.cpp:410-416), sim in the device adapter (device_manager.cpp:440), bread per-device via is_default_signal() (rlht_adapter.cpp:76, dcmt_adapter.cpp:117). Only ezo's placement is liftable into a shared handler.

  • Decide + define: a single DeviceDescriptor.default_signal_ids contract surfaced to the SDK; sim/bread expose their curated default set through it so the lifted handler owns the empty-signal_ids branch uniformly.

Deliverable: append decisions to working/provider-sdk-wave5-design-addendum.md. Evidence: audit note (G3/G5/P5). Gates the result-type + descriptor lift in #45.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions