feat(proto): add nuncio-proto gRPC contract crate (System.GetStatus skeleton)

New crate crates/nuncio-proto houses the versioned protobuf contract
(proto/nuncio/v1) and tonic-generated client+server stubs, starting with a
minimal System.GetStatus RPC. protoc is vendored via protoc-bin-vendored
(prebuilt binaries; no system protoc, cmake, or C++ toolchain) for reproducible
CI on Linux/macOS/Windows. Uses the tonic 0.14 split (tonic + tonic-prost
runtime, tonic-prost-build codegen). Generated code exempted from workspace
lints; hand-written code keeps them.

Refs #148
This commit is contained in:
James Maes committed 2026-07-26 21:14:55 -05:00
1 parent 7c0465cf35
commit 1b58ec187e
6 files changed
+479

No files matched your search

Generated
+330
View File
@@ -160,6 +160,12 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "anyhow"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]]
name = "ar_archive_writer"
version = "0.5.2"
@@ -447,6 +453,49 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "axum"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90"
dependencies = [
"axum-core",
"bytes",
"futures-util",
"http",
"http-body",
"http-body-util",
"itoa",
"matchit",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"serde_core",
"sync_wrapper",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "axum-core"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
dependencies = [
"bytes",
"futures-core",
"http",
"http-body",
"http-body-util",
"mime",
"pin-project-lite",
"sync_wrapper",
"tower-layer",
"tower-service",
]
[[package]]
name = "base64"
version = "0.21.7"
@@ -1172,6 +1221,12 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "fixedbitset"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
[[package]]
name = "flate2"
version = "1.1.9"
@@ -1633,6 +1688,19 @@ dependencies = [
"webpki-roots",
]
[[package]]
name = "hyper-timeout"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"
dependencies = [
"hyper",
"hyper-util",
"pin-project-lite",
"tokio",
"tower-service",
]
[[package]]
name = "hyper-util"
version = "0.1.20"
@@ -1959,6 +2027,15 @@ dependencies = [
"nom 8.0.0",
]
[[package]]
name = "itertools"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.18"
@@ -2135,6 +2212,12 @@ dependencies = [
"encoding_rs",
]
[[package]]
name = "matchit"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
[[package]]
name = "md-5"
version = "0.10.6"
@@ -2212,6 +2295,12 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "multimap"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
[[package]]
name = "nix"
version = "0.26.4"
@@ -2484,6 +2573,17 @@ dependencies = [
"wiremock",
]
[[package]]
name = "nuncio-proto"
version = "0.1.0"
dependencies = [
"prost",
"protoc-bin-vendored",
"tonic",
"tonic-prost",
"tonic-prost-build",
]
[[package]]
name = "nuncio-store"
version = "0.1.0"
@@ -2627,6 +2727,17 @@ version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "petgraph"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455"
dependencies = [
"fixedbitset",
"hashbrown 0.15.5",
"indexmap",
]
[[package]]
name = "phf"
version = "0.11.3"
@@ -2831,6 +2942,16 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "prettyplease"
version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
"syn 2.0.119",
]
[[package]]
name = "proc-macro-crate"
version = "1.3.1"
@@ -2874,6 +2995,123 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "prost"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1"
dependencies = [
"bytes",
"prost-derive",
]
[[package]]
name = "prost-build"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042"
dependencies = [
"heck",
"itertools",
"log",
"multimap",
"petgraph",
"prettyplease",
"prost",
"prost-types",
"pulldown-cmark",
"pulldown-cmark-to-cmark",
"regex",
"syn 2.0.119",
"tempfile",
]
[[package]]
name = "prost-derive"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf"
dependencies = [
"anyhow",
"itertools",
"proc-macro2",
"quote",
"syn 2.0.119",
]
[[package]]
name = "prost-types"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a"
dependencies = [
"prost",
]
[[package]]
name = "protoc-bin-vendored"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1c381df33c98266b5f08186583660090a4ffa0889e76c7e9a5e175f645a67fa"
dependencies = [
"protoc-bin-vendored-linux-aarch_64",
"protoc-bin-vendored-linux-ppcle_64",
"protoc-bin-vendored-linux-s390_64",
"protoc-bin-vendored-linux-x86_32",
"protoc-bin-vendored-linux-x86_64",
"protoc-bin-vendored-macos-aarch_64",
"protoc-bin-vendored-macos-x86_64",
"protoc-bin-vendored-win32",
]
[[package]]
name = "protoc-bin-vendored-linux-aarch_64"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c350df4d49b5b9e3ca79f7e646fde2377b199e13cfa87320308397e1f37e1a4c"
[[package]]
name = "protoc-bin-vendored-linux-ppcle_64"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a55a63e6c7244f19b5c6393f025017eb5d793fd5467823a099740a7a4222440c"
[[package]]
name = "protoc-bin-vendored-linux-s390_64"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dba5565db4288e935d5330a07c264a4ee8e4a5b4a4e6f4e83fad824cc32f3b0"
[[package]]
name = "protoc-bin-vendored-linux-x86_32"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8854774b24ee28b7868cd71dccaae8e02a2365e67a4a87a6cd11ee6cdbdf9cf5"
[[package]]
name = "protoc-bin-vendored-linux-x86_64"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b38b07546580df720fa464ce124c4b03630a6fb83e05c336fea2a241df7e5d78"
[[package]]
name = "protoc-bin-vendored-macos-aarch_64"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89278a9926ce312e51f1d999fee8825d324d603213344a9a706daa009f1d8092"
[[package]]
name = "protoc-bin-vendored-macos-x86_64"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81745feda7ccfb9471d7a4de888f0652e806d5795b61480605d4943176299756"
[[package]]
name = "protoc-bin-vendored-win32"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95067976aca6421a523e491fce939a3e65249bac4b977adee0ee9771568e8aa3"
[[package]]
name = "psm"
version = "0.1.31"
@@ -2884,6 +3122,26 @@ dependencies = [
"cc",
]
[[package]]
name = "pulldown-cmark"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e"
dependencies = [
"bitflags 2.13.1",
"memchr",
"unicase",
]
[[package]]
name = "pulldown-cmark-to-cmark"
version = "22.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50793def1b900256624a709439404384204a5dc3a6ec580281bfaac35e882e90"
dependencies = [
"pulldown-cmark",
]
[[package]]
name = "quick-xml"
version = "0.41.0"
@@ -4158,6 +4416,74 @@ dependencies = [
"winnow",
]
[[package]]
name = "tonic"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef"
dependencies = [
"async-trait",
"axum",
"base64 0.22.1",
"bytes",
"h2",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-timeout",
"hyper-util",
"percent-encoding",
"pin-project",
"socket2 0.6.5",
"sync_wrapper",
"tokio",
"tokio-stream",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tonic-build"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c68f61875ac5293cf72e6c8cf0158086428c82c37229e98c840878f1706b0322"
dependencies = [
"prettyplease",
"proc-macro2",
"quote",
"syn 2.0.119",
]
[[package]]
name = "tonic-prost"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0"
dependencies = [
"bytes",
"prost",
"tonic",
]
[[package]]
name = "tonic-prost-build"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "654e5643eff75d7f8c99197ce1440ed19a3474eada74c12bbac488b2cafdae27"
dependencies = [
"prettyplease",
"proc-macro2",
"prost-build",
"prost-types",
"quote",
"syn 2.0.119",
"tempfile",
"tonic-build",
]
[[package]]
name = "tower"
version = "0.5.3"
@@ -4166,11 +4492,15 @@ checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
dependencies = [
"futures-core",
"futures-util",
"indexmap",
"pin-project-lite",
"slab",
"sync_wrapper",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
+6
View File
@@ -9,6 +9,7 @@ members = [
"crates/nunciod",
"crates/nuncio-filter",
"crates/nuncio-contacts",
"crates/nuncio-proto",
]
[workspace.package]
@@ -77,6 +78,11 @@ hex = "0.4"
flate2 = "1.0"
tar = "0.4"
zip = { version = "8.6", default-features = false, features = ["deflate"] }
tonic = "0.14"
tonic-prost = "0.14"
prost = "0.14"
tonic-prost-build = "0.14"
protoc-bin-vendored = "3.2"
+19
View File
@@ -0,0 +1,19 @@
[package]
name = "nuncio-proto"
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
[lints]
workspace = true
[dependencies]
tonic.workspace = true
tonic-prost.workspace = true
prost.workspace = true
[build-dependencies]
tonic-prost-build.workspace = true
protoc-bin-vendored.workspace = true
+39
View File
@@ -0,0 +1,39 @@
//! Build script for `nuncio-proto`.
//!
//! Compiles the versioned protobuf definitions under `proto/nuncio/v1` into
//! Rust client + server stubs via `tonic-prost-build`.
//!
//! `protoc` is vendored via the `protoc-bin-vendored` crate, which bundles
//! prebuilt `protoc` binaries for Linux, macOS, and Windows directly inside
//! the crate. This means the build never depends on a system-installed
//! protobuf compiler being present on PATH, nor on a C/C++ toolchain or
//! `cmake` to build one from source (unlike source-vendoring alternatives
//! such as `protobuf-src`). This is required for reproducible builds in CI
//! across all three platforms (see backlog story 1.A.1 / GH-148).
fn main() {
let protoc_path = match protoc_bin_vendored::protoc_bin_path() {
Ok(path) => path,
Err(err) => {
eprintln!("failed to locate vendored protoc binary: {err}");
std::process::exit(1);
}
};
// Point prost-build at the vendored protoc binary instead of requiring
// one on the host's PATH.
std::env::set_var("PROTOC", protoc_path);
let proto_file = "proto/nuncio/v1/nuncio.proto";
println!("cargo:rerun-if-changed={proto_file}");
if let Err(err) = tonic_prost_build::configure()
.build_client(true)
.build_server(true)
.compile_protos(&[proto_file], &["proto"])
{
eprintln!("failed to compile nuncio.proto: {err}");
std::process::exit(1);
}
}
@@ -0,0 +1,28 @@
syntax = "proto3";
package nuncio.v1;
// System service exposes daemon-level introspection RPCs.
//
// This is the foundation of the versioned gRPC API (see
// docs/adr/0001-engine-first-grpc-architecture.md). Additional services and
// RPCs will be added under the `nuncio.v1` package as later stories land;
// breaking changes will be introduced under a new `nuncio.v2` package rather
// than mutating this one.
service System {
// GetStatus reports basic daemon/engine health information.
rpc GetStatus(GetStatusRequest) returns (GetStatusResponse);
}
// GetStatusRequest currently carries no parameters. Fields may be added
// here in future stories (e.g. requested detail level).
message GetStatusRequest {}
// GetStatusResponse reports the current health and build identity of the
// running nunciod engine.
message GetStatusResponse {
// Human-readable engine status (e.g. "ok", "degraded").
string engine_status = 1;
// The nunciod build/crate version serving this response.
string version = 2;
}
+57
View File
@@ -0,0 +1,57 @@
//! `nuncio-proto`: versioned gRPC/protobuf API definitions for the Nuncio
//! daemon (`nunciod`).
//!
//! This crate holds the `.proto` sources under `proto/nuncio/v1/` and the
//! `tonic`-generated client + server stubs for the `nuncio.v1` package. It is
//! the foundation laid by backlog story 1.A.1 (GH-148): a compiling skeleton
//! with a single minimal `System.GetStatus` RPC. Real server wiring, auth,
//! and business logic are intentionally out of scope here and land in later
//! stories (1.A.2 / 1.A.3).
//!
//! Consumers (e.g. `nunciod`, `nuncio-cli`, and future client repos) should
//! depend on this crate and use the generated client/server types under
//! [`v1`] rather than re-generating protobuf code themselves.
/// Generated code for the `nuncio.v1` protobuf package.
///
/// The generated `prost`/`tonic` code does not conform to this workspace's
/// lint policy (see root `Cargo.toml` `[workspace.lints]`), so this module
/// is exempted from clippy's pedantic/all groups and other lints that only
/// make sense for hand-written code. Hand-written code elsewhere in this
/// crate remains subject to the full workspace lint set via
/// `[lints] workspace = true` in `Cargo.toml`.
#[allow(
clippy::all,
clippy::pedantic,
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
unused_qualifications
)]
pub mod v1 {
tonic::include_proto!("nuncio.v1");
}
#[cfg(test)]
mod tests {
use super::v1::{GetStatusRequest, GetStatusResponse};
#[test]
fn get_status_response_constructs_and_reads_back_fields() {
let response = GetStatusResponse {
engine_status: "ok".to_string(),
version: "0.1.0".to_string(),
};
assert_eq!(response.engine_status, "ok");
assert_eq!(response.version, "0.1.0");
}
#[test]
fn get_status_request_is_constructible() {
// GetStatusRequest currently has no fields; this proves the
// generated type exists and is usable (e.g. as a tonic::Request
// payload) even though it carries no data yet.
let _request = GetStatusRequest {};
}
}