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

nordisk/holger

holger-cli/src/generated/holger.v1.rs

// @generated by `cargo xtask gen-proto` (protox + tonic-build, no protoc).
// DO NOT EDIT BY HAND. Regenerate after changing proto/holger.proto.

// This file is @generated by prost-build.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ArtifactId {
    /// e.g. groupId for Maven, empty for Rust
    #[prost(string, tag = "1")]
    pub namespace: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub name: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub version: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct FetchArtifactRequest {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    #[prost(message, optional, tag = "2")]
    pub id: ::core::option::Option<ArtifactId>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct FetchArtifactResponse {
    #[prost(bytes = "vec", tag = "1")]
    pub data: ::prost::alloc::vec::Vec<u8>,
    #[prost(string, tag = "2")]
    pub content_type: ::prost::alloc::string::String,
    #[prost(int64, tag = "3")]
    pub size_bytes: i64,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ArtifactChunk {
    #[prost(bytes = "vec", tag = "1")]
    pub data: ::prost::alloc::vec::Vec<u8>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ListArtifactsRequest {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    /// optional substring filter
    #[prost(string, tag = "2")]
    pub name_filter: ::prost::alloc::string::String,
    #[prost(int32, tag = "3")]
    pub limit: i32,
    #[prost(string, tag = "4")]
    pub page_token: ::prost::alloc::string::String,
}
/// One row of a repository listing.
///
/// ── Fields 4, 5 and 6 are `optional`, and that word is load-bearing ────────────
///
/// A proto3 scalar has no field presence: a peer that does not send `sha256`
/// and a peer that sends `sha256 = ""` are indistinguishable on the wire, and a
/// `published_unix_ms` of 0 arrives looking exactly like a real answer of
/// 1970-01-01T00:00:00Z. Both of those would be a FABRICATED value dressed as a
/// measurement — an empty digest compares equal to another empty digest, and a
/// zero timestamp sorts as the oldest thing in the repository.
///
/// The `optional` keyword restores explicit presence (proto3 field presence;
/// prost renders these as `Option<i64>` / `Option<String>`), so "this publisher
/// does not know" is a distinct state on the wire and not a value at all.
///
/// Wire compatibility, both directions:
///
/// * an OLD server answering a NEW client sends neither field; the client
///   reads `None` = unknown, which is the truth about an old server.
/// * a NEW server answering an OLD client sends two fields the old client
///   does not know; proto3 drops unknown fields, and the old client sees
///   exactly the listing it saw before.
///   Neither peer has to be upgraded first, and nothing here is an invented value.
///
/// Belt and braces on top of presence: a receiver still treats a
/// `published_unix_ms` that is not strictly positive, and a `sha256` that is not
/// 64 hex characters, as unknown — so even a hand-rolled client that emits the
/// proto3 zero values cannot claim 1970 or an empty hash. See
/// `holger_traits::normalize_published_unix_ms` / `normalize_sha256`.
///
/// This is the same reasoning as `StartMigrationRequest.skip_digest_verification`
/// next door, which is INVERTED on the wire so that the proto3 zero value is the
/// safe one. Here the safe state is "unknown", and presence says it outright
/// rather than by inversion.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ArtifactEntry {
    #[prost(message, optional, tag = "1")]
    pub id: ::core::option::Option<ArtifactId>,
    #[prost(int64, tag = "2")]
    pub size_bytes: i64,
    #[prost(string, tag = "3")]
    pub content_type: ::prost::alloc::string::String,
    /// When these bytes were published, Unix milliseconds UTC.
    /// ABSENT = the serving backend does not know. Never guessed, never 0.
    #[prost(int64, optional, tag = "4")]
    pub published_unix_ms: ::core::option::Option<i64>,
    /// Lowercase-hex SHA-256 of the artifact bytes, 64 chars, no `sha256:` prefix.
    /// ABSENT = the serving backend does not know, and in particular does NOT mean
    /// the bytes are trusted — the same rule `RemoteAsset.sha256` states. A
    /// backend that would have to read the artifact to answer leaves it absent
    /// rather than turning a listing into a full read of the repository.
    #[prost(string, optional, tag = "5")]
    pub sha256: ::core::option::Option<::prost::alloc::string::String>,
    /// An OPAQUE CHANGE TOKEN for these bytes, scoped to this server+repository.
    ///
    /// Equal ⇒ unchanged HERE. Different ⇒ changed HERE. It is not a content
    /// digest and it is not comparable with one; nor is it comparable with a
    /// token from any other source, because two sources holding byte-identical
    /// artifacts legitimately publish different tokens (holger's binds the
    /// archive-relative path, exactly as znippy's own provenance digest does).
    /// A consumer stamps its own source scope onto the value before it stores or
    /// compares it — see `holger_traits::scope_change_token`.
    ///
    /// This is the ONE provenance question a znippy-backed repository can answer
    /// cheaply: the archive index already carries a BLAKE3 per chunk, so a
    /// per-entry fold of them reads no artifact byte. 15 of 17 backends are
    /// znippy-backed, and without this every one of them answered `None` to both
    /// fields above, landed in the mirror's `unproven` bucket on every tick, and
    /// re-fetched its whole repository every 300 s under the default policy.
    ///
    /// ABSENT = the serving backend does not know. Never guessed, never "".
    #[prost(string, optional, tag = "6")]
    pub change_token: ::core::option::Option<::prost::alloc::string::String>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListArtifactsResponse {
    #[prost(message, repeated, tag = "1")]
    pub artifacts: ::prost::alloc::vec::Vec<ArtifactEntry>,
    #[prost(string, tag = "2")]
    pub next_page_token: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct PutArtifactRequest {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    #[prost(message, optional, tag = "2")]
    pub id: ::core::option::Option<ArtifactId>,
    #[prost(bytes = "vec", tag = "3")]
    pub data: ::prost::alloc::vec::Vec<u8>,
    /// ASYNC SHAPE -- see `PromoteArtifactRequest.async_job`. Unset/false writes
    /// the bytes into the backend on this RPC, as always. Set, the FINALIZE half
    /// (the backend write, which for a znippy repo is an index re-seal and for a
    /// proxy an outbound round-trip) becomes a job: the body is staged and the
    /// answer is a job id. The INGEST GATES still run here, before admission --
    /// making an upload asynchronous must not make it ungated.
    #[prost(bool, tag = "4")]
    pub async_job: bool,
}
/// One piece of a `PutArtifactStream` upload. `repository`, `id` and
/// `async_job` are read from the FIRST message only; `data` from every one.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct PutArtifactChunk {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    #[prost(message, optional, tag = "2")]
    pub id: ::core::option::Option<ArtifactId>,
    #[prost(bytes = "vec", tag = "3")]
    pub data: ::prost::alloc::vec::Vec<u8>,
    #[prost(bool, tag = "4")]
    pub async_job: bool,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct PutArtifactResponse {
    #[prost(bool, tag = "1")]
    pub success: bool,
    #[prost(string, tag = "2")]
    pub message: ::prost::alloc::string::String,
    /// Set ONLY when the request asked for the async shape. Empty otherwise.
    #[prost(string, tag = "3")]
    pub job_id: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ListArchiveFilesRequest {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    /// optional path prefix filter
    #[prost(string, tag = "2")]
    pub prefix: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ListArchiveFilesResponse {
    #[prost(string, repeated, tag = "1")]
    pub paths: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    #[prost(int64, tag = "2")]
    pub total_files: i64,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ArchiveInfoRequest {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ArchiveInfoResponse {
    #[prost(int64, tag = "1")]
    pub file_count: i64,
    #[prost(int64, tag = "2")]
    pub total_uncompressed_bytes: i64,
    #[prost(string, tag = "3")]
    pub archive_path: ::prost::alloc::string::String,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct HealthRequest {}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct HealthResponse {
    /// "ok"
    #[prost(string, tag = "1")]
    pub status: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub version: ::prost::alloc::string::String,
    #[prost(int64, tag = "3")]
    pub uptime_seconds: i64,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ListRepositoriesRequest {}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct RepositoryInfo {
    #[prost(string, tag = "1")]
    pub name: ::prost::alloc::string::String,
    /// "rust", "maven3"
    #[prost(string, tag = "2")]
    pub repo_type: ::prost::alloc::string::String,
    #[prost(bool, tag = "3")]
    pub writable: bool,
    #[prost(bool, tag = "4")]
    pub has_archive: bool,
    /// Whether `RepositoryService.ListArtifacts` on this repository is a REAL
    /// enumeration (`RepositoryBackendTrait::supports_listing`). A counter that
    /// ignores this reads a full repository as empty; a consumer that meters by
    /// artifact count MUST refuse, by name, while this is false.
    #[prost(bool, tag = "5")]
    pub supports_listing: bool,
    /// A GROUP repository is a read-only VIEW over `members`: it owns no storage,
    /// and its `ArchiveInfo` is the SUM of its members'. A fleet total that adds a
    /// group to its members counts those bytes twice — skip every `is_group`.
    #[prost(bool, tag = "6")]
    pub is_group: bool,
    /// The member repository names of a group, in resolution order. Empty for a
    /// repository that owns its own storage.
    #[prost(string, repeated, tag = "7")]
    pub members: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// A SYSTEM repository of this estate (floored at Admin, e.g. the sealed
    /// `monetize-backup`): the estate's own, its name taken, never a tenant a
    /// buyer pays for. Set by `ListRepositories` only; false elsewhere.
    #[prost(bool, tag = "8")]
    pub system: bool,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListRepositoriesResponse {
    #[prost(message, repeated, tag = "1")]
    pub repositories: ::prost::alloc::vec::Vec<RepositoryInfo>,
}
/// Confer the TWIN role on this box. See AdminService.BecomeTwin.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct BecomeTwinRequest {
    /// The primary this box will follow, as an address a client would use
    /// ("grpc.holger.rs:50051"). MANDATORY: a twin that names no primary could
    /// neither refuse a write by name nor follow anything.
    #[prost(string, tag = "1")]
    pub primary: ::prost::alloc::string::String,
    /// Seconds between follow cycles. 0 = the server's default.
    #[prost(uint64, tag = "2")]
    pub poll_seconds: u64,
    /// The MEASUREMENT that decided this election, in the caller's own words
    /// ("2 cores / 1 GB / 20 GB hdd vs 2 / 4 / 20 maxiops"). Recorded verbatim:
    /// this record is read by an operator on the worst day, and a number with no
    /// units is not a reason.
    #[prost(string, tag = "3")]
    pub reason: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct BecomeTwinReply {
    /// Unix seconds the election was recorded at.
    #[prost(uint64, tag = "1")]
    pub elected_at: u64,
    /// The authenticated identity that elected it — the server's own reading of
    /// the credential, not anything the caller said about itself.
    #[prost(string, tag = "2")]
    pub elected_by: ::prost::alloc::string::String,
    /// True: the LOOPBACK BIND of the public doors waits for the next start,
    /// because doors are bound at wiring time and a running server does not
    /// rebind them underneath its clients. The role itself is live — see
    /// `applied_live`.
    #[prost(bool, tag = "3")]
    pub restart_required: bool,
    /// True when every door refuses writes by name from this reply on and the
    /// follow has started, without a restart (stinky 14 §P3).
    #[prost(bool, tag = "4")]
    pub applied_live: bool,
}
/// Which credential slot of THIS box a pairing step is about: "twin" (the
/// twin following its primary; the default when empty) or "recharge" (a fresh
/// main reading its twin).
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct TwinCsrRequest {
    #[prost(string, tag = "1")]
    pub purpose: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct TwinCsrReply {
    /// PKCS#10, PEM. Its key was minted on this box and never leaves it; asked
    /// again, the same request.
    #[prost(string, tag = "1")]
    pub csr_pem: ::prost::alloc::string::String,
    /// The CN it carries — the principal the source must issue for.
    #[prost(string, tag = "2")]
    pub principal: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct IssueTwinCertificateRequest {
    /// `holger-twin` or `holger-recharge`; the request's own CN must be this.
    #[prost(string, tag = "1")]
    pub principal: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub csr_pem: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct IssueTwinCertificateReply {
    /// The client leaf: CN = principal, clientAuth only, 365 days.
    #[prost(string, tag = "1")]
    pub cert_pem: ::prost::alloc::string::String,
    /// This box's replication issuer — what the reader pins.
    #[prost(string, tag = "2")]
    pub issuer_pem: ::prost::alloc::string::String,
    /// The replication door's port and the addresses it answers on, in order.
    #[prost(uint32, tag = "3")]
    pub port: u32,
    #[prost(string, repeated, tag = "4")]
    pub hosts: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// notAfter, Unix seconds.
    #[prost(int64, tag = "5")]
    pub not_after: i64,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct InstallTwinCertificateRequest {
    #[prost(string, tag = "1")]
    pub purpose: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub cert_pem: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub issuer_pem: ::prost::alloc::string::String,
    #[prost(uint32, tag = "4")]
    pub port: u32,
    #[prost(string, repeated, tag = "5")]
    pub hosts: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// RE-POINT (purpose "twin" only): the primary this twin followed is DEAD and
    /// a fresh main was recharged from it — a main with an issuer of its own (an
    /// issuer is never replicated). Every install check but the pin runs; the new
    /// issuer is pinned and the twin's role record names `primary` from now on.
    /// Admin and explicit: never a courier's retry.
    #[prost(bool, tag = "6")]
    pub repoint: bool,
    #[prost(string, tag = "7")]
    pub primary: ::prost::alloc::string::String,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct FencePrimaryRequest {
    /// The epoch the order names (0 = a local fence).
    #[prost(uint64, tag = "1")]
    pub epoch: u64,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct FencePrimaryReply {
    /// The box is fenced now: every door refuses writes.
    #[prost(bool, tag = "1")]
    pub fenced: bool,
    /// The epoch it is fenced at.
    #[prost(uint64, tag = "2")]
    pub epoch: u64,
    /// The write refusal its doors answer from now on.
    #[prost(string, tag = "3")]
    pub refusal: ::prost::alloc::string::String,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct RechargeStatusRequest {}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct RechargeStatusReply {
    /// "fresh" (holds nothing of its own — a recharge may start), "restoring" (a
    /// recharge began and is not whole — it resumes), "recharged" (done, once),
    /// "holding" (state of its own: a re-image makes it fresh).
    #[prost(string, tag = "1")]
    pub state: ::prost::alloc::string::String,
    #[prost(bool, tag = "2")]
    pub fresh: bool,
    #[prost(bool, tag = "3")]
    pub restoring: bool,
    #[prost(bool, tag = "4")]
    pub recharged: bool,
    /// False while the box refuses to serve (holger-twin-15).
    #[prost(bool, tag = "5")]
    pub serving: bool,
    /// What makes the box not fresh, by path; empty when fresh.
    #[prost(string, tag = "6")]
    pub held: ::prost::alloc::string::String,
    /// The source a pending recharge waits for, when one is declared.
    #[prost(string, tag = "7")]
    pub awaiting_from: ::prost::alloc::string::String,
    /// This box's control plane as a client dials it (its gRPC door; an
    /// unspecified bind is named by its replication door's first address) — what
    /// a twin re-pointed at it names as its primary.
    #[prost(string, tag = "8")]
    pub control: ::prost::alloc::string::String,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct TwinStatusRequest {}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct TwinStatusReply {
    /// "twin" or "primary".
    #[prost(string, tag = "1")]
    pub role: ::prost::alloc::string::String,
    /// The primary it follows (a twin).
    #[prost(string, tag = "2")]
    pub primary: ::prost::alloc::string::String,
    /// What it holds: estate files, and artifacts over every repository.
    #[prost(uint64, tag = "3")]
    pub estate_files: u64,
    #[prost(uint64, tag = "4")]
    pub artifacts: u64,
    /// True when its last follow cycle that REACHED its primary was whole — a dead
    /// primary makes every later cycle fail to connect, and that is not a loss.
    #[prost(bool, tag = "5")]
    pub complete: bool,
    /// Why not complete, in words; empty when complete.
    #[prost(string, tag = "6")]
    pub why: ::prost::alloc::string::String,
    /// Unix seconds of the last whole cycle; 0 = never.
    #[prost(int64, tag = "7")]
    pub last_whole_unix: i64,
    /// How it last followed ("mtls <door>" / "plain <endpoint>").
    #[prost(string, tag = "8")]
    pub follow: ::prost::alloc::string::String,
    /// ★ What it last HEARD of its primary — the fence gate's evidence (A7 row 4,
    /// Gunnar R-13 fence before recharge): Unix ms of the last follow cycle that
    /// reached it (0 = never), how long ago that was on the TWIN's clock, what the
    /// primary listed then (estate files; 0 = an empty primary), and the twin's
    /// word: "following", "unreachable" (its last cycle did not reach it) or "idle".
    #[prost(int64, tag = "9")]
    pub primary_answer_unix_ms: i64,
    #[prost(uint64, tag = "10")]
    pub primary_answer_ago_ms: u64,
    #[prost(uint64, tag = "11")]
    pub primary_head: u64,
    #[prost(string, tag = "12")]
    pub follow_state: ::prost::alloc::string::String,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct InstallTwinCertificateReply {
    #[prost(int64, tag = "1")]
    pub days_left: i64,
    /// True when this replaced a certificate from the SAME issuer.
    #[prost(bool, tag = "2")]
    pub renewal: bool,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct RechargeRequest {}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct RechargeReply {
    /// The estate line, one line per repository, and what failed (empty = whole;
    /// the `holger-recharged` marker is written only then).
    #[prost(string, tag = "1")]
    pub estate: ::prost::alloc::string::String,
    #[prost(string, repeated, tag = "2")]
    pub artifacts: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    #[prost(string, repeated, tag = "3")]
    pub failed: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct FlowSvgRequest {
    /// The zoom, as `GET /-/flow.svg?open=` names it (HOL-FLOW-SMART): the machines to unfold,
    /// comma-separated, by id (`estate:main`) or short name (`main`, `twin`, a downstream's
    /// name). Empty is level 1 (the Overview: the machines and the upstream sources); some is
    /// level 2 (the Flow: those machines unfolded in place, with their part of the RON); `all`
    /// is level 3, the full RON.
    #[prost(string, tag = "1")]
    pub open: ::prost::alloc::string::String,
}
/// The whole drawing, `image/svg+xml`, UTF-8, self-contained (no script, no external
/// reference), and the model it was drawn from, JSON.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct FlowSvgReply {
    #[prost(string, tag = "1")]
    pub svg: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub graph_json: ::prost::alloc::string::String,
    /// Where the drawing is clickable (HOL-FLOW-SMART): each machine that unfolds or folds,
    /// and the full-RON link. A console showing the drawing as an image (which follows no
    /// link inside it) lays a plain link over each; it computes nothing.
    #[prost(message, repeated, tag = "3")]
    pub links: ::prost::alloc::vec::Vec<FlowLink>,
}
/// One clickable place of the flow drawing, as the share (0..1) of the drawing's width and
/// height it covers, and the relative link it follows (`flow?open=main`).
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct FlowLink {
    #[prost(string, tag = "1")]
    pub href: ::prost::alloc::string::String,
    /// What following it does: `unfold main`, `fold twin`, `show the full RON`.
    #[prost(string, tag = "2")]
    pub label: ::prost::alloc::string::String,
    #[prost(double, tag = "3")]
    pub left: f64,
    #[prost(double, tag = "4")]
    pub top: f64,
    #[prost(double, tag = "5")]
    pub width: f64,
    #[prost(double, tag = "6")]
    pub height: f64,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct CapacityRequest {}
/// One measurement of the filesystem under `path` (the data root).
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct CapacityReply {
    /// The filesystem size: f_blocks * f_frsize.
    #[prost(uint64, tag = "1")]
    pub total_bytes: u64,
    /// SERVABLE: what an unprivileged writer (holger) may still put there —
    /// f_bavail * f_frsize, i.e. without the root reserve. Not f_bfree.
    #[prost(uint64, tag = "2")]
    pub available_bytes: u64,
    /// The sum of `ArchiveInfo.total_uncompressed_bytes` over every repository
    /// that owns storage. Groups are excluded (their info is a sum of members).
    #[prost(uint64, tag = "3")]
    pub used_by_holger_bytes: u64,
    /// The data root the measurement was taken over.
    #[prost(string, tag = "4")]
    pub path: ::prost::alloc::string::String,
    /// ── the GROWTH VERDICT (2026-09-27, additive) ──
    /// Can this data set ever hold more than it does, and by whose hand — edda
    /// appliance-grow's ladder over MEASURED facts (the journal on the box, this
    /// build's engine, the kernel's PCI hot-plug, PID 1). Reported on every
    /// answer: "yes, and this is the last capacity" is a different sale. An OLD
    /// holger leaves it 0 (unspecified), which a reader must take as unknown.
    #[prost(enumeration = "SetGrowth", tag = "5")]
    pub growth: i32,
    /// The clause that says it, in words (an attached disk that is billed and
    /// invisible is said in those words).
    #[prost(string, tag = "6")]
    pub growth_reason: ::prost::alloc::string::String,
    /// What `path` sits on: `4×75G raid0 xfs`; empty when it is not a mount of its own.
    #[prost(string, tag = "7")]
    pub data_set: ::prost::alloc::string::String,
    /// The running kernel has PCI hot-plug (a runtime growth needs it).
    #[prost(bool, tag = "8")]
    pub hotplug: bool,
    /// ── the rest of the ELECTION's measurement (stinky SB #37, additive) ──
    /// The installer elects the weakest box the twin on cores, then RAM, then data
    /// room (nordisk-pairing `elect::weakest`); a capacity that answered the disk
    /// alone could not say which box that is. An OLD holger leaves both 0.
    /// CPUs this process may run on (available_parallelism).
    #[prost(uint32, tag = "9")]
    pub cpu_cores: u32,
    /// MemTotal of /proc/meminfo, bytes.
    #[prost(uint64, tag = "10")]
    pub ram_bytes: u64,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ServerProfileRequest {}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct PromoteArtifactRequest {
    /// source, mutable DEV repository
    #[prost(string, tag = "1")]
    pub from_repo: ::prost::alloc::string::String,
    /// target, immutable PROD repository
    #[prost(string, tag = "2")]
    pub to_repo: ::prost::alloc::string::String,
    #[prost(message, optional, tag = "3")]
    pub artifact: ::core::option::Option<ArtifactId>,
    /// ASYNC SHAPE (2026-09-21, stinky 01 §1.3), purely ADDITIVE: unset/false is
    /// the original synchronous promotion, byte for byte -- the seal runs on this
    /// RPC and the response carries `content_address`. Set true and the server
    /// ADMITS the promotion to its durable job queue and answers at once with
    /// `job_id`; the seal happens on the queue's gatling pool and is read back
    /// through `JobService.GetJob`. A server built WITHOUT the `jobs` feature
    /// refuses a true here BY NAME rather than silently promoting inline.
    #[prost(bool, tag = "4")]
    pub async_job: bool,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct PromoteArtifactResponse {
    #[prost(bool, tag = "1")]
    pub success: bool,
    #[prost(string, tag = "2")]
    pub message: ::prost::alloc::string::String,
    /// blake3 hex of the promoted bytes
    #[prost(string, tag = "3")]
    pub content_address: ::prost::alloc::string::String,
    /// identity that performed the promotion
    #[prost(string, tag = "4")]
    pub promoted_by: ::prost::alloc::string::String,
    /// Set ONLY when the request asked for the async shape: the admitted job's id.
    /// Empty on every synchronous promotion, so an old client sees no change.
    #[prost(string, tag = "5")]
    pub job_id: ::prost::alloc::string::String,
}
/// One evidence slot: kind is scan | malware | license | provenance | approval |
/// other; verdict is pass | warn | fail. A caller never supplies `approval`:
/// the server mints it from the authenticated approver (holger-duty-7).
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct IntakeEvidence {
    #[prost(string, tag = "1")]
    pub kind: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub source: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub verdict: ::prost::alloc::string::String,
    #[prost(string, tag = "4")]
    pub reference: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdvanceArtifactRequest {
    #[prost(message, optional, tag = "1")]
    pub artifact: ::core::option::Option<ArtifactId>,
    #[prost(enumeration = "IntakeVerb", tag = "2")]
    pub verb: i32,
    /// Optional: the state ADVANCE is meant to reach (refused unless it is the next one).
    #[prost(string, tag = "3")]
    pub to_state: ::prost::alloc::string::String,
    #[prost(string, tag = "4")]
    pub reason: ::prost::alloc::string::String,
    #[prost(message, repeated, tag = "5")]
    pub evidence: ::prost::alloc::vec::Vec<IntakeEvidence>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdvanceArtifactResponse {
    #[prost(string, tag = "1")]
    pub from_state: ::prost::alloc::string::String,
    /// The state after the call. Equal to from_state when an approval vote was
    /// recorded short of the quorum.
    #[prost(string, tag = "2")]
    pub state: ::prost::alloc::string::String,
    /// Distinct approvals now recorded for the APPROVED hop, and how many it needs.
    #[prost(uint32, tag = "3")]
    pub approvals: u32,
    #[prost(uint32, tag = "4")]
    pub approvals_required: u32,
    /// The evidence the transition carried (the approval slots on APPROVED).
    #[prost(message, repeated, tag = "5")]
    pub evidence: ::prost::alloc::vec::Vec<IntakeEvidence>,
    #[prost(string, tag = "6")]
    pub message: ::prost::alloc::string::String,
    #[prost(string, tag = "7")]
    pub sha256: ::prost::alloc::string::String,
    /// The authenticated principal the server acted for.
    #[prost(string, tag = "8")]
    pub actor: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct GetArtifactStateRequest {
    #[prost(message, optional, tag = "1")]
    pub artifact: ::core::option::Option<ArtifactId>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct IntakeTransition {
    #[prost(string, tag = "1")]
    pub from_state: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub to_state: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub actor: ::prost::alloc::string::String,
    #[prost(int64, tag = "4")]
    pub at: i64,
    #[prost(message, repeated, tag = "5")]
    pub evidence: ::prost::alloc::vec::Vec<IntakeEvidence>,
    #[prost(string, tag = "6")]
    pub policy: ::prost::alloc::string::String,
    #[prost(string, tag = "7")]
    pub reason: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetArtifactStateResponse {
    #[prost(string, tag = "1")]
    pub state: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub sha256: ::prost::alloc::string::String,
    /// The principal that ingested the artifact; it never approves it.
    #[prost(string, tag = "3")]
    pub importer: ::prost::alloc::string::String,
    #[prost(uint32, tag = "4")]
    pub approvals: u32,
    #[prost(uint32, tag = "5")]
    pub approvals_required: u32,
    #[prost(message, repeated, tag = "6")]
    pub history: ::prost::alloc::vec::Vec<IntakeTransition>,
    /// Approval votes recorded short of the quorum.
    #[prost(message, repeated, tag = "7")]
    pub pending_approvals: ::prost::alloc::vec::Vec<IntakeEvidence>,
    /// The source the artifact came from (tier 1 `sources:`); empty on a chain
    /// declared with the old `promotion:` spelling.
    #[prost(string, tag = "8")]
    pub source: ::prost::alloc::string::String,
    /// The artifact's effective policy (the floor plus its source's gates), as JSON:
    /// each rule with who set it (`floor`, `steps.gates`, `source '<name>'`).
    #[prost(string, tag = "9")]
    pub effective_policy: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ListIntakeArtifactsRequest {
    /// The queue whose rows to return: incoming | quarantined |
    /// awaiting-approval | blocked | available. Empty returns the counts only.
    #[prost(string, tag = "1")]
    pub queue: ::prost::alloc::string::String,
    /// At most this many rows (0 = the server's default, 200).
    #[prost(uint32, tag = "2")]
    pub limit: u32,
}
/// One queue of the security dashboard, as the server groups the states.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct IntakeQueue {
    /// The stable name: incoming | quarantined | awaiting-approval | blocked | available.
    #[prost(string, tag = "1")]
    pub name: ::prost::alloc::string::String,
    /// The words an operator reads: "Awaiting approval".
    #[prost(string, tag = "2")]
    pub title: ::prost::alloc::string::String,
    /// The intake states the queue holds, by name.
    #[prost(string, repeated, tag = "3")]
    pub states: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// The artifacts in the queue that the caller may read.
    #[prost(uint64, tag = "4")]
    pub count: u64,
}
/// One intake artifact where it stands now.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct IntakeArtifactRow {
    #[prost(message, optional, tag = "1")]
    pub artifact: ::core::option::Option<ArtifactId>,
    #[prost(string, tag = "2")]
    pub state: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub sha256: ::prost::alloc::string::String,
    /// The intake repository it stands in.
    #[prost(string, tag = "4")]
    pub repository: ::prost::alloc::string::String,
    /// The principal of the last transition, and when (Unix seconds).
    #[prost(string, tag = "5")]
    pub actor: ::prost::alloc::string::String,
    #[prost(int64, tag = "6")]
    pub at: i64,
    /// The state a QUARANTINED artifact was held at.
    #[prost(string, tag = "7")]
    pub held_from: ::prost::alloc::string::String,
    #[prost(string, tag = "8")]
    pub importer: ::prost::alloc::string::String,
    /// Approval votes recorded short of the quorum, and the quorum.
    #[prost(uint32, tag = "9")]
    pub approvals: u32,
    #[prost(uint32, tag = "10")]
    pub approvals_required: u32,
    /// The policy's words and the reason of the last transition.
    #[prost(string, tag = "11")]
    pub policy: ::prost::alloc::string::String,
    #[prost(string, tag = "12")]
    pub reason: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListIntakeArtifactsResponse {
    #[prost(message, repeated, tag = "1")]
    pub queues: ::prost::alloc::vec::Vec<IntakeQueue>,
    /// The rows of the queue asked for.
    #[prost(message, repeated, tag = "2")]
    pub artifacts: ::prost::alloc::vec::Vec<IntakeArtifactRow>,
    /// True when the queue held more rows than `limit`.
    #[prost(bool, tag = "3")]
    pub truncated: bool,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct GetArtifactEvidenceRequest {
    #[prost(message, optional, tag = "1")]
    pub artifact: ::core::option::Option<ArtifactId>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct EvidenceHash {
    /// sha256 | blake3.
    #[prost(string, tag = "1")]
    pub alg: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub hex: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct EvidenceFinding {
    #[prost(string, tag = "1")]
    pub id: ::prost::alloc::string::String,
    /// info | low | medium | high | critical.
    #[prost(string, tag = "2")]
    pub severity: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub summary: ::prost::alloc::string::String,
}
/// One scanner's evidence about the artifact.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct EvidenceRecord {
    #[prost(string, tag = "1")]
    pub scanner_id: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub scanner_version: ::prost::alloc::string::String,
    /// inspection | malware | vulnerability | license | secrets | provenance | sbom.
    #[prost(string, tag = "3")]
    pub kind: ::prost::alloc::string::String,
    /// pass | warn | block | error.
    #[prost(string, tag = "4")]
    pub verdict: ::prost::alloc::string::String,
    #[prost(message, repeated, tag = "5")]
    pub findings: ::prost::alloc::vec::Vec<EvidenceFinding>,
    #[prost(message, repeated, tag = "6")]
    pub inputs: ::prost::alloc::vec::Vec<EvidenceHash>,
    #[prost(string, tag = "7")]
    pub detail: ::prost::alloc::string::String,
    /// The operator requires this kind; an error from it blocks.
    #[prost(bool, tag = "8")]
    pub required: bool,
    /// No scanner is installed in this slot.
    #[prost(bool, tag = "9")]
    pub not_configured: bool,
    /// A document the scanner produced (the CycloneDX SBOM), as JSON. Empty when none.
    #[prost(string, tag = "10")]
    pub document_json: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetArtifactEvidenceResponse {
    /// The intake state and the sha256 recorded at ingest.
    #[prost(string, tag = "1")]
    pub state: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub sha256: ::prost::alloc::string::String,
    /// False when no scan has recorded evidence for these bytes yet.
    #[prost(bool, tag = "3")]
    pub scanned: bool,
    #[prost(string, tag = "4")]
    pub file_name: ::prost::alloc::string::String,
    #[prost(string, tag = "5")]
    pub ecosystem: ::prost::alloc::string::String,
    #[prost(uint64, tag = "6")]
    pub size: u64,
    /// The hashes of the bytes the scanners saw.
    #[prost(message, repeated, tag = "7")]
    pub hashes: ::prost::alloc::vec::Vec<EvidenceHash>,
    /// The fold over every record: pass | warn | block | error.
    #[prost(string, tag = "8")]
    pub verdict: ::prost::alloc::string::String,
    /// One sentence per reason the verdict is not pass.
    #[prost(string, repeated, tag = "9")]
    pub reasons: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    #[prost(message, repeated, tag = "10")]
    pub records: ::prost::alloc::vec::Vec<EvidenceRecord>,
    /// When the scan ran, Unix seconds.
    #[prost(int64, tag = "11")]
    pub scanned_at: i64,
    /// The policy's words on the last transition.
    #[prost(string, tag = "12")]
    pub policy: ::prost::alloc::string::String,
    /// W5: every stored record about these bytes, oldest scan first, each with the
    /// envelope that signs it.
    #[prost(message, repeated, tag = "13")]
    pub stored: ::prost::alloc::vec::Vec<ArtifactEvidenceRecord>,
    /// The attestation signer's certificate (DER) the envelopes verify against.
    #[prost(bytes = "vec", tag = "14")]
    pub signer_cert: ::prost::alloc::vec::Vec<u8>,
    /// `/-/intake/sbom?sha256=<hex>` when the newest record carries an SBOM.
    #[prost(string, tag = "15")]
    pub sbom_link: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ListDependencySetsRequest {
    /// Only the sets in this status (resolving | held | refused | awaiting-approval |
    /// approved | available); empty: every set the caller may read.
    #[prost(string, tag = "1")]
    pub status: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListDependencySetsResponse {
    /// Newest first.
    #[prost(message, repeated, tag = "1")]
    pub sets: ::prost::alloc::vec::Vec<DependencySet>,
    /// How many distinct approvers each member needs.
    #[prost(uint32, tag = "2")]
    pub approvals_required: u32,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct GetDependencySetRequest {
    #[prost(string, tag = "1")]
    pub id: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct JudgeDependencySetRequest {
    #[prost(string, tag = "1")]
    pub id: ::prost::alloc::string::String,
    /// Why: kept with every vote; a refusal names it on every blocked member (required).
    #[prost(string, tag = "2")]
    pub reason: ::prost::alloc::string::String,
    /// The `revision` of the set as the caller was shown it (SEC-REVIEW D4, required): a vote
    /// naming none, or another than the set has now, is refused (FAILED_PRECONDITION,
    /// holger-depset-4) and nothing is cast.
    #[prost(string, tag = "3")]
    pub revision: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct JudgeDependencySetResponse {
    #[prost(string, tag = "1")]
    pub id: ::prost::alloc::string::String,
    /// Where the set stands after the call.
    #[prost(string, tag = "2")]
    pub status: ::prost::alloc::string::String,
    /// The members this call voted on (approve) or blocked (refuse).
    #[prost(uint32, tag = "3")]
    pub moved: u32,
    #[prost(string, tag = "4")]
    pub message: ::prost::alloc::string::String,
    #[prost(message, optional, tag = "5")]
    pub set: ::core::option::Option<DependencySet>,
}
/// A member or a coordinate, and why it refuses or holds a set.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct DependencySetReason {
    #[prost(string, tag = "1")]
    pub name: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub why: ::prost::alloc::string::String,
}
/// One member of a set, as an approver is shown it.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct DependencySetMember {
    /// The chain coordinate (`pypi/dep-1.0-py3-none-any.whl`).
    #[prost(string, tag = "1")]
    pub name: ::prost::alloc::string::String,
    /// requested | parent | bom | descriptor | dependency.
    #[prost(string, tag = "2")]
    pub role: ::prost::alloc::string::String,
    /// What needed it.
    #[prost(string, tag = "3")]
    pub via: ::prost::alloc::string::String,
    /// The intake state (POLICY_CHECKED …), or not-in-chain.
    #[prost(string, tag = "4")]
    pub state: ::prost::alloc::string::String,
    #[prost(string, tag = "5")]
    pub sha256: ::prost::alloc::string::String,
    /// The votes cast on its current bytes, and by whom.
    #[prost(uint32, tag = "6")]
    pub approvals: u32,
    #[prost(string, repeated, tag = "7")]
    pub approvers: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// Why it is refused or held, when it is.
    #[prost(string, tag = "8")]
    pub reason: ::prost::alloc::string::String,
    /// Advisories recorded as a warning.
    #[prost(string, repeated, tag = "9")]
    pub warnings: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
}
/// One dependency set: what a pull brought in, judged as one.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct DependencySet {
    #[prost(string, tag = "1")]
    pub id: ::prost::alloc::string::String,
    /// The pull-through source.
    #[prost(string, tag = "2")]
    pub source: ::prost::alloc::string::String,
    /// maven | npm | crates | python.
    #[prost(string, tag = "3")]
    pub ecosystem: ::prost::alloc::string::String,
    /// What was asked for, in the ecosystem's words (`app==1.0`).
    #[prost(string, tag = "4")]
    pub root: ::prost::alloc::string::String,
    /// When the pull ran, Unix seconds.
    #[prost(int64, tag = "5")]
    pub at: i64,
    /// resolving | held | refused | awaiting-approval | approved | available.
    #[prost(string, tag = "6")]
    pub status: ::prost::alloc::string::String,
    /// The words for the status.
    #[prost(string, tag = "7")]
    pub summary: ::prost::alloc::string::String,
    #[prost(message, repeated, tag = "8")]
    pub members: ::prost::alloc::vec::Vec<DependencySetMember>,
    /// The members that refuse the set.
    #[prost(message, repeated, tag = "9")]
    pub blockers: ::prost::alloc::vec::Vec<DependencySetReason>,
    /// What holds the set.
    #[prost(message, repeated, tag = "10")]
    pub holds: ::prost::alloc::vec::Vec<DependencySetReason>,
    #[prost(uint32, tag = "11")]
    pub approvals_required: u32,
    /// The approvers who voted on every member still waiting.
    #[prost(string, repeated, tag = "12")]
    pub approvers: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// Members waiting at POLICY_CHECKED, and members AVAILABLE.
    #[prost(uint32, tag = "13")]
    pub awaiting: u32,
    #[prost(uint32, tag = "14")]
    pub available: u32,
    #[prost(string, repeated, tag = "15")]
    pub notes: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// What a vote names (SEC-REVIEW D4): a hash over the members and their sha256 as shown.
    #[prost(string, tag = "16")]
    pub revision: ::prost::alloc::string::String,
}
/// One stored scan-evidence record (W5).
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ArtifactEvidenceRecord {
    /// The blake3 of the record's bytes: its name in the evidence store.
    #[prost(string, tag = "1")]
    pub id: ::prost::alloc::string::String,
    /// When the scan ran, Unix seconds.
    #[prost(int64, tag = "2")]
    pub scanned_at: i64,
    /// The fold over every scanner: pass | warn | block | error.
    #[prost(string, tag = "3")]
    pub verdict: ::prost::alloc::string::String,
    #[prost(string, repeated, tag = "4")]
    pub reasons: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// The record itself (holger.scan-evidence/v1 JSON), byte-identical to the store.
    #[prost(bytes = "vec", tag = "5")]
    pub evidence_json: ::prost::alloc::vec::Vec<u8>,
    /// The DSSE envelope (in-toto, predicate <https://holger.rs/attestation/scan-evidence/v1>)
    /// that verifies to this record; empty when the record is not signed.
    #[prost(bytes = "vec", tag = "6")]
    pub envelope: ::prost::alloc::vec::Vec<u8>,
    /// Empty when a scan now would agree; otherwise why it is stale (a newer
    /// scanner version or intel database sequence).
    #[prost(string, tag = "7")]
    pub stale: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct GetArtifactTrailRequest {
    /// Lowercase-hex SHA-256 of the artifact's bytes (a `sha256:` prefix is allowed).
    #[prost(string, tag = "1")]
    pub sha256: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ArtifactTrailEntry {
    /// The record's sequence number and chain hash in the audit log.
    #[prost(uint64, tag = "1")]
    pub seq: u64,
    #[prost(string, tag = "2")]
    pub hash: ::prost::alloc::string::String,
    #[prost(int64, tag = "3")]
    pub ts_nanos: i64,
    /// imported | hash_verified | scanned | policy_passed | policy_denied |
    /// approved | sealed | exported | airgap_imported
    #[prost(string, tag = "4")]
    pub kind: ::prost::alloc::string::String,
    #[prost(string, tag = "5")]
    pub ident: ::prost::alloc::string::String,
    #[prost(string, tag = "6")]
    pub repo: ::prost::alloc::string::String,
    #[prost(string, tag = "7")]
    pub artifact: ::prost::alloc::string::String,
    #[prost(uint32, tag = "8")]
    pub status: u32,
    #[prost(string, tag = "9")]
    pub detail: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetArtifactTrailResponse {
    #[prost(string, tag = "1")]
    pub sha256: ::prost::alloc::string::String,
    #[prost(message, repeated, tag = "2")]
    pub entries: ::prost::alloc::vec::Vec<ArtifactTrailEntry>,
    /// Whether the whole audit chain verified when the trail was read.
    #[prost(bool, tag = "3")]
    pub chain_intact: bool,
    #[prost(string, tag = "4")]
    pub chain_summary: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct QueryDownloadsRequest {
    /// Who downloaded (the authenticated principal; `anonymous` for open reads).
    /// Empty = anybody.
    #[prost(string, tag = "1")]
    pub ident: ::prost::alloc::string::String,
    /// The repository. Empty = every repository.
    #[prost(string, tag = "2")]
    pub repo: ::prost::alloc::string::String,
    /// From (inclusive) and to (exclusive), nanoseconds since the Unix epoch.
    /// Zero = open.
    #[prost(int64, tag = "3")]
    pub since_nanos: i64,
    #[prost(int64, tag = "4")]
    pub until_nanos: i64,
    /// At most this many rows, the NEWEST that match. Zero = 1000; capped at 10000.
    #[prost(uint64, tag = "5")]
    pub limit: u64,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct DownloadRow {
    #[prost(uint64, tag = "1")]
    pub seq: u64,
    #[prost(string, tag = "2")]
    pub hash: ::prost::alloc::string::String,
    #[prost(int64, tag = "3")]
    pub ts_nanos: i64,
    #[prost(string, tag = "4")]
    pub ident: ::prost::alloc::string::String,
    #[prost(string, tag = "5")]
    pub repo: ::prost::alloc::string::String,
    #[prost(string, tag = "6")]
    pub artifact: ::prost::alloc::string::String,
    #[prost(string, tag = "7")]
    pub source_ip: ::prost::alloc::string::String,
    #[prost(uint32, tag = "8")]
    pub status: u32,
    #[prost(uint64, tag = "9")]
    pub bytes: u64,
    #[prost(string, tag = "10")]
    pub sha256: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct QueryDownloadsResponse {
    #[prost(message, repeated, tag = "1")]
    pub rows: ::prost::alloc::vec::Vec<DownloadRow>,
    /// How many rows matched in all, and whether the limit left some out.
    #[prost(uint64, tag = "2")]
    pub matched: u64,
    #[prost(bool, tag = "3")]
    pub truncated: bool,
}
/// Which records: every field optional, set fields AND together.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AuditFilter {
    /// The actor (authenticated principal; "anonymous" for open reads).
    #[prost(string, tag = "1")]
    pub ident: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub repo: ::prost::alloc::string::String,
    /// A PREFIX of the artifact: "acme/" a namespace, "acme/widget@" every version.
    #[prost(string, tag = "3")]
    pub artifact_prefix: ::prost::alloc::string::String,
    /// download | upload | delete | list | promote | entitlement | purge | scan |
    /// token | other. Any other word is refused.
    #[prost(string, tag = "4")]
    pub action: ::prost::alloc::string::String,
    /// The client address; without a port it matches every port of the address.
    #[prost(string, tag = "5")]
    pub source_ip: ::prost::alloc::string::String,
    /// The exact status. 0 = any.
    #[prost(uint32, tag = "6")]
    pub status: u32,
    /// From (inclusive) and to (exclusive), nanoseconds since the Unix epoch. 0 = open.
    #[prost(int64, tag = "7")]
    pub since_nanos: i64,
    #[prost(int64, tag = "8")]
    pub until_nanos: i64,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AuditRecordRow {
    #[prost(uint64, tag = "1")]
    pub seq: u64,
    #[prost(string, tag = "2")]
    pub hash: ::prost::alloc::string::String,
    #[prost(int64, tag = "3")]
    pub ts_nanos: i64,
    #[prost(string, tag = "4")]
    pub ident: ::prost::alloc::string::String,
    #[prost(string, tag = "5")]
    pub action: ::prost::alloc::string::String,
    #[prost(string, tag = "6")]
    pub repo: ::prost::alloc::string::String,
    #[prost(string, tag = "7")]
    pub artifact: ::prost::alloc::string::String,
    #[prost(string, tag = "8")]
    pub source_ip: ::prost::alloc::string::String,
    #[prost(uint32, tag = "9")]
    pub status: u32,
    #[prost(uint64, tag = "10")]
    pub bytes: u64,
    #[prost(string, tag = "11")]
    pub detail: ::prost::alloc::string::String,
    #[prost(string, tag = "12")]
    pub sha256: ::prost::alloc::string::String,
    #[prost(string, tag = "13")]
    pub trail: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AuditQueryRequest {
    #[prost(message, optional, tag = "1")]
    pub filter: ::core::option::Option<AuditFilter>,
    /// Matching records to skip; pass back next_offset.
    #[prost(uint64, tag = "2")]
    pub offset: u64,
    /// Page size. 0 = 100; capped at 1000 (limit_applied says what was used).
    #[prost(uint32, tag = "3")]
    pub limit: u32,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AuditQueryResponse {
    /// The page, oldest first.
    #[prost(message, repeated, tag = "1")]
    pub records: ::prost::alloc::vec::Vec<AuditRecordRow>,
    /// Every match before paging: the number to show.
    #[prost(uint64, tag = "2")]
    pub matched: u64,
    #[prost(uint64, tag = "3")]
    pub next_offset: u64,
    /// Matches exist beyond this page.
    #[prost(bool, tag = "4")]
    pub more: bool,
    #[prost(uint64, tag = "5")]
    pub scanned: u64,
    #[prost(uint32, tag = "6")]
    pub limit_applied: u32,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AuditAggregateRequest {
    #[prost(message, optional, tag = "1")]
    pub filter: ::core::option::Option<AuditFilter>,
    /// repo | action | day | ident | client | status. Empty = repo, action, day.
    #[prost(string, repeated, tag = "2")]
    pub group_by: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// Only 2xx statuses (what was served, not what was refused).
    #[prost(bool, tag = "3")]
    pub ok_only: bool,
    /// At most this many groups (the first in key order). 0 = 10000.
    #[prost(uint32, tag = "4")]
    pub max_groups: u32,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AuditAggregateRow {
    /// The keys not grouped on are empty (status 0).
    #[prost(string, tag = "1")]
    pub repo: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub action: ::prost::alloc::string::String,
    /// YYYY-MM-DD, UTC.
    #[prost(string, tag = "3")]
    pub day: ::prost::alloc::string::String,
    #[prost(string, tag = "4")]
    pub ident: ::prost::alloc::string::String,
    /// The client address without its port. An address is not an identity.
    #[prost(string, tag = "5")]
    pub client: ::prost::alloc::string::String,
    #[prost(uint32, tag = "6")]
    pub status: u32,
    #[prost(uint64, tag = "7")]
    pub count: u64,
    #[prost(uint64, tag = "8")]
    pub bytes: u64,
    #[prost(int64, tag = "9")]
    pub first_ts_nanos: i64,
    #[prost(int64, tag = "10")]
    pub last_ts_nanos: i64,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AuditAggregateResponse {
    #[prost(string, repeated, tag = "1")]
    pub group_by: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    #[prost(message, repeated, tag = "2")]
    pub rows: ::prost::alloc::vec::Vec<AuditAggregateRow>,
    #[prost(bool, tag = "3")]
    pub groups_truncated: bool,
    #[prost(uint64, tag = "4")]
    pub rows_counted: u64,
    #[prost(uint64, tag = "5")]
    pub scanned: u64,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AuditExportRequest {
    #[prost(message, optional, tag = "1")]
    pub filter: ::core::option::Option<AuditFilter>,
    /// Only rows with seq >= since_seq (the next page: next_seq of the last reply).
    #[prost(uint64, tag = "2")]
    pub since_seq: u64,
    /// At most this many rows, the oldest that match. 0 = 50000; capped at 50000.
    #[prost(uint32, tag = "3")]
    pub limit: u32,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AuditExportResponse {
    /// One Arrow IPC file.
    #[prost(bytes = "vec", tag = "1")]
    pub arrow_ipc: ::prost::alloc::vec::Vec<u8>,
    #[prost(uint64, tag = "2")]
    pub rows: u64,
    #[prost(bool, tag = "3")]
    pub truncated: bool,
    #[prost(uint64, tag = "4")]
    pub next_seq: u64,
    /// "holger.audit.index/v1" and the schema, `name:type` per column.
    #[prost(string, tag = "5")]
    pub layout: ::prost::alloc::string::String,
    #[prost(string, tag = "6")]
    pub schema: ::prost::alloc::string::String,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct VerifyAuditChainRequest {}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct VerifyAuditChainResponse {
    #[prost(bool, tag = "1")]
    pub intact: bool,
    #[prost(uint64, tag = "2")]
    pub records: u64,
    #[prost(uint64, tag = "3")]
    pub checkpoints: u64,
    #[prost(uint64, tag = "4")]
    pub signatures_verified: u64,
    #[prost(uint64, tag = "5")]
    pub signatures_unchecked: u64,
    #[prost(uint64, tag = "6")]
    pub unsigned_checkpoints: u64,
    /// The hash of the last line that verified.
    #[prost(string, tag = "7")]
    pub head: ::prost::alloc::string::String,
    /// The first break: 1-based line, its seq, and why. Zero / empty when intact.
    #[prost(uint64, tag = "8")]
    pub break_line: u64,
    #[prost(uint64, tag = "9")]
    pub break_seq: u64,
    #[prost(string, tag = "10")]
    pub break_reason: ::prost::alloc::string::String,
    #[prost(string, tag = "11")]
    pub summary: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SearchRequest {
    /// Case-insensitive substring match on the artifact NAME (Maven artifactId,
    /// crate name, …). Empty = any name.
    #[prost(string, tag = "1")]
    pub name: ::prost::alloc::string::String,
    /// Case-insensitive substring match on the NAMESPACE (Maven groupId, npm
    /// scope). Empty = any / no namespace constraint.
    #[prost(string, tag = "2")]
    pub namespace: ::prost::alloc::string::String,
    /// Exact match on the artifact VERSION. Empty = any version.
    #[prost(string, tag = "3")]
    pub version: ::prost::alloc::string::String,
    /// Lowercase-hex sha256 of the artifact CONTENT (exact, case-insensitive).
    /// Setting this forces the server to hash candidate artifacts' bytes, so it is
    /// the one expensive axis — leave empty unless you are searching by digest.
    #[prost(string, tag = "4")]
    pub checksum: ::prost::alloc::string::String,
    /// Case-insensitive substring match on a RAW archive file path. Produces path
    /// hits (see `paths`), independent of the artifact axes above.
    #[prost(string, tag = "5")]
    pub path: ::prost::alloc::string::String,
    /// Restrict the search to these repository names. Empty = every configured repo.
    #[prost(string, repeated, tag = "6")]
    pub repositories: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// Cap the number of hits returned (per hit kind). 0 ⇒ a server default.
    #[prost(int32, tag = "7")]
    pub limit: i32,
    /// Custom-PROPERTY filters (AND-composed with each other and the axes above). An
    /// artifact matches only if it carries every listed property. Empty = no
    /// property constraint. Requires the server to have a property store configured;
    /// with none, a property filter matches nothing (fail-closed).
    #[prost(message, repeated, tag = "8")]
    pub properties: ::prost::alloc::vec::Vec<PropertyMatch>,
}
/// One custom-property filter: the artifact must carry `key`, and — when `value`
/// is non-empty — that exact value among the key's values (empty `value` = "the
/// key is present, any value").
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct PropertyMatch {
    #[prost(string, tag = "1")]
    pub key: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub value: ::prost::alloc::string::String,
}
/// One artifact matched by name / coordinate / checksum, tagged with the repo it
/// was found in.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ArtifactHit {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    #[prost(message, optional, tag = "2")]
    pub id: ::core::option::Option<ArtifactId>,
    #[prost(int64, tag = "3")]
    pub size_bytes: i64,
    #[prost(string, tag = "4")]
    pub content_type: ::prost::alloc::string::String,
    /// sha256 hex of the content — set ONLY when a checksum query forced a hash
    /// (empty otherwise, to keep the common name/coordinate search cheap).
    #[prost(string, tag = "5")]
    pub checksum: ::prost::alloc::string::String,
}
/// One raw archive path matched by the `path` axis, tagged with its repo.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct PathHit {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub path: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SearchResponse {
    #[prost(message, repeated, tag = "1")]
    pub artifacts: ::prost::alloc::vec::Vec<ArtifactHit>,
    #[prost(message, repeated, tag = "2")]
    pub paths: ::prost::alloc::vec::Vec<PathHit>,
    /// True when the result set hit the `limit` cap and more hits exist.
    #[prost(bool, tag = "3")]
    pub truncated: bool,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AttachSbomRequest {
    /// The repository the artifact lives in.
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    /// The artifact coordinate the SBOM describes (namespace/name/version).
    #[prost(message, optional, tag = "2")]
    pub artifact: ::core::option::Option<ArtifactId>,
    /// The SBOM document bytes to host (a CycloneDX 1.5 JSON document). Served back
    /// byte-identical by FetchSbom / the HTTP door.
    #[prost(bytes = "vec", tag = "3")]
    pub document: ::prost::alloc::vec::Vec<u8>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AttachSbomResponse {
    #[prost(bool, tag = "1")]
    pub success: bool,
    #[prost(string, tag = "2")]
    pub message: ::prost::alloc::string::String,
    /// blake3 hex of the attached document (the SBOM's content address).
    #[prost(string, tag = "3")]
    pub content_address: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct FetchSbomRequest {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    #[prost(message, optional, tag = "2")]
    pub artifact: ::core::option::Option<ArtifactId>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct FetchSbomResponse {
    /// The hosted SBOM document bytes (byte-identical to what was attached).
    #[prost(bytes = "vec", tag = "1")]
    pub document: ::prost::alloc::vec::Vec<u8>,
    #[prost(int64, tag = "2")]
    pub size_bytes: i64,
    /// blake3 hex of the document (its content address).
    #[prost(string, tag = "3")]
    pub content_address: ::prost::alloc::string::String,
}
/// One property: a key with its ordered set of values (the map's entry form on
/// the wire, since proto has no first-class ordered multimap here).
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct PropertyEntry {
    #[prost(string, tag = "1")]
    pub key: ::prost::alloc::string::String,
    #[prost(string, repeated, tag = "2")]
    pub values: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct SetPropertyRequest {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    #[prost(message, optional, tag = "2")]
    pub artifact: ::core::option::Option<ArtifactId>,
    /// The property key to set (or, with empty `values`, remove).
    #[prost(string, tag = "3")]
    pub key: ::prost::alloc::string::String,
    /// The key's values (deduped, order preserved). EMPTY ⇒ remove the key.
    #[prost(string, repeated, tag = "4")]
    pub values: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SetPropertyResponse {
    #[prost(bool, tag = "1")]
    pub success: bool,
    #[prost(string, tag = "2")]
    pub message: ::prost::alloc::string::String,
    /// The coordinate's full property map AFTER the set/remove.
    #[prost(message, repeated, tag = "3")]
    pub properties: ::prost::alloc::vec::Vec<PropertyEntry>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct GetPropertiesRequest {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    #[prost(message, optional, tag = "2")]
    pub artifact: ::core::option::Option<ArtifactId>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetPropertiesResponse {
    /// The coordinate's full property map (empty when none attached).
    #[prost(message, repeated, tag = "1")]
    pub properties: ::prost::alloc::vec::Vec<PropertyEntry>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ReplicateRequest {
    /// Source repository — read-only here (only listed + fetched, never mutated).
    #[prost(string, tag = "1")]
    pub from_repo: ::prost::alloc::string::String,
    /// Destination repository — where artifacts land. MUST be writable.
    #[prost(string, tag = "2")]
    pub to_repo: ::prost::alloc::string::String,
    /// false (default) = dry-run PREVIEW (report what would copy, write nothing);
    /// true = actually copy the missing artifacts into the destination.
    #[prost(bool, tag = "3")]
    pub execute: bool,
    /// Cap the number of source artifacts examined; 0 = unlimited.
    #[prost(int32, tag = "4")]
    pub limit: i32,
    /// ASYNC SHAPE -- see `PromoteArtifactRequest.async_job`. True admits it to the
    /// job queue and answers with `job_id`. An EXECUTING replication on a server
    /// with a job queue is queued even when this is unset; a dry run, or a server
    /// without a queue, runs on this RPC and the caller waits.
    #[prost(bool, tag = "5")]
    pub async_job: bool,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ReplicateResponse {
    /// Total source artifacts examined.
    #[prost(int64, tag = "1")]
    pub examined: i64,
    /// Artifacts actually written into the destination (0 on a dry run).
    #[prost(int64, tag = "2")]
    pub copied: i64,
    /// Artifacts already present in the destination by content id (skipped).
    #[prost(int64, tag = "3")]
    pub skipped: i64,
    /// Artifacts a dry run WOULD copy (0 on an executing run).
    #[prost(int64, tag = "4")]
    pub would_copy: i64,
    /// Artifacts that could not be replicated (source unreadable / dest read-only).
    #[prost(int64, tag = "5")]
    pub failed: i64,
    /// Sum of bytes copied (0 on a dry run).
    #[prost(int64, tag = "6")]
    pub copied_bytes: i64,
    /// True when the `limit` cap was hit and more source artifacts remained.
    #[prost(bool, tag = "7")]
    pub truncated: bool,
    /// True when nothing failed — the replication is fully accounted for.
    #[prost(bool, tag = "8")]
    pub complete: bool,
    #[prost(string, tag = "9")]
    pub message: ::prost::alloc::string::String,
    /// Set ONLY when the request asked for the async shape: the admitted job's id.
    /// Every count above is 0 in that case -- nothing has run yet, and reporting a
    /// zero as a result would be a lie. Read the outcome with `JobService.GetJob`.
    #[prost(string, tag = "10")]
    pub job_id: ::prost::alloc::string::String,
}
/// Where a migration reads FROM, credentials included.
///
/// ⚠ The credential is a PARAMETER and lives in memory for the life of the job
/// alone. It is never written to disk, never echoed back by any RPC here, and
/// never audited. A one-shot move does not need a stored secret, and a stored
/// secret is a standing capability against someone else's registry that outlives
/// the reason it was given. Persisting one is a separate decision with its own
/// holder (`nornir-vault`), and it is not made here.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct MigrationSource {
    #[prost(enumeration = "migration_source::Kind", tag = "1")]
    pub kind: i32,
    /// Nexus: the base URL. Artifactory: the URL up to (not including)
    /// `/artifactory`.
    #[prost(string, tag = "2")]
    pub base_url: ::prost::alloc::string::String,
    /// Basic-auth credential. In memory only — see the warning above.
    #[prost(string, tag = "3")]
    pub username: ::prost::alloc::string::String,
    #[prost(string, tag = "4")]
    pub password: ::prost::alloc::string::String,
    /// Migrate only this ONE source repository. Empty = the whole registry.
    #[prost(string, tag = "5")]
    pub repository: ::prost::alloc::string::String,
}
/// Nested message and enum types in `MigrationSource`.
pub mod migration_source {
    #[derive(
        Clone,
        Copy,
        Debug,
        PartialEq,
        Eq,
        Hash,
        PartialOrd,
        Ord,
        ::prost::Enumeration
    )]
    #[repr(i32)]
    pub enum Kind {
        MigrationSourceUnspecified = 0,
        Nexus = 1,
        Artifactory = 2,
    }
    impl Kind {
        /// String value of the enum field names used in the ProtoBuf definition.
        ///
        /// The values are not transformed in any way and thus are considered stable
        /// (if the ProtoBuf definition does not change) and safe for programmatic use.
        pub fn as_str_name(&self) -> &'static str {
            match self {
                Self::MigrationSourceUnspecified => "MIGRATION_SOURCE_UNSPECIFIED",
                Self::Nexus => "NEXUS",
                Self::Artifactory => "ARTIFACTORY",
            }
        }
        /// Creates an enum from field names used in the ProtoBuf definition.
        pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
            match value {
                "MIGRATION_SOURCE_UNSPECIFIED" => Some(Self::MigrationSourceUnspecified),
                "NEXUS" => Some(Self::Nexus),
                "ARTIFACTORY" => Some(Self::Artifactory),
                _ => None,
            }
        }
    }
}
/// One source repository and what taking it would mean for holger.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct MigrationRepoPlan {
    #[prost(string, tag = "1")]
    pub source_repo: ::prost::alloc::string::String,
    /// The format string the SOURCE used, verbatim (`maven2`, `pypi`, `generic`).
    #[prost(string, tag = "2")]
    pub source_format: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub target_repo: ::prost::alloc::string::String,
    /// holger's `ron_repo_type` for the mapped format (`maven3`, `pip`, `raw`).
    /// Empty when holger has no format for what the source said.
    #[prost(string, tag = "4")]
    pub target_format: ::prost::alloc::string::String,
    /// `existing` | `create` | `collision` | `unmapped_format`.
    #[prost(string, tag = "5")]
    pub disposition: ::prost::alloc::string::String,
    /// Why this repository refuses, when it does. Empty otherwise.
    #[prost(string, tag = "6")]
    pub refusal_reason: ::prost::alloc::string::String,
    /// Assets the source LISTED. No artifact content was read to count them.
    #[prost(int64, tag = "7")]
    pub assets: i64,
    /// Sum of the sizes the source's listing advertised. 0 where it advertised
    /// none — which is "not stated", not "empty".
    #[prost(int64, tag = "8")]
    pub bytes: i64,
    /// The RON declaration an operator must add to the wired config, and restart,
    /// BEFORE this repository can be filled. Non-empty only for `create`.
    ///
    /// ⚠ holger cannot create a repository while it is running: the route table is
    /// built from the config at boot and is immutable for the process lifetime. So
    /// a `create` row is not a thing the migration will do — it is a thing a person
    /// must do first. Rendered by `traits::migrate::ron_declaration`, the same
    /// function the run-time refusal quotes, so the console and the terminal hand
    /// over one text and not two.
    #[prost(string, tag = "9")]
    pub declaration: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct DiscoverMigrationRequest {
    #[prost(message, optional, tag = "1")]
    pub source: ::core::option::Option<MigrationSource>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct DiscoverMigrationResponse {
    #[prost(message, repeated, tag = "1")]
    pub repos: ::prost::alloc::vec::Vec<MigrationRepoPlan>,
    #[prost(int64, tag = "2")]
    pub total_assets: i64,
    #[prost(int64, tag = "3")]
    pub total_bytes: i64,
    /// True when nothing refuses — this plan would actually run.
    #[prost(bool, tag = "4")]
    pub would_run: bool,
    /// One line per refusing repository. Non-empty iff `would_run` is false.
    #[prost(string, repeated, tag = "5")]
    pub refusals: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// The same human preview the CLI's `--dry-run` prints, rendered ONCE in
    /// `traits::migrate` so the UI and the terminal cannot describe the same plan
    /// in two different ways.
    #[prost(string, tag = "6")]
    pub report: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct StartMigrationRequest {
    #[prost(message, optional, tag = "1")]
    pub source: ::core::option::Option<MigrationSource>,
    /// In-flight asset transfers. 0 = the engine default.
    #[prost(int32, tag = "2")]
    pub concurrency: i32,
    /// ⚠ Inverted ON PURPOSE. proto3 has no field presence for a bool, so a
    /// `verify_digests` a caller forgot to set would arrive as false and silently
    /// turn the check off. The safe state has to be the zero value: leave this
    /// alone and every asset the source published a sha256 for is verified before
    /// it is stored.
    #[prost(bool, tag = "3")]
    pub skip_digest_verification: bool,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct StartMigrationResponse {
    /// Follow it with `Watch`, stop it with `Cancel`.
    #[prost(string, tag = "1")]
    pub job_id: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub message: ::prost::alloc::string::String,
    /// Echo of the plan the job started with, so a caller that skipped `Discover`
    /// still learns which repositories it is creating.
    #[prost(message, repeated, tag = "3")]
    pub repos: ::prost::alloc::vec::Vec<MigrationRepoPlan>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct WatchMigrationRequest {
    #[prost(string, tag = "1")]
    pub job_id: ::prost::alloc::string::String,
}
/// One progress row. A watcher that joins late receives the latest row for each
/// repository first, then follows live — so a UI that reconnects is not blind.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct MigrationProgressEvent {
    #[prost(string, tag = "1")]
    pub job_id: ::prost::alloc::string::String,
    /// The holger repository this row is about.
    #[prost(string, tag = "2")]
    pub repo: ::prost::alloc::string::String,
    /// Assets written into this repository so far.
    #[prost(int64, tag = "3")]
    pub done: i64,
    /// Assets that could not be moved.
    #[prost(int64, tag = "4")]
    pub failed: i64,
    /// Assets the destination already held — the idempotence count.
    #[prost(int64, tag = "5")]
    pub skipped: i64,
    /// Assets the source listed for this repository: the denominator.
    #[prost(int64, tag = "6")]
    pub total: i64,
    #[prost(int64, tag = "7")]
    pub bytes: i64,
    /// Last row for this repository.
    #[prost(bool, tag = "8")]
    pub repo_finished: bool,
    /// Last row for the whole job. The stream ends after it.
    #[prost(bool, tag = "9")]
    pub job_finished: bool,
    /// Only meaningful when `job_finished`: nothing failed and it was not cut
    /// short. A migration that "succeeded" with failures is one an operator would
    /// wrongly believe is done.
    #[prost(bool, tag = "10")]
    pub complete: bool,
    #[prost(bool, tag = "11")]
    pub cancelled: bool,
    #[prost(string, tag = "12")]
    pub message: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct CancelMigrationRequest {
    #[prost(string, tag = "1")]
    pub job_id: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct CancelMigrationResponse {
    /// True when the job was running and is now winding down. False when it had
    /// already finished — which is not an error, just an answer.
    #[prost(bool, tag = "1")]
    pub cancelling: bool,
    #[prost(string, tag = "2")]
    pub message: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct WhoAmIRequest {
    /// Optional. When set, the answer also carries the caller's role ON THIS
    /// repository (`repository_role`) — the per-repository ACL included, the same
    /// resolution the write and admin gates apply. A console asks this instead of
    /// deciding for itself what a person may do to a repository (holger-ui's
    /// thin-layer move, 2026-10-04: buying room for a repository is a write on it).
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct WhoAmIResponse {
    /// True when the presented credential validated against a configured method.
    #[prost(bool, tag = "1")]
    pub authenticated: bool,
    /// The validated principal (OIDC sub / StaticToken subject / mTLS CN).
    /// Empty for anonymous callers.
    #[prost(string, tag = "2")]
    pub subject: ::prost::alloc::string::String,
    /// Which configured method validated the credential (e.g. "bearer", "oidc",
    /// "mtls"). Empty for anonymous callers.
    #[prost(string, tag = "3")]
    pub method: ::prost::alloc::string::String,
    /// The caller's effective GLOBAL role name ("denied"/"reader"/"writer"/
    /// "admin"), from the RBAC map or the default role. Per-repo ACLs can grant
    /// or deny beyond this — this is discoverability, not authorization.
    #[prost(string, tag = "4")]
    pub global_role: ::prost::alloc::string::String,
    /// Whether the opt-in read gate (`require_auth_for_reads`) is active — with
    /// it on, even reads need the reader floor.
    #[prost(bool, tag = "5")]
    pub read_gate: bool,
    /// The caller's effective role on `WhoAmIRequest.repository`
    /// ("denied"/"reader"/"writer"/"admin"), per-repository ACL included. Empty
    /// when no repository was asked about.
    #[prost(string, tag = "6")]
    pub repository_role: ::prost::alloc::string::String,
    /// What is open on this Holger, in plain words (HCON-5: the RON's `access`
    /// block and its public repositories), read only.
    #[prost(string, tag = "7")]
    pub access_words: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ServerProfileResponse {
    /// "static" (sealed / read-only) or "dynamic" (writable / proxy).
    #[prost(string, tag = "1")]
    pub profile: ::prost::alloc::string::String,
    /// True when the server accepts no writes on any repository — server truth,
    /// derived from the live route table (or an explicit sealed-mode override).
    #[prost(bool, tag = "2")]
    pub read_only: bool,
    /// Human label for the UI chrome/badge (e.g. the red "silent running" strip).
    #[prost(string, tag = "3")]
    pub label: ::prost::alloc::string::String,
    /// Number of configured repositories that accept writes (0 ⇒ read_only).
    #[prost(int32, tag = "4")]
    pub writable_repo_count: i32,
    /// ── THE MODULE CENSUS ────────────────────────────────────────────────────
    ///
    /// An appliance has no shell. This is the only way an operator can ask "what
    /// is loaded here, and what may it do" — and the only way a test can ask it of
    /// a RUNNING box rather than of a build.
    ///
    /// A cargo feature's absence is provable in the symbol table. An uninstalled
    /// module's absence is only "a file that is not there", which is weaker. These
    /// three fields are where that strength is recovered.
    #[prost(message, repeated, tag = "5")]
    pub modules: ::prost::alloc::vec::Vec<LoadedModule>,
    /// The union of every capability granted to any module on this boot. A set
    /// that does not contain `principal.read`, `digest.read`, `clock.read` or
    /// `audit.write` proves "and none can be" from CONFIGURATION, without looking
    /// at a directory at all.
    #[prost(string, repeated, tag = "6")]
    pub granted_capabilities: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// The host functions actually defined on this boot's wasm linkers. A module
    /// importing anything outside this set fails INSTANTIATION, because the import
    /// is not defined — it is not merely refused at the call.
    #[prost(string, repeated, tag = "7")]
    pub linker_defines: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
}
/// One guest this boot loaded.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct LoadedModule {
    /// The name the module's own manifest declares.
    #[prost(string, tag = "1")]
    pub name: ::prost::alloc::string::String,
    /// "linked" for a guest compiled into this binary, or the module's file name
    /// for one loaded from the plugin directory.
    #[prost(string, tag = "2")]
    pub origin: ::prost::alloc::string::String,
    /// "package-handler" | "meter".
    #[prost(string, tag = "3")]
    pub kind: ::prost::alloc::string::String,
    /// Hex blake3-256 of the module bytes, over exactly what the detached CMS
    /// signature covers. EMPTY for a linked guest, which has no module bytes —
    /// and empty is distinguishable from a digest, which is the point.
    #[prost(string, tag = "4")]
    pub digest: ::prost::alloc::string::String,
    /// The verified signer this module arrived under, when a trust policy was in
    /// force. Empty means no provenance was REQUIRED — never "it failed and we
    /// carried on", which is a boot error.
    #[prost(string, tag = "5")]
    pub receipt: ::prost::alloc::string::String,
    /// What the operator granted THIS module, by name.
    #[prost(string, repeated, tag = "6")]
    pub granted: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct MeterReading {
    /// The meter's name, as monetize's holger plugin declares it: `artifacts`,
    /// `archive_bytes`, `bytes_served`, `requests`, `proxy_upstream_hits`, `repos`.
    #[prost(string, tag = "1")]
    pub name: ::prost::alloc::string::String,
    /// ⚠ MEANINGLESS unless `counted` is true. See below.
    #[prost(uint64, tag = "2")]
    pub value: u64,
    #[prost(enumeration = "MeterScope", tag = "3")]
    pub scope: i32,
    /// Where the number came from: the backend name, `metrics`, or whatever
    /// produced it. A reader that has to ask "who said this" has a number it
    /// cannot check.
    #[prost(string, tag = "4")]
    pub source: ::prost::alloc::string::String,
    /// **THE FALSE-ZERO GUARD.** `false` means this backend cannot answer this
    /// meter at all, and `value` is not a measurement — not a zero, not a
    /// default, not "empty".
    ///
    /// Four of holger's backends (`znippy-go`, `znippy-composer`, `znippy-docker`,
    /// `znippy-nuget`) never override `RepositoryBackendTrait::list` and answer the
    /// trait default, an empty listing. `list(...).unwrap_or(0)` stamped with a
    /// REPOSITORY scope reported a full repository as empty, and collapsed a
    /// genuine backend ERROR into the same 0 — so "the disk broke" and "nothing
    /// here" were one answer on the wire. A bill drawn from that is wrong in the
    /// customer's favour on a healthy box and wrong in ours on a broken one.
    ///
    /// A fold that treats `counted == false` as a zero is the bug this field
    /// exists to make impossible. monetize's own fold already counts an absent
    /// reading as a HOLE (`FleetTotal::tenants_without_reading`), which is the
    /// behaviour this field lets it keep.
    #[prost(bool, tag = "5")]
    pub counted: bool,
    /// Why not, by name, when `counted` is false. Empty when it is true.
    #[prost(string, tag = "6")]
    pub refusal_reason: ::prost::alloc::string::String,
}
/// A ceiling an order attached to one meter, echoed back so a tenant can see its
/// own. `limit` of 0 means NO CEILING -- it has never meant "may hold nothing".
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct MeterCap {
    #[prost(string, tag = "1")]
    pub meter: ::prost::alloc::string::String,
    #[prost(uint64, tag = "2")]
    pub limit: u64,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ReadUsageRequest {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ReadUsageResponse {
    #[prost(message, repeated, tag = "1")]
    pub meters: ::prost::alloc::vec::Vec<MeterReading>,
    /// When the reading was taken, Unix milliseconds — `monetize_product::Usage`
    /// carries the same field and will not invent one.
    #[prost(int64, tag = "2")]
    pub measured_at_unix_ms: i64,
    /// The ceilings in force for this repository, so a tenant can see its own.
    /// Empty in a build with no paid state, and empty is not "zero everywhere".
    #[prost(message, repeated, tag = "3")]
    pub caps: ::prost::alloc::vec::Vec<MeterCap>,
}
/// One row of the queue, as a reader sees it.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct JobRow {
    #[prost(string, tag = "1")]
    pub job_id: ::prost::alloc::string::String,
    /// `holger_promote` | `holger_replicate` | `holger_upload` | `holger_gate`.
    #[prost(string, tag = "2")]
    pub kind: ::prost::alloc::string::String,
    /// What it acts on, human-readable (`dev->prod:name:version`).
    #[prost(string, tag = "3")]
    pub target: ::prost::alloc::string::String,
    /// `queued` | `running` | `done` | `failed` | `interrupted`.
    ///
    /// `interrupted` is holger's own and is the point of the whole lane: a job that
    /// was running when the process died is named, with a reason, instead of being
    /// left `running` for ever (stinky 01 §6.2) or laundered into `failed`, which
    /// would claim it was tried and refused.
    #[prost(string, tag = "4")]
    pub status: ::prost::alloc::string::String,
    /// The idempotency key -- two jobs with the same content id are the same work.
    #[prost(string, tag = "5")]
    pub content_id: ::prost::alloc::string::String,
    /// Terminal result pointer: a seal's content address, a replication's counts.
    #[prost(string, tag = "6")]
    pub result_ref: ::prost::alloc::string::String,
    /// Why it failed or was interrupted. Empty otherwise -- never a placeholder.
    #[prost(string, tag = "7")]
    pub reason: ::prost::alloc::string::String,
    /// The authenticated principal that asked.
    #[prost(string, tag = "8")]
    pub requested_by: ::prost::alloc::string::String,
    #[prost(int64, tag = "9")]
    pub ts_start_micros: i64,
    #[prost(int64, tag = "10")]
    pub ts_end_micros: i64,
    #[prost(int64, tag = "11")]
    pub elapsed_ms: i64,
    /// What it is doing in the admin view's words: a pull-through (`holger_fetch`)
    /// or a mirror asset (`holger_mirror_asset`) reads `requested` -> `fetching` ->
    /// `done` | `failed`; every other kind reads its status word. A `failed` stage
    /// with `next_attempt_micros` set is a retry waiting (status `retry_wait`).
    #[prost(string, tag = "12")]
    pub stage: ::prost::alloc::string::String,
    /// Attempts made so far, and the ceiling (1 for the four original kinds).
    #[prost(uint32, tag = "13")]
    pub attempts: u32,
    #[prost(uint32, tag = "14")]
    pub max_attempts: u32,
    /// When a `retry_wait` job runs again (µs since the epoch); 0 = not waiting.
    #[prost(int64, tag = "15")]
    pub next_attempt_micros: i64,
    /// Pending-list priority from the consumer's admission class: 0 Full,
    /// 1 Reduced, 2 Floor, 3 Queued. Lower runs first.
    #[prost(uint32, tag = "16")]
    pub priority: u32,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct GetJobRequest {
    #[prost(string, tag = "1")]
    pub job_id: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct GetJobResponse {
    /// False when the ledger holds no such job -- the row below is then empty, and
    /// "not found" is not spelled as an all-zero job.
    #[prost(bool, tag = "1")]
    pub found: bool,
    #[prost(message, optional, tag = "2")]
    pub job: ::core::option::Option<JobRow>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ListJobsRequest {
    /// Filter by kind; empty = every kind.
    #[prost(string, tag = "1")]
    pub kind: ::prost::alloc::string::String,
    /// Cap the rows returned; 0 = every row the ledger holds.
    #[prost(int32, tag = "2")]
    pub limit: i32,
    /// Filter by state: empty = all; `waiting` (queued, or failed with a retry
    /// scheduled), `running`, `failed` (terminal failed or interrupted, AND
    /// retry_wait — every row with a reason), `done`.
    #[prost(string, tag = "3")]
    pub state: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListJobsResponse {
    #[prost(message, repeated, tag = "1")]
    pub jobs: ::prost::alloc::vec::Vec<JobRow>,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminSnapshotRequest {
    /// How many of the newest log lines to return; 0 = 200, capped at 2000.
    #[prost(uint32, tag = "1")]
    pub log_lines: u32,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdminSnapshotReply {
    /// When this was taken, by the estate clock (Unix ms), and by whom.
    #[prost(int64, tag = "1")]
    pub taken_unix_ms: i64,
    #[prost(string, tag = "2")]
    pub host: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub version: ::prost::alloc::string::String,
    #[prost(uint64, tag = "4")]
    pub uptime_seconds: u64,
    /// "primary" | "twin".
    #[prost(string, tag = "5")]
    pub role: ::prost::alloc::string::String,
    #[prost(message, optional, tag = "6")]
    pub disks: ::core::option::Option<AdminDisks>,
    #[prost(message, optional, tag = "7")]
    pub twin: ::core::option::Option<AdminTwin>,
    #[prost(message, optional, tag = "8")]
    pub growth: ::core::option::Option<AdminGrowth>,
    #[prost(message, optional, tag = "9")]
    pub clock: ::core::option::Option<AdminClock>,
    #[prost(message, optional, tag = "10")]
    pub plugins: ::core::option::Option<AdminPlugins>,
    #[prost(message, optional, tag = "11")]
    pub audit: ::core::option::Option<AdminAudit>,
    #[prost(message, optional, tag = "12")]
    pub logs: ::core::option::Option<AdminLogs>,
    #[prost(message, optional, tag = "13")]
    pub payments: ::core::option::Option<AdminPayments>,
    /// The disk speed test over the data root (edda disk-snapshot `speed`), run
    /// ONCE at start on its own thread. `measured` false = not run yet / skipped /
    /// failed, with the reason: the console says N/A, never a zero.
    #[prost(message, optional, tag = "14")]
    pub disk_speed: ::core::option::Option<AdminDiskSpeed>,
    /// Every repository (monetize's TENANT for holger): what it holds on disk,
    /// whether those bytes are a CACHE (a repository with an upstream: pull-through
    /// or proxy), and its paid `disk_bytes` cap (the metered build's entitlement).
    #[prost(message, repeated, tag = "15")]
    pub tenants: ::prost::alloc::vec::Vec<AdminTenant>,
    /// The redb job queue's depth, by status.
    #[prost(message, optional, tag = "16")]
    pub queue: ::core::option::Option<AdminQueue>,
    /// Every paired downstream as this upstream last heard from it: the rows of
    /// holger.grow.v1 GrowService.Downstreams, field for field (the twins are
    /// `twin.twins`, GrowService.Twins). The console's Sync view reads both.
    #[prost(message, repeated, tag = "17")]
    pub downstreams: ::prost::alloc::vec::Vec<AdminDownstreamRow>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdminDiskSpeed {
    #[prost(bool, tag = "1")]
    pub measured: bool,
    /// The directory measured (the data root).
    #[prost(string, tag = "2")]
    pub path: ::prost::alloc::string::String,
    /// Sequential write + fsync, and the read back off the device, bytes/s.
    #[prost(double, tag = "3")]
    pub seq_write_bps: f64,
    #[prost(double, tag = "4")]
    pub seq_read_bps: f64,
    /// direct (O_DIRECT) | dropped (the page cache dropped first)
    #[prost(string, tag = "5")]
    pub read_how: ::prost::alloc::string::String,
    /// The read was faster than any disk (> 5 GB/s): the cache answered, so the
    /// read figure is not a disk speed.
    #[prost(bool, tag = "6")]
    pub read_cached: bool,
    /// 4 KiB overwrites, each fdatasync'd, per second.
    #[prost(double, tag = "7")]
    pub sync_4k_ops_per_s: f64,
    #[prost(double, tag = "8")]
    pub seconds: f64,
    #[prost(int64, tag = "9")]
    pub at_unix_ms: i64,
    /// Why there is no figure (not run yet, skipped for free space, failed).
    #[prost(string, tag = "10")]
    pub why: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminTenant {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    /// The repository has an upstream: what it holds is a cache.
    #[prost(bool, tag = "2")]
    pub cache: bool,
    #[prost(string, repeated, tag = "3")]
    pub upstreams: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// `disk_bytes` as the meter counts it; `used_measured` false with `used_why`
    /// when it could not be counted (a group owns none, no storage yet …).
    #[prost(bool, tag = "4")]
    pub used_measured: bool,
    #[prost(uint64, tag = "5")]
    pub used_bytes: u64,
    #[prost(string, tag = "6")]
    pub used_why: ::prost::alloc::string::String,
    /// The paid cap (quota): `has_cap` false with `cap_why` when none is known.
    #[prost(bool, tag = "7")]
    pub has_cap: bool,
    #[prost(uint64, tag = "8")]
    pub cap_bytes: u64,
    #[prost(string, tag = "9")]
    pub cap_why: ::prost::alloc::string::String,
    /// The entitlement's state (active | grace | suspended …) when one exists.
    #[prost(string, tag = "10")]
    pub state: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdminQueue {
    /// False when this server carries no job queue (built or configured without it).
    #[prost(bool, tag = "1")]
    pub present: bool,
    #[prost(string, tag = "2")]
    pub why: ::prost::alloc::string::String,
    /// Jobs not in a terminal state (queued, running, waiting to retry).
    #[prost(uint64, tag = "3")]
    pub open: u64,
    /// status word → count, over the newest `scanned` jobs.
    #[prost(map = "string, uint64", tag = "4")]
    pub by_status: ::std::collections::HashMap<::prost::alloc::string::String, u64>,
    #[prost(uint64, tag = "5")]
    pub scanned: u64,
    #[prost(uint32, tag = "6")]
    pub workers: u32,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdminDisks {
    /// Every storage mount (pseudo filesystems left out), with holger's labels
    /// on the mount each labelled path sits on: `system` (/), `data` (the data
    /// root), `storage:<repo>` (a repository's archive or files).
    #[prost(message, repeated, tag = "1")]
    pub mounts: ::prost::alloc::vec::Vec<AdminDisk>,
    #[prost(message, repeated, tag = "2")]
    pub block_devices: ::prost::alloc::vec::Vec<AdminBlockDevice>,
    /// A labelled path that sits on no mount, with the reason.
    #[prost(message, repeated, tag = "3")]
    pub unresolved: ::prost::alloc::vec::Vec<AdminUnresolved>,
    /// Why the mount table or /sys/block could not be read.
    #[prost(string, repeated, tag = "4")]
    pub problems: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// The rule the floor figures were computed with, in words — and whether
    /// holger enforces it (it does not, today: the floor is advisory).
    #[prost(string, tag = "5")]
    pub floor_rule: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminDisk {
    #[prost(string, tag = "1")]
    pub source: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub mount_point: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub fstype: ::prost::alloc::string::String,
    #[prost(bool, tag = "4")]
    pub read_only: bool,
    #[prost(string, repeated, tag = "5")]
    pub labels: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    #[prost(string, repeated, tag = "6")]
    pub paths: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// statvfs(3), in bytes. All 0 with `error` set when it could not be taken.
    #[prost(uint64, tag = "7")]
    pub total_bytes: u64,
    #[prost(uint64, tag = "8")]
    pub free_bytes: u64,
    #[prost(uint64, tag = "9")]
    pub available_bytes: u64,
    #[prost(uint64, tag = "10")]
    pub used_bytes: u64,
    #[prost(uint64, tag = "11")]
    pub reserved_bytes: u64,
    #[prost(uint64, tag = "12")]
    pub inodes_total: u64,
    #[prost(uint64, tag = "13")]
    pub inodes_free: u64,
    #[prost(uint64, tag = "14")]
    pub block_size: u64,
    #[prost(uint64, tag = "15")]
    pub floor_bytes: u64,
    /// available − floor.
    #[prost(uint64, tag = "16")]
    pub servable_bytes: u64,
    #[prost(uint32, tag = "17")]
    pub used_permille: u32,
    #[prost(string, tag = "18")]
    pub error: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminPartition {
    #[prost(string, tag = "1")]
    pub name: ::prost::alloc::string::String,
    #[prost(uint64, tag = "2")]
    pub size_bytes: u64,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdminBlockDevice {
    #[prost(string, tag = "1")]
    pub name: ::prost::alloc::string::String,
    #[prost(uint64, tag = "2")]
    pub size_bytes: u64,
    #[prost(bool, tag = "3")]
    pub rotational: bool,
    #[prost(bool, tag = "4")]
    pub removable: bool,
    #[prost(bool, tag = "5")]
    pub read_only: bool,
    #[prost(message, repeated, tag = "6")]
    pub partitions: ::prost::alloc::vec::Vec<AdminPartition>,
    /// What holds it or one of its partitions (md127, dm-0).
    #[prost(string, repeated, tag = "7")]
    pub holders: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// What it is built from (an array's members).
    #[prost(string, repeated, tag = "8")]
    pub members: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    #[prost(string, tag = "9")]
    pub raid_level: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminUnresolved {
    #[prost(string, tag = "1")]
    pub label: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub path: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub why: ::prost::alloc::string::String,
    /// True for a repository's storage folder (`storage:<repo>`) that does not exist yet:
    /// holger creates it at the first upload, so it is no fault, and `why` says that
    /// (lane HOL-UI-FIX). False for every other path that sits on no mount.
    #[prost(bool, tag = "4")]
    pub made_at_first_upload: bool,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdminTwin {
    /// "primary" | "twin".
    #[prost(string, tag = "1")]
    pub role: ::prost::alloc::string::String,
    /// The primary a twin follows.
    #[prost(string, tag = "2")]
    pub primary: ::prost::alloc::string::String,
    #[prost(bool, tag = "3")]
    pub serving: bool,
    #[prost(bool, tag = "4")]
    pub accepts_writes: bool,
    /// A box awaiting its recharge serves nothing; the source it waits for.
    #[prost(string, tag = "5")]
    pub awaiting_recharge_from: ::prost::alloc::string::String,
    /// A twin: is it alive and whole — how it last followed, whether its last
    /// cycle that reached the primary was whole, when the last whole one ended,
    /// and the lag: now − that end, seconds (−1 = never whole).
    #[prost(string, tag = "6")]
    pub follow: ::prost::alloc::string::String,
    #[prost(bool, tag = "7")]
    pub complete: bool,
    #[prost(string, tag = "8")]
    pub why: ::prost::alloc::string::String,
    #[prost(int64, tag = "9")]
    pub last_whole_unix: i64,
    #[prost(int64, tag = "10")]
    pub lag_seconds: i64,
    /// The storage invariant's verdict warning (empty when none).
    #[prost(string, tag = "11")]
    pub store_warning: ::prost::alloc::string::String,
    /// The replication door on this box: refusals by name and admitted peers.
    #[prost(uint64, tag = "12")]
    pub door_refused: u64,
    #[prost(string, tag = "13")]
    pub door_last_refusal: ::prost::alloc::string::String,
    #[prost(map = "string, uint64", tag = "14")]
    pub door_admitted: ::std::collections::HashMap<::prost::alloc::string::String, u64>,
    /// The mTLS credentials this box holds (purpose "twin", "recharge").
    #[prost(message, repeated, tag = "15")]
    pub credentials: ::prost::alloc::vec::Vec<AdminTwinCredential>,
    /// A primary: every enrolled twin, as its reports say.
    #[prost(message, repeated, tag = "16")]
    pub twins: ::prost::alloc::vec::Vec<AdminTwinRow>,
    #[prost(string, tag = "17")]
    pub twins_error: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminTwinCredential {
    #[prost(string, tag = "1")]
    pub purpose: ::prost::alloc::string::String,
    #[prost(bool, tag = "2")]
    pub installed: bool,
    /// The leaf's CN, the pinned issuer's CN.
    #[prost(string, tag = "3")]
    pub principal: ::prost::alloc::string::String,
    #[prost(string, tag = "4")]
    pub issuer: ::prost::alloc::string::String,
    #[prost(int64, tag = "5")]
    pub not_after_unix: i64,
    #[prost(int64, tag = "6")]
    pub days_left: i64,
    #[prost(string, repeated, tag = "7")]
    pub doors: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// Why it could not be read (a half-installed credential is an error).
    #[prost(string, tag = "8")]
    pub error: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminTwinRow {
    #[prost(string, tag = "1")]
    pub principal: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub address: ::prost::alloc::string::String,
    /// ok | behind | stalled | silent — stalled: still reporting, the applied
    /// position unchanged with the head ahead for longer than TWIN_STALLED_AFTER_MS
    #[prost(string, tag = "3")]
    pub state: ::prost::alloc::string::String,
    #[prost(int64, tag = "4")]
    pub last_seen_unix_ms: i64,
    #[prost(uint64, tag = "5")]
    pub lag_entries: u64,
    #[prost(uint64, tag = "6")]
    pub disk_total_bytes: u64,
    #[prost(uint64, tag = "7")]
    pub disk_used_bytes: u64,
    #[prost(uint32, tag = "8")]
    pub fill_permille: u32,
    /// The last synced point and today's pulls (holger.grow.v1 TwinRow 9, 10, 15, 16).
    #[prost(uint64, tag = "9")]
    pub applied_seq: u64,
    #[prost(uint64, tag = "10")]
    pub head_seq: u64,
    #[prost(uint64, tag = "11")]
    pub pulls_today: u64,
    #[prost(int64, tag = "12")]
    pub last_pull_unix: i64,
}
/// One paired downstream (holger.grow.v1 DownstreamRow, field for field).
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdminDownstreamRow {
    #[prost(string, tag = "1")]
    pub name: ::prost::alloc::string::String,
    /// `sha256:<64 hex>` of the paired client certificate.
    #[prost(string, tag = "2")]
    pub fingerprint: ::prost::alloc::string::String,
    /// ok | behind | stalled | silent — the worst repository's; `silent` when never heard.
    #[prost(string, tag = "3")]
    pub state: ::prost::alloc::string::String,
    #[prost(bool, tag = "4")]
    pub stalled: bool,
    /// The largest repository lag.
    #[prost(uint64, tag = "5")]
    pub lag_entries: u64,
    #[prost(int64, tag = "6")]
    pub last_seen_unix_ms: i64,
    #[prost(uint64, tag = "7")]
    pub seen_ago_ms: u64,
    #[prost(uint32, tag = "8")]
    pub every_secs: u32,
    #[prost(message, repeated, tag = "9")]
    pub repositories: ::prost::alloc::vec::Vec<AdminDownstreamRepo>,
    /// Today's pulls (UTC day, since this process started) and the last one.
    #[prost(uint64, tag = "10")]
    pub requests_today: u64,
    #[prost(uint64, tag = "11")]
    pub bytes_today: u64,
    #[prost(int64, tag = "12")]
    pub last_pull_unix: i64,
}
/// One paired repository's sync point (holger.grow.v1 DownstreamRepoRow).
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminDownstreamRepo {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    /// ok | behind | stalled | silent — TwinRow.state's words and rule.
    #[prost(string, tag = "2")]
    pub state: ::prost::alloc::string::String,
    #[prost(uint64, tag = "3")]
    pub lag_entries: u64,
    #[prost(uint64, tag = "4")]
    pub applied_seq: u64,
    #[prost(uint64, tag = "5")]
    pub head_seq: u64,
    /// When the last complete cycle of this repository ended; 0 = never.
    #[prost(int64, tag = "6")]
    pub last_complete_unix_ms: i64,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminGrowMember {
    #[prost(uint32, tag = "1")]
    pub index: u32,
    #[prost(string, tag = "2")]
    pub device: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub partition: ::prost::alloc::string::String,
    #[prost(uint64, tag = "4")]
    pub disk_bytes: u64,
    #[prost(uint64, tag = "5")]
    pub set_bytes: u64,
    #[prost(uint64, tag = "6")]
    pub offered_bytes: u64,
    #[prost(bool, tag = "7")]
    pub larger: bool,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdminGrowth {
    /// False when this process holds no growth plane (a bare service).
    #[prost(bool, tag = "1")]
    pub present: bool,
    #[prost(string, tag = "2")]
    pub phase: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub why: ::prost::alloc::string::String,
    #[prost(uint64, tag = "4")]
    pub epoch: u64,
    #[prost(bool, tag = "5")]
    pub serving: bool,
    #[prost(bool, tag = "6")]
    pub engine_present: bool,
    #[prost(bool, tag = "7")]
    pub hotplug: bool,
    #[prost(uint64, tag = "8")]
    pub in_flight: u64,
    #[prost(int64, tag = "9")]
    pub since_unix_ms: i64,
    #[prost(string, tag = "10")]
    pub detail: ::prost::alloc::string::String,
    #[prost(string, tag = "11")]
    pub set_uuid: ::prost::alloc::string::String,
    #[prost(uint64, tag = "12")]
    pub total_bytes: u64,
    #[prost(message, repeated, tag = "13")]
    pub members: ::prost::alloc::vec::Vec<AdminGrowMember>,
    #[prost(string, tag = "14")]
    pub members_verdict: ::prost::alloc::string::String,
    /// THE HISTORY: the boot stack's grow journal — its phase, the steps it
    /// took in order, the members a partial growth left behind, where it lives.
    #[prost(string, tag = "15")]
    pub journal_phase: ::prost::alloc::string::String,
    #[prost(string, repeated, tag = "16")]
    pub journal_steps: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    #[prost(uint32, repeated, tag = "17")]
    pub journal_partial_members: ::prost::alloc::vec::Vec<u32>,
    #[prost(string, tag = "18")]
    pub journal_detail: ::prost::alloc::string::String,
    #[prost(string, tag = "19")]
    pub journal_path: ::prost::alloc::string::String,
    /// The capacity ladder's verdict over this machine.
    #[prost(enumeration = "SetGrowth", tag = "20")]
    pub capacity_growth: i32,
    #[prost(string, tag = "21")]
    pub capacity_growth_reason: ::prost::alloc::string::String,
    #[prost(string, tag = "22")]
    pub data_set: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminClockSource {
    #[prost(string, tag = "1")]
    pub source: ::prost::alloc::string::String,
    #[prost(bool, tag = "2")]
    pub answered: bool,
    #[prost(int64, tag = "3")]
    pub offset_ms: i64,
    #[prost(string, tag = "4")]
    pub error: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdminClockSync {
    /// timer | boot | fed | …
    #[prost(string, tag = "1")]
    pub trigger: ::prost::alloc::string::String,
    #[prost(int64, tag = "2")]
    pub at_unix_ms: i64,
    /// stepped | slewed | already-right | apply-failed | no-quorum | …
    #[prost(string, tag = "3")]
    pub outcome: ::prost::alloc::string::String,
    #[prost(bool, tag = "4")]
    pub vouches: bool,
    #[prost(int64, tag = "5")]
    pub offset_ms: i64,
    #[prost(string, tag = "6")]
    pub detail: ::prost::alloc::string::String,
    #[prost(message, repeated, tag = "7")]
    pub sources: ::prost::alloc::vec::Vec<AdminClockSource>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdminClock {
    /// Whether a verified answer from the front stands behind holger's clock.
    #[prost(bool, tag = "1")]
    pub trusted: bool,
    /// The correction held in-process (the machine's clock was not moved), ms.
    #[prost(int64, tag = "2")]
    pub owed_ms: i64,
    /// The configuration in force, in words (or why it is refused).
    #[prost(string, tag = "3")]
    pub config: ::prost::alloc::string::String,
    #[prost(int64, tag = "4")]
    pub estate_unix_ms: i64,
    #[prost(int64, tag = "5")]
    pub system_unix_ms: i64,
    /// Absent (not synced yet) when `has_last` is false.
    #[prost(bool, tag = "6")]
    pub has_last: bool,
    #[prost(message, optional, tag = "7")]
    pub last: ::core::option::Option<AdminClockSync>,
    #[prost(bool, tag = "8")]
    pub has_boot: bool,
    #[prost(message, optional, tag = "9")]
    pub boot: ::core::option::Option<AdminClockSync>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminSelfRegistration {
    /// False when this build or box does not register a plugin at all.
    #[prost(bool, tag = "1")]
    pub active: bool,
    /// The last line the registration said, and whether it was taken.
    #[prost(string, tag = "2")]
    pub line: ::prost::alloc::string::String,
    #[prost(bool, tag = "3")]
    pub registered: bool,
    #[prost(bool, tag = "4")]
    pub warning: bool,
    #[prost(int64, tag = "5")]
    pub at_unix_ms: i64,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminEntitlement {
    #[prost(string, tag = "1")]
    pub repository: ::prost::alloc::string::String,
    /// The fact's caps, `name=value`, as signed.
    #[prost(string, repeated, tag = "2")]
    pub caps: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// active | grace | suspended | … (monetize's State), when paid until (Unix
    /// ms; 0 = open-ended), and where the fact came from (operator | payment:…).
    #[prost(string, tag = "3")]
    pub state: ::prost::alloc::string::String,
    #[prost(uint64, tag = "4")]
    pub paid_until_unix_ms: u64,
    #[prost(string, tag = "5")]
    pub source: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdminPlugins {
    /// What this boot loaded (ServerProfile's census, verbatim).
    #[prost(message, repeated, tag = "1")]
    pub modules: ::prost::alloc::vec::Vec<LoadedModule>,
    #[prost(string, repeated, tag = "2")]
    pub granted_capabilities: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    #[prost(uint32, tag = "3")]
    pub meters: u32,
    /// True when this is the metered build (it carries monetize's seam).
    #[prost(bool, tag = "4")]
    pub metered_build: bool,
    /// The metered build's entitlement store: configured with monetize's key?
    #[prost(bool, tag = "5")]
    pub entitlements_configured: bool,
    #[prost(message, repeated, tag = "6")]
    pub entitlements: ::prost::alloc::vec::Vec<AdminEntitlement>,
    #[prost(message, optional, tag = "7")]
    pub self_registration: ::core::option::Option<AdminSelfRegistration>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminAudit {
    /// everything | aggregated | off
    #[prost(string, tag = "1")]
    pub mode: ::prost::alloc::string::String,
    /// "directory <path>" | "memory" | "none".
    #[prost(string, tag = "2")]
    pub source: ::prost::alloc::string::String,
    #[prost(uint64, tag = "3")]
    pub segments: u64,
    #[prost(uint64, tag = "4")]
    pub total_rows: u64,
    #[prost(uint64, tag = "5")]
    pub total_bytes: u64,
    #[prost(int64, tag = "6")]
    pub first_ts_nanos: i64,
    #[prost(int64, tag = "7")]
    pub last_ts_nanos: i64,
    #[prost(string, tag = "8")]
    pub error: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminLogs {
    /// False when this process carries no installer log (not an installer-built box).
    #[prost(bool, tag = "1")]
    pub present: bool,
    /// The installer's log door: "install" (the installer is still at work) or
    /// "log-door" (closed: the same listener serves only GET /install/log to the
    /// installer's certificate).
    #[prost(string, tag = "2")]
    pub door: ::prost::alloc::string::String,
    #[prost(bool, tag = "3")]
    pub closed: bool,
    #[prost(uint64, tag = "4")]
    pub lines_total: u64,
    #[prost(uint64, tag = "5")]
    pub lines_dropped: u64,
    /// The newest lines, oldest first.
    #[prost(string, repeated, tag = "6")]
    pub tail: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdminPayments {
    /// The Stripe webhook's last ACCEPTED delivery is kept by monetize on the
    /// front, not by holger; 0 with `note` saying where it is not measured.
    #[prost(int64, tag = "1")]
    pub stripe_last_delivery_unix_ms: i64,
    #[prost(string, tag = "2")]
    pub note: ::prost::alloc::string::String,
}
/// The six units a box runs out of (`edda_admit::Cost`). Bytes except cpu_ms.
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct CostRow {
    #[prost(uint64, tag = "1")]
    pub cpu_ms: u64,
    #[prost(uint64, tag = "2")]
    pub disk_read: u64,
    #[prost(uint64, tag = "3")]
    pub disk_write: u64,
    #[prost(uint64, tag = "4")]
    pub net_in: u64,
    #[prost(uint64, tag = "5")]
    pub net_out: u64,
    #[prost(uint64, tag = "6")]
    pub upstream_fetch: u64,
}
/// One work kind's numbers for one consumer.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct WorkUsageRow {
    /// `download` | `upload` | `pull_through` | `mirror_asset`.
    #[prost(string, tag = "1")]
    pub work: ::prost::alloc::string::String,
    #[prost(uint64, tag = "2")]
    pub requests: u64,
    #[prost(uint64, tag = "3")]
    pub refused: u64,
    #[prost(message, optional, tag = "4")]
    pub estimated: ::core::option::Option<CostRow>,
    #[prost(message, optional, tag = "5")]
    pub actual: ::core::option::Option<CostRow>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct UsageRow {
    /// `principal:<sub>` | `peer:<name>` | `anon:<day>:<8 hex>`.
    #[prost(string, tag = "1")]
    pub consumer: ::prost::alloc::string::String,
    /// Actual cost over the policy's window, and today (UTC).
    #[prost(message, optional, tag = "2")]
    pub window: ::core::option::Option<CostRow>,
    #[prost(message, optional, tag = "3")]
    pub today: ::core::option::Option<CostRow>,
    #[prost(message, repeated, tag = "4")]
    pub by_work: ::prost::alloc::vec::Vec<WorkUsageRow>,
    /// The class the last plan gave it (`full` | `reduced` | `floor` | `queued`,
    /// empty before any plan), and the plan's sentence.
    #[prost(string, tag = "5")]
    pub class: ::prost::alloc::string::String,
    #[prost(string, tag = "6")]
    pub why: ::prost::alloc::string::String,
    #[prost(uint32, tag = "7")]
    pub in_flight: u32,
}
/// The policy's learnt estimate for one work kind (`Admit::estimates`).
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct EstimateRow {
    #[prost(string, tag = "1")]
    pub kind: ::prost::alloc::string::String,
    #[prost(uint64, tag = "2")]
    pub samples: u64,
    #[prost(uint64, tag = "3")]
    pub hinted: u64,
    #[prost(message, optional, tag = "4")]
    pub mean: ::core::option::Option<CostRow>,
    /// Cost of one GB of hinted size; absent before any hinted sample.
    #[prost(message, optional, tag = "5")]
    pub per_gb: ::core::option::Option<CostRow>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AdmitPlanRequest {
    /// `principal:<sub>` | `peer:<name>` | `anonymous` (a probe token for today).
    #[prost(string, tag = "1")]
    pub consumer: ::prost::alloc::string::String,
    /// `download` (default) | `upload` | `pull_through` | `mirror_asset`.
    #[prost(string, tag = "2")]
    pub work: ::prost::alloc::string::String,
    /// Size hint in bytes; 0 = none.
    #[prost(uint64, tag = "3")]
    pub size_hint: u64,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdmitPlanResponse {
    #[prost(string, tag = "1")]
    pub consumer: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub work: ::prost::alloc::string::String,
    #[prost(string, tag = "3")]
    pub class: ::prost::alloc::string::String,
    #[prost(message, optional, tag = "4")]
    pub estimate: ::core::option::Option<CostRow>,
    #[prost(string, tag = "5")]
    pub why: ::prost::alloc::string::String,
    /// Bytes left in the window; absent = unlimited.
    #[prost(uint64, optional, tag = "6")]
    pub budget_left: ::core::option::Option<u64>,
    /// Concurrent requests this class gets at the door; absent = no share
    /// enforced (no `admission:` block).
    #[prost(uint32, optional, tag = "7")]
    pub share: ::core::option::Option<u32>,
    #[prost(string, tag = "8")]
    pub policy: ::prost::alloc::string::String,
    #[prost(message, repeated, tag = "9")]
    pub estimates: ::prost::alloc::vec::Vec<EstimateRow>,
    /// The consumer's usage row (absent when the book has none).
    #[prost(message, optional, tag = "10")]
    pub usage: ::core::option::Option<UsageRow>,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ListUsageRequest {
    /// Cap the rows; 0 = all.
    #[prost(int32, tag = "1")]
    pub limit: i32,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListUsageResponse {
    #[prost(string, tag = "1")]
    pub policy: ::prost::alloc::string::String,
    #[prost(message, repeated, tag = "2")]
    pub consumers: ::prost::alloc::vec::Vec<UsageRow>,
    /// Requests in flight through the door right now, all consumers.
    #[prost(uint32, tag = "3")]
    pub in_flight_total: u32,
    /// The door's ceiling and the per-class shares; absent = none enforced.
    #[prost(uint32, optional, tag = "4")]
    pub max_in_flight: ::core::option::Option<u32>,
    #[prost(uint32, optional, tag = "5")]
    pub share_full: ::core::option::Option<u32>,
    #[prost(uint32, optional, tag = "6")]
    pub share_reduced: ::core::option::Option<u32>,
    #[prost(uint32, optional, tag = "7")]
    pub share_floor: ::core::option::Option<u32>,
    /// Whether proxy pull-through runs on the job queue.
    #[prost(bool, tag = "8")]
    pub pull_through_queue: bool,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct SecuritySummaryRequest {}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SecuritySummaryReply {
    /// One line over the page, in the server's words.
    #[prost(string, tag = "1")]
    pub headline: ::prost::alloc::string::String,
    /// The sections, in the order the page shows them (keys: chain, sources, scanners,
    /// approvals, held, access, sync, events).
    #[prost(message, repeated, tag = "2")]
    pub sections: ::prost::alloc::vec::Vec<SecuritySection>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SecuritySection {
    /// A stable key (`chain`, `scanners`, …); the console keys its markup on it, never its words.
    #[prost(string, tag = "1")]
    pub key: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub title: ::prost::alloc::string::String,
    /// One or two sentences under the title.
    #[prost(string, tag = "3")]
    pub summary: ::prost::alloc::string::String,
    /// What to say when there are no rows.
    #[prost(string, tag = "4")]
    pub empty: ::prost::alloc::string::String,
    #[prost(message, repeated, tag = "5")]
    pub rows: ::prost::alloc::vec::Vec<SecurityRow>,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct SecurityRow {
    /// What the row is about: a step, a source, a scanner, an artifact, a repository, an event.
    #[prost(string, tag = "1")]
    pub name: ::prost::alloc::string::String,
    /// One short word for its state (`required`, `quarantined`, `public`, …).
    #[prost(string, tag = "2")]
    pub state: ::prost::alloc::string::String,
    /// `good` | `warn` | `bad` | `info`: how the state reads.
    #[prost(string, tag = "3")]
    pub tone: ::prost::alloc::string::String,
    /// The rest, in plain words: why, what it checks, who, when.
    #[prost(string, tag = "4")]
    pub detail: ::prost::alloc::string::String,
    /// The artifact the row is about, when it is one (the console links its security view).
    #[prost(message, optional, tag = "5")]
    pub artifact: ::core::option::Option<ArtifactId>,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct TopologyRequest {}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct TopologyReply {
    /// This box first, then the others in a stable order: front, primary, twins,
    /// downstreams, each by name.
    #[prost(message, repeated, tag = "1")]
    pub boxes: ::prost::alloc::vec::Vec<TopologyBox>,
    /// This server's own clock when it answered (Unix ms).
    #[prost(int64, tag = "2")]
    pub server_unix_ms: i64,
    /// The silence bound every `state` below was judged against, in ms.
    #[prost(uint64, tag = "3")]
    pub silent_after_ms: u64,
    /// The estate's name from the pairing feed; empty on a holger nobody paired.
    #[prost(string, tag = "4")]
    pub estate: ::prost::alloc::string::String,
    /// The links between the boxes: front → primary, primary → twin, primary →
    /// each downstream. Each carries the state of the box it leads INTO.
    #[prost(message, repeated, tag = "5")]
    pub links: ::prost::alloc::vec::Vec<TopologyLink>,
    /// RETIRED (Holger v2.0 H2): always empty. The server draws nothing; holger-ui
    /// draws the board from `boxes` and `links`. Kept so the tag is never reused.
    #[prost(string, tag = "6")]
    pub svg: ::prost::alloc::string::String,
    /// **Every consumer this box serves** (lane A13): named and anonymous, as the
    /// door admission's book counts them. Unset = this build keeps no book.
    #[prost(message, optional, tag = "7")]
    pub consumers: ::core::option::Option<TopologyConsumers>,
    /// **The board in one line, holger's words** (lane A13): the line drawn under
    /// the title — how many upstreams and downstreams, and every consumer — for a
    /// console's text alternative, rendered as it came.
    #[prost(string, tag = "8")]
    pub summary: ::prost::alloc::string::String,
}
/// **Who consumes this box** (lane A13, 2026-10-23), from the door admission's
/// usage book: every request asks it once, whatever the policy.
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct TopologyConsumers {
    /// False when this build keeps no book: then the numbers below are not counts.
    #[prost(bool, tag = "1")]
    pub counted: bool,
    /// Authenticated principals with a request in the window (durable: the book's
    /// ledger rows survive a restart).
    #[prost(uint64, tag = "2")]
    pub principals: u64,
    /// Paired downstream holgers with a request in the window.
    #[prost(uint64, tag = "3")]
    pub peers: u64,
    /// Anonymous clients TODAY (UTC day): each is a per-day keyed hash that dies
    /// at midnight, so there is no window for them, by design. Since this process
    /// started when it started today.
    #[prost(uint64, tag = "4")]
    pub anonymous_today: u64,
    /// The window the named counts cover, in days.
    #[prost(uint32, tag = "5")]
    pub window_days: u32,
}
/// **One box.** Every field is evidence this holger holds, never a guess: a box it
/// has no channel to read stays `unknown`, which is a different fact from `silent`.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct TopologyBox {
    /// A short name: the pairing name (`front`, `main`, `twin`), a twin's principal,
    /// a downstream's pairing name, or this box's own pairing name.
    #[prost(string, tag = "1")]
    pub name: ::prost::alloc::string::String,
    /// `front` | `primary` | `twin` | `downstream` | `upstream` (lane A13: a
    /// registry this box proxies, or a holger it mirrors).
    #[prost(string, tag = "2")]
    pub role: ::prost::alloc::string::String,
    /// Where the evidence says it is (`host` or `host:port`); empty when unknown.
    #[prost(string, tag = "3")]
    pub address: ::prost::alloc::string::String,
    /// `up` (it answered, or reported, within the bound) · `behind` (a twin or a
    /// downstream that reports and does not catch up) · `silent` (expected, and not
    /// heard within the bound, or never — and a box HELD for its recharge, which
    /// serves nothing) · `unknown` (nothing here can ask it).
    #[prost(string, tag = "4")]
    pub state: ::prost::alloc::string::String,
    /// One sentence for a human: how holger knows, and since when.
    #[prost(string, tag = "5")]
    pub why: ::prost::alloc::string::String,
    /// True for the box that answered this call.
    #[prost(bool, tag = "6")]
    pub this_box: bool,
    /// Wall clock of the newest evidence (Unix ms); 0 = none.
    #[prost(int64, tag = "7")]
    pub last_seen_unix_ms: i64,
    /// `server_unix_ms - last_seen_unix_ms` at answer time; 0 when never seen.
    #[prost(uint64, tag = "8")]
    pub seen_ago_ms: u64,
    /// The box's data volume, as measured (this box: statvfs of its data root; a
    /// twin: its own, carried on its report). False = not measured, and then the
    /// two numbers are 0 and must not be read.
    #[prost(bool, tag = "9")]
    pub disk_measured: bool,
    #[prost(uint64, tag = "10")]
    pub disk_total_bytes: u64,
    #[prost(uint64, tag = "11")]
    pub disk_used_bytes: u64,
    /// Where the evidence came from: `self`, `pairing`, `report` (a twin's
    /// TwinReport, or on a twin its own follow of the primary), `downstream`.
    #[prost(string, repeated, tag = "12")]
    pub sources: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// The WireGuard overlay address (wg0) and the utility address, from the pairing
    /// feed; empty when not fed.
    #[prost(string, tag = "13")]
    pub overlay_address: ::prost::alloc::string::String,
    #[prost(string, tag = "14")]
    pub utility_address: ::prost::alloc::string::String,
    /// **The state in a few words, holger's**: `answering`, `following`, `behind 120  entries`, `silent for 4 min`, `never heard`, `not asked`, `held for its  recharge from twin`, `fenced`. Coarse on purpose (whole minutes once past
    /// one), so the answer only changes when the state does.
    #[prost(string, tag = "15")]
    pub headline: ::prost::alloc::string::String,
    /// A twin or a downstream: the twin's own word (TwinRow.state: ok · behind ·
    /// stalled · silent, M2's `twin_state`) and its lag in log entries (M2's
    /// `lag_entries`); empty / 0 for any other box.
    #[prost(string, tag = "16")]
    pub twin_state: ::prost::alloc::string::String,
    #[prost(uint64, tag = "17")]
    pub lag_entries: u64,
    /// True when the box is HELD: a main awaiting its recharge from its twin (M3's
    /// boot hold), or a fenced primary. Drawn dark, with the word `held`.
    #[prost(bool, tag = "18")]
    pub held: bool,
    /// When this box's mutual-TLS credential to its peer expires (Unix s; the
    /// twin's `twin` credential on a twin); 0 = none held or not readable here.
    #[prost(int64, tag = "19")]
    pub cert_not_after_unix: i64,
    /// When the pairing itself expires (the estate's key, lane E2); 0 = not known.
    ///
    /// **Packages fetched** (lane A13): a downstream — artifacts delivered to it,
    #[prost(int64, tag = "20")]
    pub pairing_not_after_unix: i64,
    /// ever (durable) and today; an upstream — artifacts this box took from it
    /// since this boot (`fetched_today` unused). 0 for any other box.
    #[prost(uint64, tag = "21")]
    pub fetched_total: u64,
    #[prost(uint64, tag = "22")]
    pub fetched_today: u64,
    /// An upstream only: `proxy` (a repository another one names in
    /// `ron_upstreams`: crates.io, PyPI, npm, a remote harbour) or `mirror` (a
    /// `mirror.ron_sources` entry: another holger). Empty for any other box.
    #[prost(string, tag = "23")]
    pub upstream_kind: ::prost::alloc::string::String,
    /// An upstream only: the local repositories it feeds.
    #[prost(string, repeated, tag = "24")]
    pub feeds: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
    /// A downstream only: how it reaches this holger, `front` (the front's public
    /// door) or `wireguard` (the front's downstream interface; lane HOL-WGDS).
    #[prost(string, tag = "25")]
    pub via: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct TopologyLink {
    /// Box names, as in TopologyBox.name.
    #[prost(string, tag = "1")]
    pub from: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub to: ::prost::alloc::string::String,
    /// `serves` (front → primary) · `follows` (primary → twin) · `pulls` (primary →
    /// downstream) · `feeds` (upstream → this box, lane A13).
    #[prost(string, tag = "3")]
    pub kind: ::prost::alloc::string::String,
    /// The state of the box the link leads into (TopologyBox.state).
    #[prost(string, tag = "4")]
    pub state: ::prost::alloc::string::String,
}
/// One piece of a streamed bundle. `first_import` is read from every chunk: any
/// chunk that sets it establishes an absent anti-rollback floor with this bundle.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ImportBundleChunk {
    #[prost(bytes = "vec", tag = "1")]
    pub data: ::prost::alloc::vec::Vec<u8>,
    #[prost(bool, tag = "2")]
    pub first_import: bool,
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ImportIntelBundleReply {
    /// `new` or `idempotent-reimport`.
    #[prost(string, tag = "1")]
    pub outcome: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub bundle_id: ::prost::alloc::string::String,
    #[prost(uint64, tag = "3")]
    pub sequence: u64,
    /// YYYY-MM-DD of the advisory snapshot.
    #[prost(string, tag = "4")]
    pub snapshot_at: ::prost::alloc::string::String,
    #[prost(uint64, tag = "5")]
    pub advisories: u64,
    #[prost(string, tag = "6")]
    pub message: ::prost::alloc::string::String,
}
/// One artifact a bundle import landed.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ImportedArtifactRow {
    #[prost(string, tag = "1")]
    pub artifact: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub sha256: ::prost::alloc::string::String,
    /// AVAILABLE.
    #[prost(string, tag = "3")]
    pub state: ::prost::alloc::string::String,
    #[prost(string, tag = "4")]
    pub repository: ::prost::alloc::string::String,
    /// `landed` or `already-available`.
    #[prost(string, tag = "5")]
    pub outcome: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ImportBundleReply {
    /// `new` or `idempotent-reimport`.
    #[prost(string, tag = "1")]
    pub outcome: ::prost::alloc::string::String,
    #[prost(string, tag = "2")]
    pub bundle_id: ::prost::alloc::string::String,
    #[prost(uint64, tag = "3")]
    pub sequence: u64,
    /// `airgap-export` or `update-bundle`.
    #[prost(string, tag = "4")]
    pub kind: ::prost::alloc::string::String,
    #[prost(message, repeated, tag = "5")]
    pub artifacts: ::prost::alloc::vec::Vec<ImportedArtifactRow>,
    #[prost(string, tag = "6")]
    pub message: ::prost::alloc::string::String,
}
/// gunnar's SetGrowth, the same numbers — monetize's `Growth` reads both.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum SetGrowth {
    Unspecified = 0,
    GrowthUnknown = 1,
    GrowthSealed = 2,
    GrowthOperatorOnly = 3,
    GrowthAtRestart = 4,
    GrowthAtRuntime = 5,
}
impl SetGrowth {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            Self::Unspecified => "SET_GROWTH_UNSPECIFIED",
            Self::GrowthUnknown => "GROWTH_UNKNOWN",
            Self::GrowthSealed => "GROWTH_SEALED",
            Self::GrowthOperatorOnly => "GROWTH_OPERATOR_ONLY",
            Self::GrowthAtRestart => "GROWTH_AT_RESTART",
            Self::GrowthAtRuntime => "GROWTH_AT_RUNTIME",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "SET_GROWTH_UNSPECIFIED" => Some(Self::Unspecified),
            "GROWTH_UNKNOWN" => Some(Self::GrowthUnknown),
            "GROWTH_SEALED" => Some(Self::GrowthSealed),
            "GROWTH_OPERATOR_ONLY" => Some(Self::GrowthOperatorOnly),
            "GROWTH_AT_RESTART" => Some(Self::GrowthAtRestart),
            "GROWTH_AT_RUNTIME" => Some(Self::GrowthAtRuntime),
            _ => None,
        }
    }
}
/// What AdvanceArtifact does. ADVANCE moves to the next state on the chain (or
/// to `to_state` when set, which must be the next state).
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum IntakeVerb {
    Advance = 0,
    Quarantine = 1,
    Release = 2,
    Block = 3,
}
impl IntakeVerb {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            Self::Advance => "INTAKE_VERB_ADVANCE",
            Self::Quarantine => "INTAKE_VERB_QUARANTINE",
            Self::Release => "INTAKE_VERB_RELEASE",
            Self::Block => "INTAKE_VERB_BLOCK",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "INTAKE_VERB_ADVANCE" => Some(Self::Advance),
            "INTAKE_VERB_QUARANTINE" => Some(Self::Quarantine),
            "INTAKE_VERB_RELEASE" => Some(Self::Release),
            "INTAKE_VERB_BLOCK" => Some(Self::Block),
            _ => None,
        }
    }
}
/// What a single reading is a measurement OF.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum MeterScope {
    Unspecified = 0,
    /// Measured for THIS repository alone.
    Repository = 1,
    /// Measured for the whole server. The same value comes back for every
    /// repository, and it is not divisible between them.
    Server = 2,
}
impl MeterScope {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            Self::Unspecified => "METER_SCOPE_UNSPECIFIED",
            Self::Repository => "METER_SCOPE_REPOSITORY",
            Self::Server => "METER_SCOPE_SERVER",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "METER_SCOPE_UNSPECIFIED" => Some(Self::Unspecified),
            "METER_SCOPE_REPOSITORY" => Some(Self::Repository),
            "METER_SCOPE_SERVER" => Some(Self::Server),
            _ => None,
        }
    }
}
/// Generated client implementations.
pub mod repository_service_client {
    #![allow(
        unused_variables,
        dead_code,
        missing_docs,
        clippy::wildcard_imports,
        clippy::let_unit_value,
    )]
    use tonic::codegen::*;
    use tonic::codegen::http::Uri;
    /// Repository service — query and manage artifacts
    #[derive(Debug, Clone)]
    pub struct RepositoryServiceClient<T> {
        inner: tonic::client::Grpc<T>,
    }
    impl RepositoryServiceClient<tonic::transport::Channel> {
        /// Attempt to create a new client by connecting to a given endpoint.
        pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
        where
            D: TryInto<tonic::transport::Endpoint>,
            D::Error: Into<StdError>,
        {
            let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;
            Ok(Self::new(conn))
        }
    }
    impl<T> RepositoryServiceClient<T>
    where
        T: tonic::client::GrpcService<tonic::body::Body>,
        T::Error: Into<StdError>,
        T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static,
        <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send,
    {
        pub fn new(inner: T) -> Self {
            let inner = tonic::client::Grpc::new(inner);
            Self { inner }
        }
        pub fn with_origin(inner: T, origin: Uri) -> Self {
            let inner = tonic::client::Grpc::with_origin(inner, origin);
            Self { inner }
        }
        pub fn with_interceptor<F>(
            inner: T,
            interceptor: F,
        ) -> RepositoryServiceClient<InterceptedService<T, F>>
        where
            F: tonic::service::Interceptor,
            T::ResponseBody: Default,
            T: tonic::codegen::Service<
                http::Request<tonic::body::Body>,
                Response = http::Response<
                    <T as tonic::client::GrpcService<tonic::body::Body>>::ResponseBody,
                >,
            >,
            <T as tonic::codegen::Service<
                http::Request<tonic::body::Body>,
            >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync,
        {
            RepositoryServiceClient::new(InterceptedService::new(inner, interceptor))
        }
        /// Compress requests with the given encoding.
        ///
        /// This requires the server to support it otherwise it might respond with an
        /// error.
        #[must_use]
        pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
            self.inner = self.inner.send_compressed(encoding);
            self
        }
        /// Enable decompressing responses.
        #[must_use]
        pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
            self.inner = self.inner.accept_compressed(encoding);
            self
        }
        /// Limits the maximum size of a decoded message.
        ///
        /// Default: `4MB`
        #[must_use]
        pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
            self.inner = self.inner.max_decoding_message_size(limit);
            self
        }
        /// Limits the maximum size of an encoded message.
        ///
        /// Default: `usize::MAX`
        #[must_use]
        pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
            self.inner = self.inner.max_encoding_message_size(limit);
            self
        }
        /// Fetch a single artifact by ID
        pub async fn fetch_artifact(
            &mut self,
            request: impl tonic::IntoRequest<super::FetchArtifactRequest>,
        ) -> std::result::Result<
            tonic::Response<super::FetchArtifactResponse>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.RepositoryService/FetchArtifact",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.RepositoryService", "FetchArtifact"));
            self.inner.unary(req, path, codec).await
        }
        /// List artifacts in a repository (with optional filter)
        pub async fn list_artifacts(
            &mut self,
            request: impl tonic::IntoRequest<super::ListArtifactsRequest>,
        ) -> std::result::Result<
            tonic::Response<super::ListArtifactsResponse>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.RepositoryService/ListArtifacts",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.RepositoryService", "ListArtifacts"));
            self.inner.unary(req, path, codec).await
        }
        /// Upload an artifact (write-enabled repos only)
        pub async fn put_artifact(
            &mut self,
            request: impl tonic::IntoRequest<super::PutArtifactRequest>,
        ) -> std::result::Result<
            tonic::Response<super::PutArtifactResponse>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.RepositoryService/PutArtifact",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.RepositoryService", "PutArtifact"));
            self.inner.unary(req, path, codec).await
        }
        /// Stream download for large artifacts
        pub async fn stream_artifact(
            &mut self,
            request: impl tonic::IntoRequest<super::FetchArtifactRequest>,
        ) -> std::result::Result<
            tonic::Response<tonic::codec::Streaming<super::ArtifactChunk>>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.RepositoryService/StreamArtifact",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(
                    GrpcMethod::new("holger.v1.RepositoryService", "StreamArtifact"),
                );
            self.inner.server_streaming(req, path, codec).await
        }
        /// Stream upload for large artifacts (stinky 14). The FIRST message names the
        /// repository and the artifact and may carry the first bytes; every later
        /// message carries bytes only. The server hands the pieces to the backend as
        /// they arrive, so the body is never whole in this process unless a gate must
        /// read it (the intake chain, the ingest gates) or `async_job` stages it.
        pub async fn put_artifact_stream(
            &mut self,
            request: impl tonic::IntoStreamingRequest<Message = super::PutArtifactChunk>,
        ) -> std::result::Result<
            tonic::Response<super::PutArtifactResponse>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.RepositoryService/PutArtifactStream",
            );
            let mut req = request.into_streaming_request();
            req.extensions_mut()
                .insert(
                    GrpcMethod::new("holger.v1.RepositoryService", "PutArtifactStream"),
                );
            self.inner.client_streaming(req, path, codec).await
        }
    }
}
/// Generated client implementations.
pub mod archive_service_client {
    #![allow(
        unused_variables,
        dead_code,
        missing_docs,
        clippy::wildcard_imports,
        clippy::let_unit_value,
    )]
    use tonic::codegen::*;
    use tonic::codegen::http::Uri;
    /// Archive service — znippy archive operations
    #[derive(Debug, Clone)]
    pub struct ArchiveServiceClient<T> {
        inner: tonic::client::Grpc<T>,
    }
    impl ArchiveServiceClient<tonic::transport::Channel> {
        /// Attempt to create a new client by connecting to a given endpoint.
        pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
        where
            D: TryInto<tonic::transport::Endpoint>,
            D::Error: Into<StdError>,
        {
            let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;
            Ok(Self::new(conn))
        }
    }
    impl<T> ArchiveServiceClient<T>
    where
        T: tonic::client::GrpcService<tonic::body::Body>,
        T::Error: Into<StdError>,
        T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static,
        <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send,
    {
        pub fn new(inner: T) -> Self {
            let inner = tonic::client::Grpc::new(inner);
            Self { inner }
        }
        pub fn with_origin(inner: T, origin: Uri) -> Self {
            let inner = tonic::client::Grpc::with_origin(inner, origin);
            Self { inner }
        }
        pub fn with_interceptor<F>(
            inner: T,
            interceptor: F,
        ) -> ArchiveServiceClient<InterceptedService<T, F>>
        where
            F: tonic::service::Interceptor,
            T::ResponseBody: Default,
            T: tonic::codegen::Service<
                http::Request<tonic::body::Body>,
                Response = http::Response<
                    <T as tonic::client::GrpcService<tonic::body::Body>>::ResponseBody,
                >,
            >,
            <T as tonic::codegen::Service<
                http::Request<tonic::body::Body>,
            >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync,
        {
            ArchiveServiceClient::new(InterceptedService::new(inner, interceptor))
        }
        /// Compress requests with the given encoding.
        ///
        /// This requires the server to support it otherwise it might respond with an
        /// error.
        #[must_use]
        pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
            self.inner = self.inner.send_compressed(encoding);
            self
        }
        /// Enable decompressing responses.
        #[must_use]
        pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
            self.inner = self.inner.accept_compressed(encoding);
            self
        }
        /// Limits the maximum size of a decoded message.
        ///
        /// Default: `4MB`
        #[must_use]
        pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
            self.inner = self.inner.max_decoding_message_size(limit);
            self
        }
        /// Limits the maximum size of an encoded message.
        ///
        /// Default: `usize::MAX`
        #[must_use]
        pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
            self.inner = self.inner.max_encoding_message_size(limit);
            self
        }
        /// List files in a znippy archive backing a repository
        pub async fn list_archive_files(
            &mut self,
            request: impl tonic::IntoRequest<super::ListArchiveFilesRequest>,
        ) -> std::result::Result<
            tonic::Response<super::ListArchiveFilesResponse>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.ArchiveService/ListArchiveFiles",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.ArchiveService", "ListArchiveFiles"));
            self.inner.unary(req, path, codec).await
        }
        /// Get archive metadata (file count, total size, compression ratio)
        pub async fn archive_info(
            &mut self,
            request: impl tonic::IntoRequest<super::ArchiveInfoRequest>,
        ) -> std::result::Result<
            tonic::Response<super::ArchiveInfoResponse>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.ArchiveService/ArchiveInfo",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.ArchiveService", "ArchiveInfo"));
            self.inner.unary(req, path, codec).await
        }
    }
}
/// Generated client implementations.
pub mod admin_service_client {
    #![allow(
        unused_variables,
        dead_code,
        missing_docs,
        clippy::wildcard_imports,
        clippy::let_unit_value,
    )]
    use tonic::codegen::*;
    use tonic::codegen::http::Uri;
    /// Health / admin
    #[derive(Debug, Clone)]
    pub struct AdminServiceClient<T> {
        inner: tonic::client::Grpc<T>,
    }
    impl AdminServiceClient<tonic::transport::Channel> {
        /// Attempt to create a new client by connecting to a given endpoint.
        pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
        where
            D: TryInto<tonic::transport::Endpoint>,
            D::Error: Into<StdError>,
        {
            let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;
            Ok(Self::new(conn))
        }
    }
    impl<T> AdminServiceClient<T>
    where
        T: tonic::client::GrpcService<tonic::body::Body>,
        T::Error: Into<StdError>,
        T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static,
        <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send,
    {
        pub fn new(inner: T) -> Self {
            let inner = tonic::client::Grpc::new(inner);
            Self { inner }
        }
        pub fn with_origin(inner: T, origin: Uri) -> Self {
            let inner = tonic::client::Grpc::with_origin(inner, origin);
            Self { inner }
        }
        pub fn with_interceptor<F>(
            inner: T,
            interceptor: F,
        ) -> AdminServiceClient<InterceptedService<T, F>>
        where
            F: tonic::service::Interceptor,
            T::ResponseBody: Default,
            T: tonic::codegen::Service<
                http::Request<tonic::body::Body>,
                Response = http::Response<
                    <T as tonic::client::GrpcService<tonic::body::Body>>::ResponseBody,
                >,
            >,
            <T as tonic::codegen::Service<
                http::Request<tonic::body::Body>,
            >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync,
        {
            AdminServiceClient::new(InterceptedService::new(inner, interceptor))
        }
        /// Compress requests with the given encoding.
        ///
        /// This requires the server to support it otherwise it might respond with an
        /// error.
        #[must_use]
        pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
            self.inner = self.inner.send_compressed(encoding);
            self
        }
        /// Enable decompressing responses.
        #[must_use]
        pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
            self.inner = self.inner.accept_compressed(encoding);
            self
        }
        /// Limits the maximum size of a decoded message.
        ///
        /// Default: `4MB`
        #[must_use]
        pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
            self.inner = self.inner.max_decoding_message_size(limit);
            self
        }
        /// Limits the maximum size of an encoded message.
        ///
        /// Default: `usize::MAX`
        #[must_use]
        pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
            self.inner = self.inner.max_encoding_message_size(limit);
            self
        }
        /// Server health check
        pub async fn health(
            &mut self,
            request: impl tonic::IntoRequest<super::HealthRequest>,
        ) -> std::result::Result<tonic::Response<super::HealthResponse>, tonic::Status> {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/Health",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.AdminService", "Health"));
            self.inner.unary(req, path, codec).await
        }
        /// List configured repositories
        pub async fn list_repositories(
            &mut self,
            request: impl tonic::IntoRequest<super::ListRepositoriesRequest>,
        ) -> std::result::Result<
            tonic::Response<super::ListRepositoriesResponse>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/ListRepositories",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.AdminService", "ListRepositories"));
            self.inner.unary(req, path, codec).await
        }
        /// Report the server's operating profile — static (sealed, read-only, "rigged
        /// for silent running") vs dynamic (writable / proxy). Server-reported truth so
        /// the operator UI reflects the server, not a local toggle.
        pub async fn server_profile(
            &mut self,
            request: impl tonic::IntoRequest<super::ServerProfileRequest>,
        ) -> std::result::Result<
            tonic::Response<super::ServerProfileResponse>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/ServerProfile",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.AdminService", "ServerProfile"));
            self.inner.unary(req, path, codec).await
        }
        /// Who does the SERVER think the caller is? Resolves the presented credential
        /// (Bearer / mTLS CN) through the same validation every gated call uses and
        /// reports the resulting identity + effective GLOBAL role — introspection
        /// only, no secrets, and NOT an authorization decision: every operation is
        /// still checked by its own gate. Anonymous callers get an answer too (the
        /// default role), so a UI can explain what "not logged in" means here.
        pub async fn who_am_i(
            &mut self,
            request: impl tonic::IntoRequest<super::WhoAmIRequest>,
        ) -> std::result::Result<tonic::Response<super::WhoAmIResponse>, tonic::Status> {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/WhoAmI",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.AdminService", "WhoAmI"));
            self.inner.unary(req, path, codec).await
        }
        /// How much storage this holger has, may still write, and has already used —
        /// one statvfs(3) over its data root plus the archive bytes of every
        /// repository that OWNS storage (groups are views and are not summed). Admin
        /// read: it describes the host filesystem. A holger that was handed no data
        /// root refuses by name; it never answers a capacity of zero for a failure.
        pub async fn capacity(
            &mut self,
            request: impl tonic::IntoRequest<super::CapacityRequest>,
        ) -> std::result::Result<tonic::Response<super::CapacityReply>, tonic::Status> {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/Capacity",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.AdminService", "Capacity"));
            self.inner.unary(req, path, codec).await
        }
        /// ★★ ELECT THIS BOX A TWIN — the bootstrap door, and the ONLY way a role is
        /// conferred over the wire.
        ///
        /// Owner rulings 2026-09-21: "the weakest machine must become the twin.
        /// PERIOD" and "IT must not CHANGE role later ! so its a bootstrap thing from
        /// xtask". So: both machines install from ONE identical medium with NO role
        /// parameter, the control plane MEASURES them (Capacity here, plus the host
        /// facts it reads itself), and it tells the weaker one what it is. Exactly
        /// once: a box that already holds a role record refuses by name
        /// (holger-twin-4), and a box that is not FRESH refuses by name
        /// (holger-twin-5) because electing a serving box would put its history
        /// behind a follower's refusals.
        ///
        /// ADMIN-gated like every other mutation here. The election is RECORDED and
        /// APPLIED LIVE (stinky 14 §P3): every door refuses writes by name from the
        /// reply on, and the follow starts. What waits for the next start is the
        /// loopback bind of the public doors — a process does not rebind a door
        /// underneath its clients.
        pub async fn become_twin(
            &mut self,
            request: impl tonic::IntoRequest<super::BecomeTwinRequest>,
        ) -> std::result::Result<
            tonic::Response<super::BecomeTwinReply>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/BecomeTwin",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.AdminService", "BecomeTwin"));
            self.inner.unary(req, path, codec).await
        }
        /// ★ THE TWIN OVER MUTUAL TLS — the front certifies, the primary's OWN
        /// issuer signs, the twin pins it (nordisk-twin; gunnar's model). In order:
        /// BecomeTwin on the twin; TwinCsr on the twin (the key is born there and
        /// never crosses); IssueTwinCertificate on the primary; InstallTwinCertificate
        /// on the twin. The same three with purpose "recharge" certify a fresh main to
        /// read its twin's door (then Recharge on the main). ADMIN-gated; the three
        /// pairing steps are asked of a twin too (they change no artifact).
        pub async fn twin_csr(
            &mut self,
            request: impl tonic::IntoRequest<super::TwinCsrRequest>,
        ) -> std::result::Result<tonic::Response<super::TwinCsrReply>, tonic::Status> {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/TwinCsr",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.AdminService", "TwinCsr"));
            self.inner.unary(req, path, codec).await
        }
        /// Refused by name unless this box serves a replication door (holger-twin-7)
        /// and the principal is one it certifies (holger-twin-8): `holger-twin` from a
        /// primary only, `holger-recharge` from any box with a door.
        pub async fn issue_twin_certificate(
            &mut self,
            request: impl tonic::IntoRequest<super::IssueTwinCertificateRequest>,
        ) -> std::result::Result<
            tonic::Response<super::IssueTwinCertificateReply>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/IssueTwinCertificate",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(
                    GrpcMethod::new("holger.v1.AdminService", "IssueTwinCertificate"),
                );
            self.inner.unary(req, path, codec).await
        }
        /// Refused by name: another key (holger-twin-9), a CA that did not sign it
        /// (holger-twin-10), a CA other than the pinned one (holger-twin-11). A
        /// renewal under the SAME CA is taken.
        pub async fn install_twin_certificate(
            &mut self,
            request: impl tonic::IntoRequest<super::InstallTwinCertificateRequest>,
        ) -> std::result::Result<
            tonic::Response<super::InstallTwinCertificateReply>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/InstallTwinCertificate",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(
                    GrpcMethod::new("holger.v1.AdminService", "InstallTwinCertificate"),
                );
            self.inner.unary(req, path, codec).await
        }
        /// A fresh main pulls the estate and every repository from the box its
        /// "recharge" credential names, over that door, now. Admin; refused on a twin.
        pub async fn recharge(
            &mut self,
            request: impl tonic::IntoRequest<super::RechargeRequest>,
        ) -> std::result::Result<tonic::Response<super::RechargeReply>, tonic::Status> {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/Recharge",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.AdminService", "Recharge"));
            self.inner.unary(req, path, codec).await
        }
        /// ★ THE RECHARGE LANE'S TWO QUESTIONS (gunnar's Bootstrap.Status and the
        /// twin's log head, in holger's words). Asked BEFORE a byte moves, admin-read
        /// gated, answered by a box that serves nothing yet too.
        /// On the MAIN: fresh / restoring / recharged, and what makes it not fresh.
        pub async fn recharge_status(
            &mut self,
            request: impl tonic::IntoRequest<super::RechargeStatusRequest>,
        ) -> std::result::Result<
            tonic::Response<super::RechargeStatusReply>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/RechargeStatus",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.AdminService", "RechargeStatus"));
            self.inner.unary(req, path, codec).await
        }
        /// On the TWIN: what it holds and whether it can give everything back.
        pub async fn twin_status(
            &mut self,
            request: impl tonic::IntoRequest<super::TwinStatusRequest>,
        ) -> std::result::Result<
            tonic::Response<super::TwinStatusReply>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/TwinStatus",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.AdminService", "TwinStatus"));
            self.inner.unary(req, path, codec).await
        }
        /// ★ FENCE THIS PRIMARY (Gunnar's `fence_primary` pattern): the box that runs a
        /// pulled `fence_primary` (or a recharge's fence-first) asks the OLD primary to
        /// refuse every write from now on, and reads the fence back from the reply.
        /// ADMIN-gated by identity (not by the write gates: a fenced box answers a second
        /// fence the same). Refused on a twin, which takes no writes.
        pub async fn fence_primary(
            &mut self,
            request: impl tonic::IntoRequest<super::FencePrimaryRequest>,
        ) -> std::result::Result<
            tonic::Response<super::FencePrimaryReply>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/FencePrimary",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.AdminService", "FencePrimary"));
            self.inner.unary(req, path, codec).await
        }
        /// ★ THE ADMIN VIEW (2026-09-28; gunnar's admin mode, holger's own code): the
        /// operational snapshot an ADMINISTRATOR's console panes read — every disk and
        /// volume, the twin, the growth, the clock, plugins and monetize, the audit
        /// log, the installer's log door. ADMIN-READ (the Admin role under RBAC;
        /// refused by name to every other role and to a caller with no valid
        /// credential; open only on a server with no auth at all, like every admin
        /// read). Measured on every call, never cached. See AdminSnapshotReply.
        pub async fn admin_snapshot(
            &mut self,
            request: impl tonic::IntoRequest<super::AdminSnapshotRequest>,
        ) -> std::result::Result<
            tonic::Response<super::AdminSnapshotReply>,
            tonic::Status,
        > {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(
                        format!("Service was not ready: {}", e.into()),
                    )
                })?;
            let codec = tonic_prost::ProstCodec::default();
            let path = http::uri::PathAndQuery::from_static(
                "/holger.v1.AdminService/AdminSnapshot",
            );
            let mut req = request.into_request();
            req.extensions_mut()
                .insert(GrpcMethod::new("holger.v1.AdminService", "AdminSnapshot"));
            self.inner.unary(req, path, codec).await
        }
        /// ★ THE ESTATE BOARD (lane E3, 2026-10-19; Gunnar's `Admin.Topology` pattern,
        /// Holger's own code): "which boxes is this estate, as THIS holger knows them?"
        /// One row per box — this box first, then every box it holds EVIDENCE of: the
        /// pairing feed's front, main and twin, the twins whose reports it keeps, the
        /// primary a twin follows, and the downstream holgers that pull from it. Each row
        /// carries its own live state, the sentence that says how holger knows, the
        /// WireGuard overlay address, and the twin's lag. The board is DATA (Holger v2.0
        /// H2): the server decides every word and draws nothing; holger-ui draws the rows
        /// as they came and decides nothing. ADMIN-READ, like TwinStatus: the rows name
        /// addresses, never a secret. Also served as JSON, `GET /-/estate.json`, on the
        /// HTTP door.
        pub async fn topology(
            &mut self,
            request: impl tonic::IntoRequest<super::TopologyRequest>,
        ) -> std::result::Result<tonic::Response<super::TopologyReply>, tonic::Status> {
            self.inner
                .ready()
                .await
                .map_err(|e| {
                    tonic::Status::unknown(

The file goes on; the console shows all of it.