remote

package
v0.8.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 33 Imported by: 0

Documentation

Overview

Package remote is evolve's client for patchy's remote-evaluation service: the OIDC login flow and credential store, the HTTP/SSE client, the deterministic workspace bundler, the remote sweep orchestrator, and the bidirectional Reporter seam — EventReporter serializes run.Reporter calls onto the in-pod EVOLVE-EVENT stdout stream, ApplyEvent replays received events back onto a local Reporter, so a remote run's output is indistinguishable from a local one.

The wire types in wire.go are local copies of patchy's pkg/evaluation contract; the import swaps to the published package once patchy releases it (they must stay field-for-field identical until then).

Index

Constants

View Source
const (
	EnvUnitFile  = "EVOLVE_UNIT_FILE"
	EnvBundleDir = "EVOLVE_BUNDLE_DIR"
)

Pod input environment: where the prepare container staged the unit spec (a UnitSpec JSON document) and the extracted workspace bundle.

View Source
const (
	TypeUnitStarted     = "unit_started"
	TypeUnitSkipped     = "unit_skipped"
	TypeItemStarted     = "item_started"
	TypeItemDone        = "item_done"
	TypeBaselineStarted = "baseline_started"
	TypeBaselineDone    = "baseline_done"
	TypeUnitFinished    = "unit_finished"
	TypeWarn            = "warn"
	TypeResult          = "result"
	TypeFatal           = "fatal"
)

Event types. Patchy interprets only TypeResult and TypeFatal; every other type is progress, relayed verbatim to the monitoring client, which replays it onto its local reporter.

View Source
const (
	SSEEventUnit  = "unit"
	SSEEventEvent = "event"
	SSEEventEnd   = "end"
)

SSE event names on GET /api/v1/evaluations/{name}/events.

The stream is content-bearing with an explicit end event:

  • On connect the server replays one "unit" event per child, so a reconnecting client rebuilds its view without Last-Event-ID; updates re-emit "unit" and the client applies them idempotently by name.
  • "event" events relay raw in-pod progress lines tagged with the unit name. They are best-effort and degradable: a client must render correctly from "unit" events alone.
  • "end" carries the final snapshot; the server closes after sending it.
View Source
const EventPrefix = "EVOLVE-EVENT: "

EventPrefix marks an event line on the runner's stdout; everything else the pod prints goes to stderr.

View Source
const EventVersion = 1

EventVersion is the current event schema version.

View Source
const MaxDetailLen = 4096

MaxDetailLen bounds human-facing detail strings on the wire (mirrors the CR status bound).

View Source
const MaxEntryBytes = 900 << 10

MaxEntryBytes bounds UnitResult.Entry. The pod truncates evidence fields until the marshalled entry fits — the entry is stored in a ConfigMap under Kubernetes' ~1MiB object cap, and this bound leaves headroom for the object's own metadata after gzip.

View Source
const MaxOutputLen = 16 << 10

MaxOutputLen bounds relayed item output snippets, so one chatty case cannot bloat the progress stream.

View Source
const SubmissionVersion = "v1"

SubmissionVersion is the accepted Submission.Version value.

Variables

View Source
var ErrLoginExpired = errors.New("not logged in (or the session expired): run `evolve login`")

ErrLoginExpired means no usable credential exists for the remote — never stored, or its refresh token no longer works. The fix is `evolve login`.

Functions

func ApplyEvent

func ApplyEvent(rep run.Reporter, ev Event)

ApplyEvent replays one wire event onto a local run.Reporter: the monitor half of the seam. result and fatal events are not progress and are ignored here — the sweep handles them itself.

func Bearer

func Bearer(ctx context.Context, store *Store, remoteURL string, info *AuthInfo) (string, error)

Bearer returns a live bearer token for the remote, refreshing (and save-through persisting — dex rotates refresh tokens) when the stored ID token is stale. A hard refresh failure is ErrLoginExpired.

func Login

func Login(ctx context.Context, store *Store, remoteURL string, noBrowser bool, out io.Writer) error

Login runs the OIDC authorization-code + PKCE flow against the remote's issuer and persists the credential in the store. The client is public (no secret); the redirect is an ephemeral localhost listener. noBrowser skips the best-effort browser open — the URL is always printed either way.

func MarshalEvalEntry

func MarshalEvalEntry(e *results.EvalEntry) (json.RawMessage, error)

MarshalEvalEntry renders an eval entry within MaxEntryBytes, shedding weight in fidelity order: snapshot result arrays first (their summaries survive), then assertion evidence, then the assertions themselves.

func MarshalTriggerEntry

func MarshalTriggerEntry(e *results.TriggerEntry) (json.RawMessage, error)

MarshalTriggerEntry renders a trigger entry within MaxEntryBytes, dropping the previous snapshot's per-query results first — the summary survives, and the wire's fidelity floor is the fresh results.

func NormalizeRemote

func NormalizeRemote(u string) string

NormalizeRemote canonicalizes a remote URL as the credential key: lowercase, no trailing slash.

func ReadBundle

func ReadBundle(b *Bundle) (map[string]string, error)

ReadBundle is a test helper: it lists a bundle's entries.

func Sweep

func Sweep(ctx context.Context, opts SweepOptions) (failed bool, err error)

Sweep plans, submits, and monitors a remote run: enumerate units exactly as run.Sweep would, compute the case selection locally, bundle and dedupe workspaces, submit, then stream — progress events replay onto the Reporter, and every settled unit's entry merges into the local results file, saved with the same rotation a local run performs. failed reports graded failures (the --strict signal).

func Truncate

func Truncate(s string, max int) string

Truncate clips s to at most max bytes on a rune boundary, appending an ellipsis when it clipped. Used by the pod to bound detail/output strings and evidence fields until an entry fits MaxEntryBytes.

Types

type AuthInfo

type AuthInfo struct {
	// Issuer is the OIDC issuer URL (discovery is derived from it).
	Issuer string `json:"issuer"`
	// ClientID of the public (PKCE, secret-less) client the login uses.
	ClientID string `json:"clientID"`
	// Scopes to request; the client unions in openid and offline_access.
	Scopes []string `json:"scopes,omitempty"`
	// Mode is the server's auth mode ("oidc" or "none"). Mode none needs no
	// login at all.
	Mode string `json:"mode"`
}

AuthInfo is GET /api/v1/auth/info: everything the client's login flow needs to run OIDC discovery and the PKCE authorization-code exchange, so a user configures nothing but the service URL.

func FetchAuthInfo

func FetchAuthInfo(ctx context.Context, remoteURL string) (*AuthInfo, error)

FetchAuthInfo reads the remote's GET /api/v1/auth/info — everything the login flow needs, so the user configures nothing but the URL.

type Bundle

type Bundle struct {
	// Digest is the hex sha256 of Data.
	Digest string
	// Data is the gzip tarball.
	Data []byte
}

Bundle is one deterministic workspace tarball: identical inputs always produce identical bytes, so the sha256 digest doubles as the dedupe key.

func EvalsBundle

func EvalsBundle(set layout.EvalSet) (*Bundle, error)

EvalsBundle stages one skill's evals workspace: the skill directory plus its evals/<skill>/ tree (specs and fixtures; results files excluded).

func TriggersBundle

func TriggersBundle(p layout.Plugin) (*Bundle, error)

TriggersBundle stages a plugin's triggers workspace: every sibling skill (the trigger surface is the whole skill roster) plus each skill's triggers spec — results files excluded. One bundle serves every trigger unit of the plugin.

type CaseStatus

type CaseStatus struct {
	// ID is the trigger query or eval id.
	ID string `json:"id"`
	// Passed reports the graded outcome.
	Passed bool `json:"passed"`
}

CaseStatus is one case's graded outcome, compact enough for CR status.

type Client

type Client struct {
	// BaseURL of the service.
	BaseURL string
	// Store holds the login credential; Info the service's auth discovery.
	Store *Store
	Info  *AuthInfo
	// HTTPClient defaults to http.DefaultClient.
	HTTPClient *http.Client
}

Client talks to a patchy remote-evaluation service, attaching the stored bearer credential (refreshed as needed) to every request.

func NewClient

func NewClient(ctx context.Context, store *Store, baseURL string) (*Client, error)

NewClient discovers the remote's auth mode and binds the credential store.

func (*Client) Cancel

func (c *Client) Cancel(ctx context.Context, name string) error

Cancel deletes the evaluation server-side.

func (*Client) Events

func (c *Client) Events(ctx context.Context, name string,
	onUnit func(UnitStatusWire), onEvent func(EventWire)) (*EvaluationStatusWire, error)

Events follows the evaluation's SSE monitor until the end event: onUnit for every unit state, onEvent for relayed in-pod progress (best-effort — the server may not send any). A dropped stream reconnects with backoff, re-fetching the snapshot to reconcile; the final snapshot is returned.

func (*Client) HasWorkspace

func (c *Client) HasWorkspace(ctx context.Context, digest string) (bool, error)

HasWorkspace reports whether the digest is already cached server-side.

func (*Client) Status

func (c *Client) Status(ctx context.Context, name string) (*EvaluationStatusWire, error)

Status fetches the evaluation's snapshot.

func (*Client) Submit

func (c *Client) Submit(ctx context.Context, sub *Submission) (*SubmissionResponse, error)

Submit posts the submission and returns the evaluation to monitor.

func (*Client) UploadWorkspace

func (c *Client) UploadWorkspace(ctx context.Context, digest string, bundle []byte) error

UploadWorkspace uploads a bundle under its digest.

type Credential

type Credential struct {
	// IDToken is the raw ID token (the bearer the API verifies).
	IDToken string `json:"idToken"`
	// IDTokenExpiry is the verified token's expiry.
	IDTokenExpiry time.Time `json:"idTokenExpiry"`
	// Token is the OAuth2 access/refresh token pair.
	Token *oauth2.Token `json:"token"`
}

Credential is one remote's stored login: the verified ID token presented as the bearer, and the OAuth2 token carrying the refresh token that renews it.

type EvaluationStatusWire

type EvaluationStatusWire struct {
	Name string `json:"name"`
	// Phase is Pending|Running|Complete|Failed.
	Phase     string `json:"phase,omitempty"`
	Submitter string `json:"submitter,omitempty"`
	// Unit counters.
	UnitsTotal    int `json:"unitsTotal"`
	UnitsComplete int `json:"unitsComplete"`
	UnitsFailed   int `json:"unitsFailed"`
	// Units are the per-child states, index-ordered.
	Units []UnitStatusWire `json:"units,omitempty"`
}

EvaluationStatusWire is the GET snapshot and the SSE "end" payload.

type Event

type Event struct {
	V    int      `json:"v"`
	Type string   `json:"type"`
	Unit *UnitRef `json:"unit,omitempty"`
	// Item carries the per-item payloads (see ItemEvent).
	Item *ItemEvent `json:"item,omitempty"`
	// Sum rides on unit_finished.
	Sum *UnitSummary `json:"sum,omitempty"`
	// Msg is the unit_skipped reason or the warn text.
	Msg string `json:"msg,omitempty"`
	// Result rides on type=result: the unit's outcome, exactly once per
	// successful pod, as the last event before exit.
	Result *UnitResult `json:"result,omitempty"`
	// Error rides on type=fatal: the pod could not produce a result.
	Error string `json:"error,omitempty"`
}

Event is one EVOLVE-EVENT line: the pod's progress and result stream.

func Decode

func Decode(line []byte) (Event, bool)

Decode recovers an event from one log line; ok is false for any line that is not an event. The prefix is found anywhere in the line, because Kubernetes log lines may carry timestamps or wrapping.

func (Event) Encode

func (e Event) Encode() (string, error)

Encode renders the event as one stdout line (prefix included, newline excluded).

type EventReporter

type EventReporter struct {
	// contains filtered or unexported fields
}

EventReporter implements run.Reporter by emitting EVOLVE-EVENT lines: the in-pod half of the Reporter seam. Emissions are mutex-serialized — ItemDone and Warn fire from the parallel agent-run goroutines — and everything else the process prints must go to stderr, keeping stdout pure event stream.

func NewEventReporter

func NewEventReporter(w io.Writer, plugin string) *EventReporter

NewEventReporter builds an EventReporter writing to w (the pod's stdout). plugin tags every unit reference, since plan.UnitRef does not carry it.

func (*EventReporter) BaselineDone

func (r *EventReporter) BaselineDone(u plan.UnitRef, item run.ItemResult)

BaselineDone implements run.Reporter.

func (*EventReporter) BaselineStarted

func (r *EventReporter) BaselineStarted(u plan.UnitRef, item run.ItemStart)

BaselineStarted implements run.Reporter.

func (*EventReporter) Emit

func (r *EventReporter) Emit(ev Event)

Emit writes one event line directly — the result/fatal channel exec-unit uses beside the Reporter methods.

func (*EventReporter) ItemDone

func (r *EventReporter) ItemDone(u plan.UnitRef, item run.ItemResult)

ItemDone implements run.Reporter.

func (*EventReporter) ItemStarted

func (r *EventReporter) ItemStarted(u plan.UnitRef, item run.ItemStart)

ItemStarted implements run.Reporter.

func (*EventReporter) UnitFinished

func (r *EventReporter) UnitFinished(u plan.UnitRef, sum run.UnitSummary, _ string)

UnitFinished implements run.Reporter. savedRel is dropped: the pod's results path is meaningless to the monitor, which reports its own local save path when it lands the entry.

func (*EventReporter) UnitSkipped

func (r *EventReporter) UnitSkipped(u plan.UnitRef, reason string)

UnitSkipped implements run.Reporter.

func (*EventReporter) UnitStarted

func (r *EventReporter) UnitStarted(u plan.UnitRef, total, runs int, mode plan.Mode)

UnitStarted implements run.Reporter.

func (*EventReporter) Warn

func (r *EventReporter) Warn(format string, a ...any)

Warn implements run.Reporter.

type EventWire

type EventWire struct {
	// Unit is the EvaluationUnit name.
	Unit string `json:"unit"`
	// Event is the relayed in-pod event, verbatim.
	Event Event `json:"event"`
}

EventWire is an SSE "event" payload: one relayed in-pod event, tagged with the unit it came from.

type HarnessOption

type HarnessOption struct {
	// Harness id ("claude", "codex", …).
	Harness string `json:"harness"`
	// ModelID is the harness-native model id the unit's model maps to.
	ModelID string `json:"modelID,omitempty"`
}

HarnessOption is one acceptable harness for a unit, in preference order.

type ItemEvent

type ItemEvent struct {
	Index int    `json:"index,omitempty"`
	Label string `json:"label,omitempty"`
	Runs  int    `json:"runs,omitempty"`
	// Total and Mode ride on unit_started: the unit's case count and its
	// run mode ("run" or "count-only").
	Total int    `json:"total,omitempty"`
	Mode  string `json:"mode,omitempty"`
	// Status is pass|fail|skip|error (item_done only).
	Status  string       `json:"status,omitempty"`
	Detail  string       `json:"detail,omitempty"`
	Output  string       `json:"output,omitempty"`
	Metrics *ItemMetrics `json:"metrics,omitempty"`
}

ItemEvent carries the per-item payloads. unit_started uses Total/Runs/Mode; item_started uses Index/Label/Runs; item_done (and the baseline pair) uses Index/Label/Status/Detail/Output/Metrics. Local workspace and log paths never appear — they are meaningless outside the pod.

type ItemMetrics

type ItemMetrics struct {
	Hits                *int     `json:"hits,omitempty"`
	Runs                *int     `json:"runs,omitempty"`
	AvgRunSeconds       *float64 `json:"avgRunSeconds,omitempty"`
	InputTokens         *int     `json:"inputTokens,omitempty"`
	CacheReadTokens     *int     `json:"cacheReadTokens,omitempty"`
	CacheCreationTokens *int     `json:"cacheCreationTokens,omitempty"`
	OutputTokens        *int     `json:"outputTokens,omitempty"`
	CostUSD             *float64 `json:"costUSD,omitempty"`
	AssertPassed        *int     `json:"assertPassed,omitempty"`
	AssertTotal         *int     `json:"assertTotal,omitempty"`
}

ItemMetrics mirrors the client's plan.ItemMetrics: the per-item figures a live dashboard renders. All fields optional.

type JudgeSpec

type JudgeSpec struct {
	// Model is the canonical provider-qualified judge model id.
	Model string `json:"model"`
	// ModelID is its harness-native id on the unit's harness.
	ModelID string `json:"modelID,omitempty"`
}

JudgeSpec binds the in-pod LLM judge. V1 constraint: the judge model must be runnable by the unit's own harness — the client validates this before submitting.

type ResultSummary

type ResultSummary struct {
	CasesPassed  int `json:"casesPassed"`
	CasesFailed  int `json:"casesFailed"`
	CasesErrored int `json:"casesErrored"`
	// Cases lists per-case outcomes; the pod bounds the list (the CR caps
	// it at 256 entries).
	Cases []CaseStatus `json:"cases,omitempty"`
	// TokenUsage summed over the unit's agent runs.
	TokenUsage TokenUsage `json:"tokenUsage,omitempty"`
	// ElapsedMS is the unit's wall-clock duration.
	ElapsedMS int64 `json:"elapsedMS,omitempty"`
	// Outcome is "ok" for a completed unit (graded failures included) or a
	// short failure word ("error", "timeout") otherwise.
	Outcome string `json:"outcome"`
}

ResultSummary is the typed, bounded portion of a unit result — everything patchy stamps into the EvaluationUnit status.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store persists credentials per normalized remote URL in one user-level file. UserConfigDir, not UserCacheDir: these are durable secrets, not a purgeable cache — evolve's first user-level file (everything else is repo-scoped configuration).

func NewStore

func NewStore() (*Store, error)

NewStore opens the default user-level store (<UserConfigDir>/evolve/credentials.json).

func NewStoreAt

func NewStoreAt(path string) *Store

NewStoreAt opens a store at an explicit path (tests).

func (*Store) Delete

func (s *Store) Delete(remote string) error

Delete forgets the remote's credential; deleting an absent one is fine.

func (*Store) Load

func (s *Store) Load(remote string) (*Credential, error)

Load returns the remote's credential, or ErrLoginExpired when absent.

func (*Store) Save

func (s *Store) Save(remote string, cred *Credential) error

Save stores the remote's credential (save-through on refresh rotation).

type Submission

type Submission struct {
	// Version of this contract; must be SubmissionVersion.
	Version string `json:"version"`
	// Units to run.
	Units []UnitSpec `json:"units"`
	// TTLSeconds overrides the server's retention of the finished
	// evaluation (0 keeps the server default).
	TTLSeconds int64 `json:"ttlSeconds,omitempty"`
}

Submission is POST /api/v1/evaluations.

type SubmissionError

type SubmissionError struct {
	Error             string   `json:"error"`
	MissingWorkspaces []string `json:"missingWorkspaces,omitempty"`
}

SubmissionError is a non-2xx body. MissingWorkspaces (with a 412) lists digests the client must upload before resubmitting.

type SubmissionResponse

type SubmissionResponse struct {
	Name  string   `json:"name"`
	Units []string `json:"units"`
}

SubmissionResponse is the 201 body: the Evaluation name to monitor and the child unit names, index-ordered.

type SweepOptions

type SweepOptions struct {
	run.Options
	Client *Client
	Tiers  plan.Tiers
	// Runs per trigger query.
	Runs int
	// EvalFilter restricts evals to one id ("" = all).
	EvalFilter string
	// Per-tier timeouts, falling back to Options.Timeout.
	TriggerTimeout time.Duration
	EvalTimeout    time.Duration
	// Judge is the resolved judge model (zero = no judge); the pod binds it
	// on the unit's own harness.
	Judge model.Model
	// ClientVersion recorded on every unit.
	ClientVersion string
}

SweepOptions configures a remote sweep. Options carries the shared engine configuration (repo, selections, filters, per-run knobs); the sweep plans with AssumeRunnable — eligibility is the server's concern — and never executes anything locally.

type TokenUsage

type TokenUsage struct {
	InputTokens         int64   `json:"inputTokens,omitempty"`
	OutputTokens        int64   `json:"outputTokens,omitempty"`
	CacheReadTokens     int64   `json:"cacheReadTokens,omitempty"`
	CacheCreationTokens int64   `json:"cacheCreationTokens,omitempty"`
	CostUSD             float64 `json:"costUSD,omitempty"`
}

TokenUsage is a unit's token and cost accounting, summed over its agent runs. Cost stays a float on the wire; CR statuses render it as a decimal string.

type UnitRef

type UnitRef struct {
	Plugin string `json:"plugin,omitempty"`
	Skill  string `json:"skill"`
	// Key is the provider-qualified model id.
	Key string `json:"key"`
	// Kind is "triggers" or "evals".
	Kind string `json:"kind"`
}

UnitRef identifies the unit an event belongs to, mirroring the client's plan.UnitRef plus the plugin.

type UnitResult

type UnitResult struct {
	// Tier (1|2), Model, and Harness echo what actually ran, so the result
	// is self-contained.
	Tier    int    `json:"tier"`
	Model   string `json:"model"`
	Harness string `json:"harness"`
	// Failed reports whether any executed case failed — the client's
	// --strict signal, not a scheduling failure.
	Failed bool `json:"failed"`
	// Summary is the bounded, typed digest patchy stores in CR status.
	Summary ResultSummary `json:"summary"`
	// Entry is the finished results entry (the client's TriggerEntry or
	// EvalEntry, schema 5), OPAQUE to patchy: stored whole in the results
	// ConfigMap and handed back to the client, which merges it into its
	// local results file. At most MaxEntryBytes.
	Entry json.RawMessage `json:"entry,omitempty"`
}

UnitResult is the type=result payload: the unit's outcome plus the finished results entry.

type UnitSpec

type UnitSpec struct {
	// Skill under evaluation and the plugin it belongs to.
	Skill  string `json:"skill"`
	Plugin string `json:"plugin,omitempty"`
	// Tier of the run: 1 = triggers, 2 = evals.
	Tier int `json:"tier"`
	// Model is the canonical provider-qualified model id.
	Model string `json:"model"`
	// Harnesses that can run the model, in preference order; the scheduler
	// launches the first one enabled in the runner fleet.
	Harnesses []HarnessOption `json:"harnesses"`
	// Workspace bundle the unit runs against.
	Workspace WorkspaceRef `json:"workspace"`
	// TimeoutMS bounds one agent run's wall clock, per tier semantics.
	TimeoutMS int64 `json:"timeoutMS,omitempty"`
	// MaxTurns per agent run (0 = the runner default).
	MaxTurns int `json:"maxTurns,omitempty"`
	// RunsPerQuery repeats each trigger query (tier 1 only).
	RunsPerQuery int `json:"runsPerQuery,omitempty"`
	// Jobs is the in-pod case concurrency (0 = the runner default).
	Jobs int `json:"jobs,omitempty"`
	// Baseline also runs each executed eval without the skill (tier 2).
	Baseline bool `json:"baseline,omitempty"`
	// Judge grades llm assertions (tier 2); nil skips the judge.
	Judge *JudgeSpec `json:"judge,omitempty"`
	// Cases is the case allowlist (trigger queries or eval ids); nil runs
	// all. The client computes --new/--failed/--modified selection locally
	// and encodes the outcome here.
	Cases []string `json:"cases,omitempty"`
	// PriorEntry is the client's existing results entry for this unit,
	// opaque to patchy. It seeds fingerprints, previous-run snapshots, and
	// baselines in-pod, so those behave exactly as they do locally.
	PriorEntry json.RawMessage `json:"priorEntry,omitempty"`
	// ClientVersion is the submitting evolve's version, recorded for skew
	// diagnostics (warned, never enforced).
	ClientVersion string `json:"clientVersion,omitempty"`
}

UnitSpec is one evaluation unit: a skill evaluated on one model at one tier. The triggers/evals spec documents travel in the workspace bundle (the evals/<skill>/ tree), not here — the pod loads them with its own loaders, keeping submissions small and bundles self-contained.

type UnitStatusWire

type UnitStatusWire struct {
	// Name of the EvaluationUnit; the client's idempotency key.
	Name string `json:"name"`
	// Index within the submission, 0-based.
	Index int    `json:"index"`
	Phase string `json:"phase,omitempty"`
	// Harness resolved at launch.
	Harness string `json:"harness,omitempty"`
	// Reason a Failed unit failed:
	// WorkspaceLost|HarnessUnavailable|JobFailed|Aborted|ResultTooLarge.
	Reason string `json:"reason,omitempty"`
	// Detail explains a failure for humans.
	Detail string `json:"detail,omitempty"`
	// Summary is the bounded digest once the unit settled.
	Summary *ResultSummary `json:"summary,omitempty"`
	// Result is the full unit result — Entry included — present once the
	// unit settled with one.
	Result *UnitResult `json:"result,omitempty"`
}

UnitStatusWire is one child's state, sent as an SSE "unit" event and embedded in snapshots. Phase values are Pending|Running|Complete|Failed.

type UnitSummary

type UnitSummary struct {
	Executed      bool     `json:"executed"`
	Passed        int      `json:"passed"`
	Failed        int      `json:"failed"`
	Errored       int      `json:"errored"`
	Total         int      `json:"total"`
	AvgRunSeconds *float64 `json:"avgRunSeconds,omitempty"`
}

UnitSummary mirrors the client's run.UnitSummary — the rollup reported when a unit finishes.

type WorkspaceRef

type WorkspaceRef struct {
	// Digest is the hex sha256 of the deterministic gzip tarball.
	Digest string `json:"digest"`
	// SizeBytes of the tarball.
	SizeBytes int64 `json:"sizeBytes,omitempty"`
}

WorkspaceRef names a content-addressed workspace bundle.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL