Skip to content

Initial Rust API design for diag-lib#1

Open
stmuench wants to merge 4 commits into
eclipse-score:mainfrom
stmuench:initial_rust_api_design_for_diag_lib
Open

Initial Rust API design for diag-lib#1
stmuench wants to merge 4 commits into
eclipse-score:mainfrom
stmuench:initial_rust_api_design_for_diag_lib

Conversation

@stmuench
Copy link
Copy Markdown
Contributor

@stmuench stmuench commented Apr 10, 2026

Summary

This PR documents the intended Rust-based API surface, explains how consumers are expected to implement and register diagnostic resources/operations, and adds a PlantUML class diagram to visualize the design.

A working implementation of this API Design, including a runtime-backed example implementation and usage snippets which are demonstrating how to use the API in practice, can be found in #2.

Changes

  • Adds the initial Rust diagnostics API documentation and supporting design diagram for score/mw/diag/api.
  • Also adds a comprehensive README.md covering:
    • common payload and error types
    • API structure and protocol views (sovd and uds)
    • implementation patterns for data resources and operations
    • adapter usage for bridging UDS-oriented implementations into the runtime-facing API
    • end-to-end usage examples and guidance

Why

The new documentation gives consumers of the diagnostics library a clearer entry point for the planned Rust API and provides a shared design reference for further implementation and review.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 10, 2026

License Check Results

🚀 The license check job ran with the Bazel command:

bazel run //:license-check

Status: ⚠️ Needs Review

Click to expand output
[License Check Output]
2026/05/28 13:08:15 Downloading https://releases.bazel.build/8.3.0/release/bazel-8.3.0-linux-x86_64...
Extracting Bazel installation...
Starting local Bazel server (8.3.0) and connecting to it...
INFO: Invocation ID: 4d19c0e8-123b-4069-b1f0-ad16e6158ddf
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Loading: 
Loading: 0 packages loaded
Loading: 0 packages loaded
Loading: 0 packages loaded
    currently loading: 
Loading: 0 packages loaded
    currently loading: 
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)

Analyzing: target //:license-check (61 packages loaded, 9 targets configured)

Analyzing: target //:license-check (71 packages loaded, 9 targets configured)

Analyzing: target //:license-check (77 packages loaded, 9 targets configured)

Analyzing: target //:license-check (134 packages loaded, 2073 targets configured)

Analyzing: target //:license-check (138 packages loaded, 2443 targets configured)

Analyzing: target //:license-check (138 packages loaded, 2443 targets configured)

Analyzing: target //:license-check (146 packages loaded, 4479 targets configured)

Analyzing: target //:license-check (146 packages loaded, 4479 targets configured)

Analyzing: target //:license-check (147 packages loaded, 4603 targets configured)

Analyzing: target //:license-check (148 packages loaded, 4723 targets configured)

Analyzing: target //:license-check (148 packages loaded, 4723 targets configured)

Analyzing: target //:license-check (148 packages loaded, 4723 targets configured)

Analyzing: target //:license-check (148 packages loaded, 4723 targets configured)

Analyzing: target //:license-check (148 packages loaded, 4723 targets configured)

Analyzing: target //:license-check (148 packages loaded, 4723 targets configured)

Analyzing: target //:license-check (148 packages loaded, 4723 targets configured)

Analyzing: target //:license-check (148 packages loaded, 4723 targets configured)

Analyzing: target //:license-check (148 packages loaded, 4723 targets configured)

Analyzing: target //:license-check (148 packages loaded, 4723 targets configured)

INFO: Analyzed target //:license-check (149 packages loaded, 6658 targets configured).
[8 / 13] JavaToolchainCompileClasses external/rules_java+/toolchains/platformclasspath_classes; 0s disk-cache, processwrapper-sandbox
INFO: From Generating Dash formatted dependency file ...:
INFO: Successfully converted 2 packages from Cargo.lock to bazel-out/k8-fastbuild/bin/formatted.txt
[11 / 13] JavaToolchainCompileBootClasspath external/rules_java+/toolchains/platformclasspath.jar; 0s disk-cache, processwrapper-sandbox
INFO: Found 1 target...
Target //:license.check.license_check up-to-date:
  bazel-bin/license.check.license_check
  bazel-bin/license.check.license_check.jar
INFO: Elapsed time: 153.245s, Critical Path: 2.39s
INFO: 13 processes: 9 internal, 3 processwrapper-sandbox, 1 worker.
INFO: Build completed successfully, 13 total actions
INFO: Running command line: bazel-bin/license.check.license_check ./formatted.txt <args omitted>
usage: org.eclipse.dash.licenses.cli.Main [-batch <int>] [-cd <url>]
       [-confidence <int>] [-ef <url>] [-excludeSources <sources>] [-help] [-lic
       <url>] [-project <shortname>] [-repo <url>] [-review] [-summary <file>]
       [-timeout <seconds>] [-token <token>]

@github-actions
Copy link
Copy Markdown

The created documentation from the pull request is available at: docu-html

Comment thread score/mw/diag/design/diag_api_rust.puml
Comment thread score/mw/diag/design/diag_api_rust.puml
@stmuench stmuench force-pushed the initial_rust_api_design_for_diag_lib branch from 57765c7 to d401cd8 Compare April 13, 2026 08:56
Comment thread score/mw/diag/design/diag_api_rust.puml
@floroks
Copy link
Copy Markdown

floroks commented Apr 13, 2026

general question: are there plans on how to support future sovd-api versions? would it make sense to version the apis?

@stmuench
Copy link
Copy Markdown
Contributor Author

general question: are there plans on how to support future sovd-api versions? would it make sense to version the apis?

Not yet. But yes, it might definitely make sense to use versioned modules such as v1, v2, etc and put the types into these modules then.

@stmuench stmuench force-pushed the initial_rust_api_design_for_diag_lib branch from d401cd8 to 6d2967e Compare April 13, 2026 11:53
Comment thread score/mw/diag/api/README.md Outdated
fn read(&self, _input: ReadValueArgs) -> DiagResult<ReadValueReply> {
Ok(ReadValueReply {
id: Some("feature_flag".to_string()),
data: ReplyMessagePayload::from_string(self.enabled.to_string()),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should support deserialization of data so the WriteableFlag could use e.g. serde and we could pass the value itself and not dealing with deserialization manually.

Copy link
Copy Markdown
Contributor Author

@stmuench stmuench Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to add json serialization as well as deserialization later on top of this design as separate features

Comment thread score/mw/diag/api/README.md Outdated
Comment thread score/mw/diag/api/README.md
The public entry point is the diag_api crate from within the [api](../api/) directory.
It re-exports the common types and groups the user-facing APIs into two main protocol views:

- `diag_api::sovd` for SOVD-oriented data resources and operations
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the design doc we named it diag_lib complementary to fault_lib. I would be consistent so lets align which naming convention to chose. We can discuss this in the next call.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my POV, diag_lib is the set of API + respective particular implementation. Since there can (and most likely also will) be different implementations of the API, I would like to keep these two parts separated. Hence, I deliberately used diag_lib here as name for the crate.

Comment thread score/mw/diag/api/README.md
Comment thread score/mw/diag/api/README.md Outdated
Comment thread score/mw/diag/design/diag_api_rust.puml Outdated
Comment thread score/mw/diag/design/diag_api_rust.puml Outdated
Comment thread score/mw/diag/design/diag_api_rust.puml Outdated
@lh-sag
Copy link
Copy Markdown

lh-sag commented Apr 14, 2026

@stmuench please run rust doc on the readme to avoid typos and not compilable code. I noticed a couple of typos and this is taking time during reviews.

serde_json::Value
}

class JsonSchema <<alias>> {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JsonSchema and JsonValue are both aliases for serde_json::Value. One should be newtype.

Comment thread score/mw/diag/design/diag_api_rust.puml Outdated
nhuvaoanh123 added a commit to nhuvaoanh123/taktflow-opensovd that referenced this pull request Apr 21, 2026
…n 1.0

Part II Draft 1.0:

- §II.6.17 PROD-17 scope reduced from build to absorb-when-ready after
  confirming eclipse-score/inc_diagnostics#1+#2 is the live upstream
  home (repo last push 2026-04-16). Build outputs retired; replaced
  with quarterly watch report and three named revisit triggers
  (upstream graduates / OEM deadline / upstream stalls). Implementation
  returns via new capability PROD-17B only if triggers fire. Saves
  8-12 engineer-weeks while preserving the strategic option.

- §II.6.20 PROD-20 UDS->SOVD ingress proxy added. Audit 2026-04-21
  found both our vendored uds2sovd-proxy/ and upstream are empty
  scaffolds (zero .rs files, ~6 months stale). Five sub-deliverables
  covering design ADR, proxy crate, gateway wiring, integration tests,
  bench fixture. 5-8 engineer-week estimate. Role clarifier added
  stating no S-CORE equivalent exists, so Taktflow authoring is
  unavoidable (distinguishes from PROD-17 absorb posture).

- §II.6.15 PROD-15 per-workstream cadence table: diag-lib Rust API and
  UDS2SOVD<->ServiceApps design both quarterly; returns to monthly on
  observed upstream activity. Basis cited with dates and URLs only
  (2026-03-24 + 2026-03-31 meetings skipped per public minutes;
  uds2sovd-proxy zero source commits since 2025-10-14).

- §II.6.16 PROD-16 revised — Role + Constraints softened to reflect
  active upstream tracking, not "reference only"; 16.1/16.2 path names
  corrected after discovering the "FaultShim" contract ships as the
  AUTOSAR Dem module in embedded-production. Added 16.5 (richer
  FaultId) and 16.6 (extern "C" on Dem.h, cross-repo tracking).

- §II.12 chase-list row 17 added (UDS->SOVD ingress proxy -> PROD-20).

- Part I §1.3 exclusion clarified from "upstream contribution" to
  "upstream code contribution" + positive scope statement that design
  absorption is in scope.

- Part I §7.11.1 P10-SCA-A1 marked superseded by PROD-20 after audit
  found crate is empty scaffold; acceptance criteria moved into
  PROD-20 Verification.

- Part I S-CORE alignment table fault-lib row: "aligned; no action"
  -> "aligned; upstream direction actively tracked" with pointer to
  PROD-16.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread score/mw/diag/api/README.md Outdated
.put(current_status, ExecutionStatusDetails::none());
}
_ => {
let mut last_exec_event_kind = exec_event.kind;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let mut last_exec_event_kind = exec_event.kind;
last_exec_event_kind = exec_event.kind;

@IoanAndrasi
Copy link
Copy Markdown

I see that from the application point of view there is no registration/deregistration, no heartbeat or topology onboarding, is this in scope or ?

@stmuench
Copy link
Copy Markdown
Contributor Author

stmuench commented May 8, 2026

I see that from the application point of view there is no registration/deregistration, no heartbeat or topology onboarding, is this in scope or ?

Idea was to add such APIs later incrementally on top of this PR in order to keep the complexity of this PR reasonable

@IoanAndrasi
Copy link
Copy Markdown

Idea was to add such APIs later incrementally on top of this PR in order to keep the complexity of this PR reasonable

I see, thanks for fast response, do you have like a plan when this PR will be merged and then when will register/deregister will be live also onboarding of topology?

The reason I ask this, is because opensovd-core is relying on this feature to be able to integrate hpc apps.

Copy link
Copy Markdown

@bharatGoswami8 bharatGoswami8 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

general suggestions

Comment thread score/mw/diag/design/diag_api_rust.puml
Comment thread score/mw/diag/design/diag_api_rust.puml Outdated
+{static} from_code_with_translation(code: ErrorCode, message: String, translation_id: String) : Self
+{static} from_vendor_error(error: String, message: String) : Self
+{static} from_vendor_error_with_translation(error: String, message: String, translation_id: String) : Self
+add_additional_attr(key: String, value: String)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about creating a pub type which will have key and value as field, if not then i suggest here use a newType so user cannot pass value wrongly.

Comment thread score/mw/diag/design/diag_api_rust.puml Outdated
@stmuench stmuench force-pushed the initial_rust_api_design_for_diag_lib branch from 88da1f8 to 22b1ca3 Compare May 28, 2026 13:08
Comment on lines +79 to +82
- **Ready**: `from_error(err)` — error available immediately
- **Ready**: `ready(reply)` / `ready()` — result available immediately
- **Pending**: `from_future(async move { ... })` — returns a future to await
- **Pending**: `from_closure(|| { ... })` — wraps a synchronous closure in an async handle that returns the result directly
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Ready**: `from_error(err)` — error available immediately
- **Ready**: `ready(reply)` / `ready()` — result available immediately
- **Pending**: `from_future(async move { ... })` — returns a future to await
- **Pending**: `from_closure(|| { ... })` — wraps a synchronous closure in an async handle that returns the result directly
1. Ready
....
2. Pending
....

+proximity_response : Option<String>
}

enum ExecutionStatus <<enum>> {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you want to consider Cancel status as separate or it is part of stopped ?

interface RoutineControl <<trait>> {
+start(input: Option<ByteSlice>) : DiagResult<StartRoutine>
+stop(input: Option<ByteSlice>) : DiagResult<Option<ByteVector>>
+completion_percentage() : Option<u8>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
+completion_percentage() : Option<u8>
+completion_status() : Option<u8>

I feel API documentation can give return type is percentage rather than API naming, or may be return tuple (bool, u8) if needed.

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.

6 participants