[bldr]docs
gRPC APIDaemon

Other data types

Messages and enums that more than one Daemon service uses.

Messages and enums used by more than one service in builder, kept here rather than repeated on each service's page.

PortForward

A host→pod port forward (host_port on the node → pod_port inside the pod).

message PortForward {
  optional uint32 host_port = 1;
  optional uint32 pod_port = 2;
  optional bool udp = 3;
}
Field
host_port 
pod_port 
udpUDP instead of TCP

TestCaseView

message TestCaseView {
  optional string name = 1;
  optional TestCaseStatus status = 2;
  optional string message = 3;
  optional uint64 duration_ms = 4;
  optional map<string, string> labels = 5;
  repeated TestAttachment attachments = 6;
}
Field
name 
status 
messagefailure detail; empty unless failed
duration_ms 
labelsWhat kind of case this is. bldr.test-type=visual-snapshot marks one whose real output is the images in attachments.
attachmentsFiles the case produced (screenshots, logs). Empty for almost every case.

TestAttachment

A file a test produced, kept by CID. What it is lives in the labels rather than in the type, so the schema stays still as the kinds of attachment grow: bldr.content-type = an IANA media type, e.g. image/png bldr.snapshot = before | after | diff

message TestAttachment {
  optional string cid = 1;
  optional map<string, string> labels = 2;
}

TaskEvent

A snapshot of one node in the invocation progress tree. Consumers key by id, link children via parent, and render state. A node moves through CACHE_LOOKUP → {CACHE_HIT | RUNNING} → {COMPLETED | FAILED}.

message TaskEvent {
  optional uint64 id = 1;
  optional string label = 3;
  optional TaskState state = 4;
  optional google.protobuf.Timestamp emitted_at = 6;
  optional map<string, string> labels = 12;
  repeated uint64 waiting_for = 13;
  oneof _parent {
    uint64 parent = 2;
  }
  oneof _output {
    string output = 5;
  }
  oneof _running_ms {
    uint64 running_ms = 7;
  }
  oneof _waiting_ms {
    uint64 waiting_ms = 8;
  }
  oneof _log_stream_id {
    string log_stream_id = 9;
  }
  oneof _log_cid {
    string log_cid = 10;
  }
  oneof _pod_id {
    string pod_id = 11;
  }
  oneof _input {
    string input = 14;
  }
  oneof _function {
    string function = 15;
  }
  oneof _rootfs {
    string rootfs = 16;
  }
  oneof _queued_at {
    google.protobuf.Timestamp queued_at = 17;
  }
  oneof _started_at {
    google.protobuf.Timestamp started_at = 18;
  }
  oneof _ended_at {
    google.protobuf.Timestamp ended_at = 19;
  }
  oneof _peer_id {
    string peer_id = 20;
  }
  oneof _step {
    TaskStep step = 21;
  }
  oneof _deadline {
    google.protobuf.Timestamp deadline = 22;
  }
}
Field
id 
parentAbsent → a root node; otherwise the id of the parent node.
labelhuman-readable description
state 
outputThe invocation's result CID, on terminal states of an invocation node.
emitted_atWall-clock time when this event was emitted on the server.
running_msOn a terminal event: server-tracked time (ms) the node spent actively running, and (if any) blocked waiting on a resource. Absent otherwise.
waiting_ms 
log_stream_idThe log stream carrying this node's output, published as soon as output starts (before the sealed CID exists). Read via the Logs service.
log_cidThe sealed log Blob CID, attached once the node's output stream closes.
pod_idThe id of the pod this node ran, if it ran one. Lets the UI link the node to the Pods page. The pod may already be reaped by the time it's viewed.
labelsFree-form key/value metadata. language names a syntax for rendering the label (e.g. "sh"), so consumers need not pattern-match the text.
waiting_forWhen queued: the tasks this one is waiting on.
inputThe invocation's input CID, so a viewer can open what went in as readily as what came out. Always the actual input block of the invocation (e.g. a pod.dag op's spec), never a substitute — see rootfs for the tree a pod ran on.
functionThe invoked function's name (e.g. "pod.dag/v0.0.0"), on invocation nodes. label starts out as this but functions replace it with a description, so the name is carried separately where a viewer can always reach it.
rootfsThe resolved rootfs FsNode CID a pod step ran on, where applicable. Kept apart from input: the rootfs is derived context, not the block the step consumed.
queued_atThe node's own span, stamped from the server's phase accumulator on every event rather than only on the terminal one — the replay a late subscriber receives is compacted to the latest event per node, so a span assembled from the event sequence would be lost the moment a node moved on.
started_at 
ended_at 
peer_idThe peer that executed this invocation, base58, when it did not run here.
stepHow this node fits a deployment's plan — the block it is, or the action it runs — when it is a step of one. Absent on every other node: a build's sync tree, a function's own subtasks (a push's layers, an apply's resources) are not steps. Set once, when the plan is published, and kept through the node's later events by the server's replay.
deadlineWhen this node must have finished, when it runs against a timeout (a composite block's timeoutSecs, k8s.job.wait's). A viewer draws the node's progress against it.

TaskStep

A deployment step's place in its plan. A deployment is a step function: before anything runs, the composite publishes every block and action it will run, each as a queued node carrying one of these, and the nodes then move through running → completed | failed | skipped.

message TaskStep {
  optional TaskStepKind kind = 1;
  optional string form = 2;
  optional string phase = 3;
  optional string name = 4;
  repeated string needs = 5;
  optional uint32 index = 6;
  optional uint32 count = 7;
}
Field
kind 
formA block's form: "sequence" | "parallel" | "try" | "dag". Empty on an action.
phaseThe phase of a try block this step is: "try" | "catch" | "finally". Empty for a step that is not directly under a try block.
nameA DAG node's name, and the names of the nodes it needs. Empty otherwise.
needs 
indexThe step's 1-based position among its siblings, and how many there are.
count 

TaskState

message TaskState {
  oneof kind {
    Unit cache_lookup = 1;
    Unit cache_hit = 2;
    TaskRunning running = 3;
    Unit completed = 4;
    TaskFailed failed = 5;
    TaskWaiting waiting = 6;
    Unit queued = 7;
    Unit cancelled = 8;
    TaskWaitingForResources waiting_for_resources = 9;
    TaskRetrying retrying = 10;
    TaskSkipped skipped = 11;
  }
}
Field
cache_lookupconsulting the cache
cache_hitresolved from cache (terminal)
runningexecuting
completedfinished ok (terminal)
failedfailed (terminal)
waitingblocked on a resource (download slot, rate limit)
queueddeclared, not started — the build knows it is coming
cancelledabandoned because something else failed (terminal)
waiting_for_resourcesheld at the admission gate
retryingan attempt failed and another will follow (NOT terminal)
skippedPlanned, and deliberately not run (terminal): a sequence step after a failure, a catch whose try succeeded. Distinct from cancelled (abandoned because something broke) and from failed (it never ran).

TaskSkipped

A planned step that did not run, and why — "step 2 failed", "try succeeded".

message TaskSkipped {
  optional string reason = 1;
}

TaskRetrying

An attempt failed and the task will be tried again — deliberately NOT a failed state: a red node reads as "this build is broken", and a retryable attempt does not mean that. Non-terminal; followed by another attempt (and eventually by completed or a failed carrying the final attempt counts).

message TaskRetrying {
  optional string error = 1;
  optional uint32 attempt = 2;
  optional uint32 limit = 3;
  oneof _retry_in_ms {
    uint64 retry_in_ms = 4;
  }
}
Field
errorThe failing attempt's error, kept so the attempt stays diagnosable.
attemptWhich attempt just failed (1-based) and how many will be made at most.
limit 
retry_in_msBackoff remaining before the next attempt starts, when the retrier knows it — so the tree reads "retrying in 2.0s" instead of looking stalled.

TaskWaiting

message TaskWaiting {
  optional string reason = 1;
  optional TaskProgress progress = 2;
}
Field
reasonWhat the node is blocked on, e.g. "download slot" or "rate limit — retry in 5s".
progressOptional countdown / progress while blocked.

TaskWaitingForResources

Held at the node's admission gate before execution starts: the host lacks the resources to start another function execution right now. Distinct from waiting, which a running function reports about its own external waits — here the function body has not begun. Non-terminal; followed by running once admitted.

message TaskWaitingForResources {
  optional string reason = 1;
  optional string resource = 2;
  optional uint64 needed = 3;
  optional uint64 available = 4;
}
Field
reasonHuman-readable, e.g. "waiting for memory (need 2.0GiB, free 0.4GiB)".
resourceWhich resource admission is short of: "cpu" | "memory" | "slots", or "queue" when this execution is short of nothing itself and is waiting behind earlier executions (only the head of the queue is admitted; reason says what the head is held on).
neededWhat admission needs: millicores (cpu), bytes of headroom (memory), the concurrency cap that is fully in use (slots), or the number of executions ahead of this one (queue).
availableWhat is free right now: millicores (cpu), bytes of headroom (memory), or free slots (0). Always 0 for queue.

Unit

message Unit {
  // no fields
}

TaskRunning

message TaskRunning {
  optional string source = 1;
  optional TaskProgress progress = 2;
}
Field
source"local", or a base58 PeerId for a remote execution.
progressoptional quantitative progress

TaskProgress

message TaskProgress {
  optional uint64 current = 1;
  optional string unit = 3;
  oneof _total {
    uint64 total = 2;
  }
  oneof _detail {
    string detail = 4;
  }
}
Field
current 
total 
unit"bytes" | "items" | "seconds"
detailThe progress in the reporter's own words, when the fraction alone does not say enough: "3 of 5 layers, 41.2 of 68.3 MiB", "142 s of 3600 s".

TaskFailed

message TaskFailed {
  optional string error = 1;
  oneof _attempts_made {
    uint32 attempts_made = 2;
  }
  oneof _attempt_limit {
    uint32 attempt_limit = 3;
  }
}
Field
error 
attempts_madeHow many attempts were made before giving up, and the limit that was hit. Present only for a task that was retried — a bare "failed" hides that the daemon tried five times, which is the first thing a reader needs to know.
attempt_limit 

CodeDiagnostic

One thing a build's tooling said about one place in the source: a type error, a lint, a deprecation.

The point of a message rather than a log line is that the location is structured. A compiler prints a path that means something inside its own pod — /src/bldr-ui/src/App.tsx — and a reader wants the file in the workspace they can open. Splitting member from path-in-member is what makes that translation the producer's job, done once where the mapping is known, instead of every consumer guessing at a prefix.

Every positional field is optional in the sense that 0 means "not reported". A tool that knows only the file must still be able to say so, and a diagnostic with no line is worth strictly more than no diagnostic.

message CodeDiagnostic {
  optional string member = 1;
  optional string path = 2;
  optional uint32 line = 3;
  optional uint32 column = 4;
  optional uint32 end_line = 5;
  optional uint32 end_column = 6;
  optional DiagnosticLevel level = 7;
  optional string title = 8;
  optional string description = 9;
  optional string snippet = 10;
  optional uint32 snippet_start_line = 11;
  optional string code = 12;
  optional string tool = 13;
  optional string target = 14;
  repeated RelatedDiagnostic related = 15;
  repeated DiagnosticFix fixes = 16;
  optional map<string, string> labels = 17;
  optional string root = 18;
  optional uint64 offset = 19;
  optional uint64 end_offset = 20;
}
Field
memberWorkspace member the file belongs to, e.g. bldr/ui. Empty when the producer could not attribute it to one — a generated file, or a path outside every member. Such a diagnostic is still shown, keyed on path.
pathPath within the member, relative and without a leading slash, e.g. src/App.tsx. When member is empty this is whatever path the tool gave, verbatim, since anything else would be an invention.
line1-based. 0 means the tool did not report a position.
column 
end_line1-based, inclusive end of the span. 0 for a point diagnostic — a consumer then highlights from (line, column) to the end of that line.
end_column 
level 
titleOne line, no trailing newline — what a list shows. e.g. Type 'true' is not assignable to type 'CargoOptions'.
descriptionThe full text, including whatever notes and hints the tool attached. Empty when it adds nothing to title; a consumer then shows title alone rather than an empty panel.
snippetSource lines around the diagnostic, verbatim and newline-separated, so a consumer can render context without fetching the file — which it may not be able to do at all, since the file lives in a member CID it would have to resolve. Empty when the producer chose not to include one.
snippet_start_line1-based line number of snippet's first line, so the excerpt can be numbered correctly. 0 when there is no snippet.
codeThe tool's own code, e.g. TS2322 or clippy::needless_borrow. Empty when the tool has no such concept. Clients group and filter on this; they must not parse it.
toolWhat produced it, e.g. tsc, clippy, rustc. Names a tool, not a version.
targetThe build target it came out of, when the producer knows — bldr/ui/check. Empty otherwise.
relatedOther places involved — a compiler's "expected because of this".
fixesFixes the tool offered.
labelsAnything tool-specific with no field here. The escape hatch that keeps this message from growing a column per tool.
rootThe tree path is relative to; empty means the member's own source. See DiagnosticSpan.root, which this mirrors for the primary location.
offset0-based byte offsets, for tools that report them instead of line/column.
end_offset 

BuildDiagnostics

Diagnostics a build produced. Emitted as they are found, so a long typecheck reports its first error immediately rather than at the end; a client appends rather than replaces.

message BuildDiagnostics {
  optional uint64 generation = 1;
  repeated CodeDiagnostic diagnostics = 2;
}

DiagnosticSpan

A place a diagnostic points at.

Split out of CodeDiagnostic so that a related place — a compiler's "expected because of this" — is described exactly the same way as the primary one. Two shapes for one idea is two shapes to keep in step.

message DiagnosticSpan {
  optional string member = 1;
  optional string path = 2;
  optional uint32 line = 3;
  optional uint32 column = 4;
  optional uint32 end_line = 5;
  optional uint32 end_column = 6;
  optional uint64 offset = 7;
  optional uint64 end_offset = 8;
  optional string root = 9;
}
Field
memberWorkspace member the file belongs to, e.g. bldr/ui. Empty when the producer could not attribute it to one.
pathPath within the member, relative and without a leading slash. When member is empty this is whatever path the tool gave, verbatim.
line1-based; 0 means the tool did not report a position.
column 
end_line1-based, inclusive end of the span. 0 for a point diagnostic.
end_column 
offset0-based byte offsets, for the tools that work in them rather than in line/column. Both 0 when not reported — a byte 0 span is not a thing any tool reports about code.
end_offset 
rootThe tree path is relative to, as a CID. Empty means the member's own source — the file a developer can open, which is the common case.

RelatedDiagnostic

A second place involved in a diagnostic, with what it has to do with it.

Not a diagnostic of its own: no severity, no code, because it is not a separate finding. Dropping these is what makes a re-rendered compiler error so much less useful than the original.

message RelatedDiagnostic {
  optional string message = 1;
  optional DiagnosticSpan location = 2;
}

DiagnosticFix

A change the tool believes would resolve the finding.

Described, not applied: a build runs on a content-addressed copy, so a fix applied there would produce a tree nobody sees. What is worth carrying is that a fix exists and how far the tool trusts it, because that is what decides whether a human runs the tool's --write mode.

message DiagnosticFix {
  optional string message = 1;
  optional string applicability = 2;
}
Field
messageWhat the fix would do, in the tool's words.
applicabilityHow safe the tool says it is — safe, unsafe, maybe-incorrect. The tool's own vocabulary, not normalised: the words mean different things per tool and flattening them would lose the warning.

TrackingInfo

A member's effective upstream tracking. An empty kind means "no tracking" (absent, or kind: none). Otherwise kind names the content-tracking-provider/&lt;kind> function and settings carries its free-form parameters.

message TrackingInfo {
  optional string kind = 1;
  optional map<string, string> settings = 2;
}

TestCaseStatus

enum TestCaseStatus {
  TEST_CASE_STATUS_UNSPECIFIED = 0;
  TEST_CASE_STATUS_PASSED = 1;
  TEST_CASE_STATUS_FAILED = 2;
  TEST_CASE_STATUS_SKIPPED = 3;
}

TaskStepKind

enum TaskStepKind {
  TASK_STEP_KIND_UNSPECIFIED = 0;
  TASK_STEP_KIND_BLOCK = 1;
  TASK_STEP_KIND_ACTION = 2;
}
Value
TASK_STEP_KIND_UNSPECIFIED 
TASK_STEP_KIND_BLOCKGroups other steps: a sequence, a parallel, a try or a dag block.
TASK_STEP_KIND_ACTIONOne child function call.

DiagnosticLevel

enum DiagnosticLevel {
  DIAGNOSTIC_LEVEL_UNSPECIFIED = 0;
  DIAGNOSTIC_LEVEL_ERROR = 1;
  DIAGNOSTIC_LEVEL_WARNING = 2;
  DIAGNOSTIC_LEVEL_INFO = 3;
}

On this page