Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/dwarves

crates/nornir-warehouse-embed/proto/bench.proto

// A TRIMMED copy of nornir-server's `Bench` service — `Submit` + `History`, and
// the messages they need. Package `nornir.v1` so the generated method paths
// (`/nornir.v1.Bench/Submit`, `/nornir.v1.Bench/History`) 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
// same pattern telemetry.proto follows).
//
// WHY dwarves needs it. Running a build-and-measure over a product is FORGE work
// (`dwarves bench run`); persisting the numbers is WAREHOUSE work. nornir holds
// the redb catalog lock, so the forge cannot append to `bench_runs` itself — it
// ships the finished `BenchRun` here and the server appends it. That is exactly
// what the upstream comment on `rpc Submit` already described ("the CLI runs
// benches locally … and ships the result over"); this makes the forge one of
// those callers.
//
// `History` was deliberately not copied at first — reading bench history was a
// warehouse query and stayed a nornir verb (`nornir bench history-show`). The
// doc-book MASHUP renderer moving into dwarves changed that: it composes the
// recorded numbers into the docs, so dwarves needs its OWN read-back leg. This
// is still the thin-client shape, not the twin: the QUERY stays nornir's (the
// server answers it out of its warehouse); dwarves only carries the call.
//
// Keep the field numbers identical to `nornir.proto` (edda's `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;

service Bench {
  // Read a repo's recorded runs back out of the warehouse — the leg the
  // doc-book mashup renderer composes its numbers from.
  rpc History (RepoOnly) returns (BenchHistoryResponse);
  // Append a freshly-computed BenchRun. The CLI runs benches locally
  // (the only place that can — they need the dev's hardware) and ships
  // the result over for the server to persist into iceberg.
  rpc Submit  (SubmitBenchRequest) returns (SubmitBenchResponse);
}

message SubmitBenchRequest {
  string repo = 1;
  BenchRun run = 2;
}

message SubmitBenchResponse {
  string run_id = 1;
}

message RepoOnly {
  string repo = 1;
}

message BenchHistoryResponse {
  string repo = 1;
  repeated BenchRun runs = 2;
}

// Byte-identical field numbering to nornir-wire's `KVF`. Declared here because
// the trimmed telemetry/workspaces/warehouse stubs never needed it.
message KVF {
  string key = 1;
  double value = 2;
}

message BenchResult {
  string name = 1;
  repeated KVF metrics = 2;
}

message BenchRun {
  string date         = 1;
  string timestamp    = 2; // RFC3339, may be empty
  string version      = 3;
  string machine      = 4;
  uint32 cores        = 5;
  repeated BenchResult results = 6;
  repeated TestOutcome tests   = 7;
  // The run's identity, minted by the PRODUCER (uuid v7) when the run was
  // measured — NOT by the server that stores it. Empty on a receipt written
  // before 2026-09-20, which is what tells the store "this one cannot be
  // deduplicated". Carrying it over the wire is what makes `Bench.Submit`
  // idempotent; without it the remote path would still double-write.
  string id           = 8;
  // `nornir_bench::machine::Machine` as JSON — what the BOX is (hostname, cpu
  // model, physical cores, logical threads, RAM, GPU, kernel, OS). A JSON
  // string rather than a nested message so the block can gain a field without
  // a wire change on both sides; empty when the producer did not look.
  string machine_facts_json = 9;
}

message TestOutcome {
  string name        = 1;
  bool   passed      = 2;
  double duration_ms = 3; // 0 when absent
  bool   has_duration = 4; // distinguishes "0 ms" from "not recorded"
  string message     = 5; // empty when absent
}