Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Remote access via connectors — Phases 0–6: converge four hand-rolled networking stacks onto two shared engines (Issue #39, [design doc](docs/design/remote-access-via-connectors.md)).** AimX remote access (and any future transport) now rides the connector layer instead of a bespoke I/O abstraction. New, runtime-neutral `aimdb-core::session` module (feature `connector-session`, `no_std + alloc`): the three-layer substrate (`Connection`/`Listener`/`Dialer` + `EnvelopeCodec` + `Dispatch`/`Session`), the reactive **server** engine (`serve`/`run_session`) and proactive **client** engine (`run_client`/`pump_client`), the `pump_sink`/`pump_source` data-plane toolkit, and the transport-agnostic `SessionClientConnector`/`SessionServerConnector`. The AimX-v2 NDJSON protocol (`session::aimx`: `AimxCodec` + `AimxDispatch`) and the WebSocket connector are ports onto this substrate, so the AimX server/client and WS server/client stacks collapse onto the two engines. New **`aimdb-uds-connector`** crate carries the UDS transport (`UdsClient`/`UdsServer`). ([aimdb-core](aimdb-core/CHANGELOG.md), [aimdb-uds-connector](aimdb-uds-connector/CHANGELOG.md), [aimdb-websocket-connector](aimdb-websocket-connector/CHANGELOG.md), [aimdb-client](aimdb-client/CHANGELOG.md), [aimdb-mqtt-connector](aimdb-mqtt-connector/CHANGELOG.md), [aimdb-knx-connector](aimdb-knx-connector/CHANGELOG.md), [aimdb-embassy-adapter](aimdb-embassy-adapter/CHANGELOG.md))
- **M16 — JSON codec extracted behind the `json-serialize` feature; `RecordValue::as_json()` now works on `no_std + alloc`, not just `std` ([Design 032](docs/design/032-M16-aimx-json-codec.md)).** New `aimdb-core::codec` module: `RemoteSerialize` (blanket-impl'd for every `serde` `Serialize + DeserializeOwned` type), the object-safe `JsonCodec<T>`, and the zero-sized `SerdeJsonCodec`. `serde_json` runs on `alloc`, so embedded targets can opt in; `std` enables the feature transitively, so std builds are unaffected. ([aimdb-core](aimdb-core/CHANGELOG.md))
- **Embassy buffer + join-queue tests now run in CI (Issue #85).** The join-queue tests previously sat behind `embassy-runtime`, which pulls `embassy-executor`'s cortex-m assembly and can't compile under `cargo test` on x86_64 — so ordering / backpressure / clone-routing regressions were never caught. The `join_queue` module is now gated on `embassy-sync`, and `make test` runs the embassy adapter's unit tests + doctests on the host (no executor). Also adds `EmbassyBuffer::peek()` and fixes a stale `EmbassyBuffer` doc example. ([aimdb-embassy-adapter](aimdb-embassy-adapter/CHANGELOG.md))
- **`no_std` AimX server — a board can serve a host, not just dial one (Issue #120, follow-up to #39).** Cross-cutting de-std of `aimdb-core`'s central record API behind a new **`remote-access`** feature (`= ["json-serialize", "thiserror"]`, transitively enabled by `std`): the type-erased `AnyRecord` JSON + metadata methods, the `AimDb` JSON read/write/subscribe API, the `remote` module (config / protocol / security / error), and the AimX server dispatch (`AimxDispatch`/`AimxSession`) now all compile on `no_std + alloc` — swapping `std::collections` → `hashbrown`, `std::sync::Arc` → `alloc::sync::Arc`, and `thiserror` to `default-features = false`. Adds a runtime-neutral wall clock, `TimeOps::unix_time()`, implemented from the OS clock on Tokio and from an `EmbassyAdapter::set_unix_time(...)` anchor on Embassy. Verified by a new `thumbv7em-none-eabihf` dispatch cross-check in the Makefile. ([aimdb-core](aimdb-core/CHANGELOG.md), [aimdb-executor](aimdb-executor/CHANGELOG.md), [aimdb-tokio-adapter](aimdb-tokio-adapter/CHANGELOG.md), [aimdb-embassy-adapter](aimdb-embassy-adapter/CHANGELOG.md), [aimdb-uds-connector](aimdb-uds-connector/CHANGELOG.md), [tools/aimdb-mcp](tools/aimdb-mcp/CHANGELOG.md))

### Changed (breaking)

- **`AimDbBuilder::with_remote_access(config)` removed — remote-access servers are now registered like any other connector (Issue #39).** Replace `.with_remote_access(config)` with `.with_connector(aimdb_uds_connector::UdsServer::from_config(config))`. The AimX wire was reshaped to **v2** (NDJSON tagged frames mapping onto the engine's role-neutral message set) and is **not** backward-compatible with the legacy AimX v1 framing; the bundled `aimdb-client` / CLI / MCP speak v2. The UDS transport types moved out of `aimdb-core` into `aimdb-uds-connector`. ([aimdb-core](aimdb-core/CHANGELOG.md), [aimdb-uds-connector](aimdb-uds-connector/CHANGELOG.md), [aimdb-client](aimdb-client/CHANGELOG.md))
- **M15 — `latest_snapshot` removed; point-in-time reads go through the new buffer-native `DynBuffer::peek()` ([Design 031](docs/design/031-M15-remove-latest-snapshot.md)).** `TypedRecord::latest()` and AimX `record.get` read the buffer directly instead of a per-record snapshot mutex (one lock + clone off the `produce()` hot path). Consequences: a `.with_remote_access()` record with **no buffer** now fails `build()` (was a silent runtime no-op); `record.get` / `latest()` on an `SpmcRing` record returns `not_found` / `None` (rings have no canonical latest — use `record.drain` / `record.subscribe`); `SingleLatest` and `Mailbox` are unaffected. `TypedRecord::produce` is removed — all writes go through `WriteHandle::push`. Adapters implement `peek()` per buffer type. ([aimdb-core](aimdb-core/CHANGELOG.md), [aimdb-tokio-adapter](aimdb-tokio-adapter/CHANGELOG.md), [aimdb-embassy-adapter](aimdb-embassy-adapter/CHANGELOG.md), [aimdb-wasm-adapter](aimdb-wasm-adapter/CHANGELOG.md))
- **M16 — `with_remote_access()` now requires the `json-serialize` feature (transitively enabled by `std`); `with_read_only_serialization()` removed ([Design 032](docs/design/032-M16-aimx-json-codec.md)).** The stored serializer/deserializer closures are replaced by a type-erased `Arc<dyn JsonCodec<T>>`. A `Serialize`-only record can no longer be exposed read-only over remote access. ([aimdb-core](aimdb-core/CHANGELOG.md))
- **`RecordMetadata` drops `created_at` / `last_update`; `AimxConfig.socket_path` is now `String` (Issue #120).** Core stopped keeping per-record timestamp state for the `no_std` AimX server (the `Mutex`-+-`SystemTime` `RecordMetadataTracker` is deleted), so AimX `record.list` and the MCP `list_records` / schema outputs no longer include the two timestamp fields. `RecordMetadata::new` drops its `created_at` parameter. `AimxConfig::socket_path` / `UdsServer::new` take `impl Into<String>` instead of `impl Into<PathBuf>` (`&Path` / `PathBuf` callers must convert). ([aimdb-core](aimdb-core/CHANGELOG.md), [aimdb-uds-connector](aimdb-uds-connector/CHANGELOG.md), [tools/aimdb-mcp](tools/aimdb-mcp/CHANGELOG.md))

- **M13 — `Spawn` trait removed across the workspace; `AimDbBuilder::build()` now returns `(AimDb, AimDbRunner)` (Issue #88, [Design 028](docs/design/028-M13-remove-spawn-trait.md)).** Every future the database drives — producer services, taps, transforms, join forwarders, connector loops, the remote-access supervisor, `on_start` tasks — is collected at build time and driven by a single `FuturesUnordered` inside `runner.run().await`. Adapter implementations (`TokioAdapter`, `EmbassyAdapter`, `WasmAdapter`) drop their `impl Spawn`. The `embassy-task-pool-8/16/32` features are deleted and `EmbassyAdapter::new_with_network` no longer takes a `Spawner`. Connector authors must update `ConnectorBuilder::build()` to return `Vec<BoxFuture>` instead of `Arc<dyn Connector>`. See each crate's CHANGELOG for the per-crate impact.

Expand Down
16 changes: 12 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,10 @@ test:
cargo test --package aimdb-core --no-default-features --features "alloc,profiling"
@printf "$(YELLOW) → Testing aimdb-core (no_std + alloc + metrics)$(NC)\n"
cargo test --package aimdb-core --no-default-features --features "alloc,metrics"
@printf "$(YELLOW) → Testing aimdb-core (no_std + alloc + json-serialize)$(NC)\n"
@printf "$(YELLOW) → Testing aimdb-core (no_std + alloc + json-serialize value codec)$(NC)\n"
cargo test --package aimdb-core --no-default-features --features "alloc,json-serialize"
@printf "$(YELLOW) → Testing aimdb-core (no_std + alloc + remote-access data model)$(NC)\n"
cargo test --package aimdb-core --no-default-features --features "alloc,remote-access"
@printf "$(YELLOW) → Testing aimdb-core remote module$(NC)\n"
cargo test --package aimdb-core --lib --features "std" remote::
@printf "$(YELLOW) → Testing aimdb-core connector-session (contracts object-safety)$(NC)\n"
Expand Down Expand Up @@ -198,8 +200,10 @@ clippy:
cargo clippy --package aimdb-data-contracts --no-default-features --features alloc -- -D warnings
@printf "$(YELLOW) → Clippy on aimdb-core (no_std + alloc)$(NC)\n"
cargo clippy --package aimdb-core --no-default-features --features alloc --all-targets -- -D warnings
@printf "$(YELLOW) → Clippy on aimdb-core (no_std + alloc + json-serialize)$(NC)\n"
@printf "$(YELLOW) → Clippy on aimdb-core (no_std + alloc + json-serialize value codec)$(NC)\n"
cargo clippy --package aimdb-core --no-default-features --features "alloc,json-serialize" --all-targets -- -D warnings
@printf "$(YELLOW) → Clippy on aimdb-core (no_std + alloc + remote-access data model)$(NC)\n"
cargo clippy --package aimdb-core --no-default-features --features "alloc,remote-access" --all-targets -- -D warnings
@printf "$(YELLOW) → Clippy on aimdb-core (std)$(NC)\n"
cargo clippy --package aimdb-core --features "std,tracing,metrics" --all-targets -- -D warnings
@printf "$(YELLOW) → Clippy on tokio adapter$(NC)\n"
Expand Down Expand Up @@ -294,12 +298,16 @@ test-embedded:
cargo check --package aimdb-data-contracts --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features alloc
@printf "$(YELLOW) → Checking aimdb-core (no_std minimal) on thumbv7em-none-eabihf target$(NC)\n"
cargo check --package aimdb-core --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features alloc
@printf "$(YELLOW) → Checking aimdb-core (no_std + alloc + json-serialize) on thumbv7em-none-eabihf target$(NC)\n"
@printf "$(YELLOW) → Checking aimdb-core (no_std + alloc + json-serialize value codec) on thumbv7em-none-eabihf target$(NC)\n"
cargo check --package aimdb-core --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features "alloc,json-serialize"
@printf "$(YELLOW) → Checking aimdb-core (no_std + alloc + remote-access data model) on thumbv7em-none-eabihf target$(NC)\n"
cargo check --package aimdb-core --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features "alloc,remote-access"
@printf "$(YELLOW) → Checking aimdb-core session engines (no_std + connector-session) on thumbv7em-none-eabihf target$(NC)\n"
cargo check --package aimdb-core --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features "alloc,connector-session"
@printf "$(YELLOW) → Checking aimdb-core AimX codec (no_std + connector-session + json-serialize) on thumbv7em-none-eabihf target$(NC)\n"
@printf "$(YELLOW) → Checking aimdb-core AimX codec (no_std client path: connector-session + json-serialize) on thumbv7em-none-eabihf target$(NC)\n"
cargo check --package aimdb-core --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features "alloc,connector-session,json-serialize"
@printf "$(YELLOW) → Checking aimdb-core AimX codec + dispatch (full no_std AimX server: connector-session + remote-access) on thumbv7em-none-eabihf target$(NC)\n"
cargo check --package aimdb-core --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features "alloc,connector-session,remote-access"
@printf "$(YELLOW) → Checking aimdb-core (no_std/embassy) on thumbv7em-none-eabihf target$(NC)\n"
cargo check --package aimdb-core --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features alloc
@printf "$(YELLOW) → Checking aimdb-embassy-adapter on thumbv7em-none-eabihf target$(NC)\n"
Expand Down
4 changes: 2 additions & 2 deletions aimdb-client/tests/aimx_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ async fn aimx_roundtrip_over_uds_production_server() {
let mut policy = SecurityPolicy::read_write();
policy.allow_write_key("setting");
let config = AimxConfig::uds_default()
.socket_path(&sock)
.socket_path(sock.to_str().unwrap())
.security_policy(policy)
.max_connections(8)
.max_subs_per_connection(8);
Expand Down Expand Up @@ -144,7 +144,7 @@ async fn record_get_on_ring_falls_back_to_drain() {
let dir = tempfile::tempdir().unwrap();
let sock = dir.path().join("aimdb.sock");

let config = AimxConfig::uds_default().socket_path(&sock);
let config = AimxConfig::uds_default().socket_path(sock.to_str().unwrap());
let mut builder = AimDbBuilder::new()
.runtime(Arc::new(TokioAdapter))
.with_connector(UdsServer::from_config(config));
Expand Down
2 changes: 1 addition & 1 deletion aimdb-client/tests/pump_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ async fn pump_client_mirrors_record_both_directions() {
let mut policy = SecurityPolicy::read_write();
policy.allow_write_key("cfg");
let config = AimxConfig::uds_default()
.socket_path(&sock)
.socket_path(sock.to_str().unwrap())
.security_policy(policy);

let mut sb = AimDbBuilder::new()
Expand Down
Loading