crates/nornir-warehouse-embed/proto/telemetry.proto
// A TRIMMED copy of nornir-server's `Telemetry` submit surface — the
// `SubmitTestResults` + the two BUILD-record methods, and the messages they need.
// Package `nornir.v1` so the generated gRPC method paths
// (`/nornir.v1.Telemetry/SubmitBuildProvenance` …) match the live `nornir-server`
// — dwarves speaks it as a THIN client WITHOUT linking the `nornir` crate (a
// `dwarves → nornir` edge would be a dependency cycle; the `nornir-funnel-embed`
// pattern). Keep the field numbers identical to `nornir.proto` (now carried by the
// edda `nornir-wire` leaf) so the wire is byte-compatible — `tests/proto_drift.rs`
// re-derives that contract and fails on drift.
syntax = "proto3";
package nornir.v1;
// The warehouse-write service (the server holds the redb catalog lock; a thin
// client can't open the Iceberg warehouse to write it — it ships rows here and
// the server appends them).
service Telemetry {
rpc SubmitTestResults (SubmitTestResultsRequest) returns (SubmitCountResponse);
// The NATIVE landing for a dwarves build. Both server handlers have existed
// since the RPCs were declared; until 2026-07-31 NOTHING in the constellation
// called them, which is why `build_provenance` and `build_info` held zero rows
// while every other table filled. See `NornirWarehouseSink::record_build`.
rpc SubmitBuildProvenance (SubmitBuildProvenanceRequest) returns (SubmitCountResponse);
rpc SubmitBuildInfo (SubmitBuildInfoRequest) returns (SubmitCountResponse);
// What a forge's Runa step MEASURED (a test step's outcomes, a bench run, a
// coverage export), filed into the workspace's warehouse keyed by (repo, commit)
// — the facts the Mímir lenses weak_tests / bench_gaps / change_risk read.
rpc SubmitStepFeed (SubmitStepFeedRequest) returns (SubmitCountResponse);
}
// Byte-identical field numbering to nornir.proto `StepTestOutcomePb`.
message StepTestOutcomePb {
string name = 1;
string krate = 2;
string status = 3;
double duration_ms = 4;
bool has_duration = 5;
string message = 6;
}
// Byte-identical field numbering to nornir.proto `SubmitStepFeedRequest`.
message SubmitStepFeedRequest {
string repo = 1;
string commit = 2;
string run_id = 3;
int64 ts_micros = 4;
string kind = 5;
repeated StepTestOutcomePb tests = 6;
string bench_json = 7;
string coverage_json = 8;
string source = 9;
// An `only: Affected` step's selection as JSON (empty = every test ran).
string selection_json = 10;
string trace_json = 11;
bytes trace_events = 12;
}
// Byte-identical field numbering to nornir/proto/nornir.proto `TestResultPb`.
message TestResultPb {
string run_id = 1;
string repo = 2;
string suite = 3;
string test_name = 4;
string status = 5;
double duration_ms = 6;
int64 ts_micros = 7;
string message = 8;
string aspect = 9;
double metric = 10;
}
message SubmitTestResultsRequest { repeated TestResultPb rows = 1; }
message SubmitCountResponse { uint32 accepted = 1; }
// Each element is one `BuildProvenance::to_json()` (JSON, not a typed Pb, so the
// record can gain fields without a proto bump — same contract as SubmitJobs).
message SubmitBuildProvenanceRequest { repeated string records_json = 1; }
// One §f3 build-info row (manifest or feed). Columns map 1:1 to the `build_info`
// table / the design's §f3 Arrow schema. `blob` is the only nullable column:
// `has_blob` distinguishes None (SQL NULL) from an empty inline payload, the same
// proto-3 presence trick SubmitReleaseEvents uses for its Options.
message BuildInfoRowPb {
string build_id = 1;
string step_id = 2;
int64 ts_micros = 3;
string kind = 4; // provenance | dep | artifact | log | metric | step
string level = 5;
string name = 6;
string value = 7;
string content_id = 8;
bytes blob = 9;
bool has_blob = 10;
}
message SubmitBuildInfoRequest { repeated BuildInfoRowPb rows = 1; }