Feat/enhance data contracts#170
Merged
Merged
Conversation
…trarExt for enhanced data integration
…ate() verb (design 041 §3.1) Reshape Simulatable to the one-verb-per-contract model and make simulation a compile-time fact, not a runtime flag: - Trait: add `type Params`; `simulate(params, previous, rng, timestamp_ms)`. Delete `SimulationConfig` (incl. `enabled`) and `SimulationParams`; add `SimProfile<P>` + off-the-shelf `RandomWalkParams`. - New `SimulatableRegistrarExt::simulate(profile, rng)` installs a source loop over `ctx.time()` (runtime-neutral, single-writer enforced by build()). - Cargo: `simulatable = ["rand", "aimdb-core"]`; `rand` drops `std_rng` (caller-supplied RNG; SmallRng needs no feature). D1 callers: - weather-mesh-common temp/humidity/location impls → `type Params = RandomWalkParams`. - weather-station-beta (std) + gamma (no_std): `sim` feature gates `.simulate()`; default (prod/flash) build reads a hardware source and is rand-free — the canonical §3.1.4 `#[cfg]` sim-to-real pattern. CI: `make check-no-sim` proves each station's production graph carries no `rand` (the tracer) and that `simulatable` is never a default feature; wired into the CI makefile-build job. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Removed `ICON` and `format_log` from the `Observable` trait, simplifying the interface. - Introduced `SignalGaugeHandle` for managing signal statistics, allowing for last/min/max/mean tracking. - Added `SignalStats` struct to encapsulate signal statistics with atomic operations for thread safety. - Updated `RecordProfilingMetrics` to include signal gauges and their statistics. - Enhanced `RecordMetadata` to optionally include signal statistics when the observability feature is enabled. - Modified `ObservableRegistrarExt` to support signal observation and logging. - Updated various schemas (e.g., `Temperature`, `Humidity`, `DewPoint`, `GpsLocation`) to align with the new observability model. - Adjusted example applications to utilize the new signal gauge functionality for metrics and logging.
…ign 041 §3.3) Implementing `Linkable` today changed nothing — every example hand-wired `with_deserializer`/`with_serializer` closures. Fix: - `LinkableRegistrarExt::linked_from`/`linked_to` install `.link_from()`/ `.link_to()` with the codec defaulted to `T::from_bytes`/`T::to_bytes`; the raw builders remain the escape hatch for per-link options (QoS, topic providers/resolvers). - `linkable` feature now depends on `aimdb-core` (same wiring as `observable`) for the registrar/connector-builder types the ext needs. - `#[derive(Linkable)]` in `aimdb-derive` emits `serde_json::to_vec`/ `from_slice` — no_std + alloc compatible (serde_json here is alloc-only, no `std` required), removing hand-written JSON boilerplate. D1 caller: tokio-mqtt-connector-demo's TempOutdoor/TempServerRoom (outbound) and CommandKey::TempOutdoor (inbound) now use `#[derive(Linkable)]` + `.linked_to`/`.linked_from`; TempIndoor keeps the raw builder since it needs QoS/retain options the ext doesn't cover. mqtt-connector-demo-common gains an opt-in `data-contracts` feature (alloc-only) so the embassy demo's hand-rolled no_std JSON path stays untouched — it doesn't enable the new feature. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`Settable` was built for the sync bridge, but `aimdb-sync` never referenced it — `SyncProducer::set(value: T)` takes a fully constructed record, so every outside-the-thread caller hand-assembled the struct. - `Settable` moves behind a `settable` feature in `aimdb-data-contracts` for tier symmetry with the other wire contracts (pure trait, no dependencies of its own). weather-mesh-common enables it unconditionally (used by all three contracts); codegen's `generate_cargo_toml`/import emission gained the same `has_settable` detection already used for `has_observable`. - `aimdb-sync` gains a `data-contracts` feature -> optional `aimdb-data-contracts/settable` dep (dependency direction stays contracts -> sync, no `sync` feature added to the contracts crate). `SyncProducer<T: Settable>::set_value`/`try_set_value`/`set_value_at` construct via `T::set(value, timestamp)` and send; `set_value`/ `try_set_value` stamp the caller's `SystemTime`, `set_value_at` takes an explicit timestamp for replay/testing. - Doctest + integration tests (aimdb-sync/tests/settable_integration.rs) exercise `set_value`/`try_set_value`/`set_value_at` end-to-end (construct -> produce -> consume). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…n 041 §6-7) - README: the 4-trait capability table becomes the §2 verb/tier table (Contract / Implement when / Verb / Tier), documents the `Simulatable` dev-tier "never ships in prod" call-out with the `#[cfg]` sim-to-real pattern, and adds the `Settable` row. - CHANGELOG entries for all four touched crates (aimdb-data-contracts, aimdb-core, aimdb-derive, aimdb-sync) describing the trait reshapes, new registrar ext traits, the signal-gauge surface, and the derive macro. - Version bumps: aimdb-data-contracts 0.2.0 -> 0.3.0 (breaking: Simulatable/ Observable reshaped, Settable feature-gated), aimdb-core 1.1.0 -> 1.2.0 (additive: signal_gauge surface), aimdb-derive 0.2.0 -> 0.3.0 (additive: #[derive(Linkable)]), aimdb-sync 0.5.0 -> 0.6.0 (additive: set_value family). Dependents pinning an exact version (aimdb-sync, aimdb-wasm- adapter, aimdb-websocket-connector -> data-contracts; aimdb-core, aimdb-data-contracts -> aimdb-derive) updated to match; aimdb-core's own 0.x-style dependents needed no change (^1.1.0 already permits 1.2.0). Verified: `make check` and `make build` green in aimdb; `make check`/`make all` green in aimdb-pro against the bumped versions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(review): SignalStatsInfo serde symmetry, live hub gauge, gamma fmt Review follow-ups on the design 041 implementation: - SignalStatsInfo.unit: add #[serde(default)] to match its skip_serializing_if. Observable::UNIT defaults to "", so a gauge without a unit serialized record.list/record.get JSON that aimdb-client/aimdb-mcp (built with observability) could not deserialize back (missing field `unit`). Regression test added. - weather-hub: enable aimdb-tokio-adapter/observability so .observe() gets a live gauge instead of the inert handle — the demo now actually surfaces signal stats on record.list/record.get as its comments and design 041 §6 claim. - weather-station-gamma: rustfmt the non-sim read_temperature signature (make fmt-check was failing). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017sJzkN61UVQboWuHVHwSKP * ci: make check-no-sim fail closed + tracer positive control The guard treated ANY non-zero 'cargo tree -i rand' exit as 'rand is absent'. An unrelated cargo failure — missing _external submodules, a typo'd package in SIM_EXAMPLES, registry trouble — therefore passed the check vacuously (observed: with submodules uninitialized, all four assertions 'passed' while cargo was erroring on embassy-executor). Now 'rand-free' is accepted only when cargo tree fails with its specific 'did not match any packages' error; any other failure aborts the check and prints cargo's output. A positive control per example additionally asserts the '--features sim' graph DOES find rand, so a silently broken tracer (e.g. rand dropped from the simulatable feature) can no longer turn the whole guard into a no-op. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017sJzkN61UVQboWuHVHwSKP --------- Co-authored-by: Claude <noreply@anthropic.com>
- Updated comments in `linkable.rs`, `observable.rs`, and `simulatable.rs` to improve clarity and remove references to design documents. - Enhanced documentation in `lib.rs` of `aimdb-derive` to clarify the derive functionality for `Linkable`. - Revised comments in `Cargo.toml` files across various examples to remove design references and improve readability. - Adjusted comments in `producer.rs` and integration tests to clarify the functionality of `SyncProducer` and its methods. - Updated design documentation to reflect changes in the implementation and clarify the purpose of various traits and features. - Removed unnecessary design references in example projects to streamline the documentation and focus on functionality.
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.
Data contracts as first-class capabilities
Reshapes AimDB's capability traits (
Simulatable,Observable,Linkable,Settable) so each unlocks exactly one registrar verb, tiered by deployment role (wire/prod vs. dev-only).Breaking changes
Simulatable:simulate(config: &SimulationConfig, ...)→simulate(params: &Self::Params, ...).SimulationConfig/SimulationParamsremoved in favor ofSimProfile<P>+RandomWalkParams. No more runtimeenabledgate — sim vs. real is a compile-time#[cfg].Observable: dropsICON/format_log(); now numeric-projection only (Signal,SIGNAL,UNIT,signal()). Presentation moved toObservableRegistrarExt::log(node_id).Settable: moved behind a newsettablefeature (was unconditional).migratable: no longer requiresstd(nowalloc-only).Added
SimulatableRegistrarExt::simulate(profile, rng)— installs a.source()emitting synthetic samples on a timer.make check-no-sim(new CI step) provesrandnever reaches a production build.ObservableRegistrarExt::observe()— feedsT::signal()into a new coreRecordRegistrar::signal_gauge, surfaced as live last/min/max/mean onrecord.list/record.get.LinkableRegistrarExt::linked_from(url)/linked_to(url)— one-line link wiring defaulted toT::from_bytes/to_bytes; plus#[derive(Linkable)]for JSON wire types.SyncProducer<T: Settable>::set_value/try_set_value/set_value_at— construct-and-send by primitive value instead of a hand-builtT.Docs & examples
docs/design/041-data-contracts-integration.md.weather-mesh-demoandmqtt-connector-demoexamples migrated to the new trait shapes.aimdb-core(1.2.0) andaimdb-sync(0.6.0).Verification
aimdb-data-contracts/tests/linkable_derive.rs,aimdb-sync/tests/settable_integration.rs, plus unit tests for the reshaped traits.make check-no-simadded to CI (.github/workflows/ci.yml).