client

package
v0.3.0-rc.1 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

Documentation

Overview

Package client is the native Go HTTP client for a Debuglet dispatcher. It runs on the researcher's machine, talks to the dispatcher's existing HTTP API and supports TEST-funded submissions only. It never imports server internals; it shares the dispatcher's HTTP types through pkg/wire.

The guest-side WASI SDK is the separate package pkg/debuglet.

Index

Constants

View Source
const (
	TagSpecVersionLegacy = wire.TagSpecVersionLegacy
	TagSpecVersionV1     = wire.TagSpecVersionV1
)

Tag specification versions of an AttributionSchedule: a legacy chain is unsupported under tag spec v1.

View Source
const (
	// MaxCaptureBytes bounds a capture read by ReadCapture.
	MaxCaptureBytes = 64 << 20
	// MaxCapturePackets bounds the packets ReadCapture returns.
	MaxCapturePackets = 1_000_000
)

Capture limits (docs/verification.md#limits). A larger capture is rejected, never truncated, so a verdict always covers the whole capture it names.

View Source
const (
	// CodeInvalidRequest is a malformed or incomplete request.
	CodeInvalidRequest = "invalid_request"
	// CodeInvalidPolicy is a policy that cannot be priced or scheduled.
	CodeInvalidPolicy = "invalid_policy"
	// CodeUnknownExecutor names an executor that is not registered.
	CodeUnknownExecutor = "unknown_executor"
	// CodeIntentMismatch is a submission whose debuglets differ from the ones
	// the payment intent was created for.
	CodeIntentMismatch = "intent_mismatch"
	// CodePaymentIncomplete is a submission for a transaction that is not paid.
	CodePaymentIncomplete = "payment_incomplete"
	// CodeUnsupportedPaymentMethod is a payment method the API does not admit.
	CodeUnsupportedPaymentMethod = "unsupported_payment_method"
	// CodePaymentsDisabled is a chain payment method while blockchain payments
	// are disabled.
	CodePaymentsDisabled = "payments_disabled"
	// CodeUnsupportedAPIVersion is APIVersion being unavailable on that server.
	CodeUnsupportedAPIVersion = "unsupported_api_version"
	// CodeUnauthorized is a missing, malformed, expired or revoked credential.
	// It is the failure a client answers by logging in again.
	CodeUnauthorized = "unauthorized"
	// CodeForbidden is an authenticated account that may not perform the
	// operation. Logging in again does not help; another account is needed.
	CodeForbidden = "forbidden"
	// CodeNotFound is a debuglet, user or executor that does not exist.
	CodeNotFound = "not_found"
	// CodeIdentityConflict refuses an unsafe sign-in method change.
	CodeIdentityConflict = "identity_conflict"
	// CodeCapacityExhausted is a batch the scheduler cannot admit.
	CodeCapacityExhausted = "capacity_exhausted"
	// CodeAccountQuota is a request exceeding the account's configured
	// run, reserved concurrency or queued-byte allowance.
	CodeAccountQuota = "account_quota_exceeded"
	// CodePayloadDeleted means the requested payload was deleted; the run's
	// identity and original outcome are still retained.
	CodePayloadDeleted = "payload_deleted"
	// CodePayloadNotDeletable means completed output or confirmed executor
	// retirement is missing, so the payload must remain retained.
	CodePayloadNotDeletable = "payload_not_deletable"
	// CodeCancelRefused is a cancellation the dispatcher did not accept.
	CodeCancelRefused = "cancel_refused"
	// CodeMethodNotAllowed is a method the route does not serve.
	CodeMethodNotAllowed = "method_not_allowed"
	// CodeUnsupportedMediaType is a body representation the route does not read.
	CodeUnsupportedMediaType = "unsupported_media_type"
	// CodePayloadTooLarge is a body beyond the accepted size.
	CodePayloadTooLarge = "payload_too_large"
	// CodeInternal is a failure inside the dispatcher, with no detail exposed.
	CodeInternal = "internal_error"
	// CodeUnavailable is a temporarily unavailable capability.
	CodeUnavailable = "service_unavailable"
	// CodeRateLimited is a client address over the rate limit of a public
	// route; retry later.
	CodeRateLimited = "rate_limited"
	// CodeAllowanceExceeded is a TEST intent whose price the account's
	// remaining usage allowance does not cover.
	CodeAllowanceExceeded = "allowance_exceeded"
	// CodeConflict is a request whose idempotency key already names a
	// different request.
	CodeConflict = "conflict"
	// CodeAllowanceOutOfRange is an account whose allowance history cannot be
	// represented in 64-bit integers; an operator has to reconcile it.
	CodeAllowanceOutOfRange = "allowance_out_of_range"
)

Documented failure codes of the dispatcher's HTTP API. They are the stable part of an error: a client selects behaviour by comparing HTTPError.Code against these values instead of matching on Message. A dispatcher may add a code within a contract major version, so treat an unknown code as a plain failure of the status it arrived with.

View Source
const (
	// EvidenceFormat names the bundle format.
	EvidenceFormat = "debuglet-verification-evidence"
	// EvidenceFormatVersion is the bundle format version this client writes
	// and reads.
	EvidenceFormatVersion = 1
	// MaxEvidenceBytes bounds a bundle read by ReadEvidence.
	MaxEvidenceBytes = 256 << 20
)
View Source
const (
	ReasonTagMismatch = "tag_mismatch" // invalid: no packet of the group matches a candidate run
	ReasonNoRun       = "no_run"       // invalid: no run was active from the address

	ReasonNotDisclosed = "not_disclosed" // pending: a needed key is not disclosed yet

	ReasonNotRetained = "not_retained" // missing: the time is before the retained history
	ReasonKeysMissing = "keys_missing" // missing: the history lacks a key that should be disclosed

	ReasonIPv6              = tagspec.UnsupportedIPv6
	ReasonNotIPv4           = tagspec.UnsupportedNotIPv4
	ReasonTooShort          = tagspec.UnsupportedTooShort
	ReasonMalformed         = tagspec.UnsupportedMalformed
	ReasonFragment          = tagspec.UnsupportedFragment
	ReasonLinkType          = "link_type"           // no IP packet could be extracted from the frame
	ReasonTagSpec           = "tag_spec"            // a candidate tags with another or the pre-v1 tag spec
	ReasonDisclosureDelay   = "disclosure_delay"    // a candidate reports a disclosure delay below 2 epochs
	ReasonSchedule          = "schedule"            // a candidate's schedule is unusable
	ReasonBadKey            = "bad_key"             // a served key does not hash to the chain anchor
	ReasonNoSigningKey      = "no_signing_key"      // captured in epoch 0 or after the chain ran out
	ReasonKeyPublic         = "key_public"          // every candidate key may have been public at capture time
	ReasonAmbiguous         = "ambiguous"           // more than one run reproduces every tag
	ReasonUnmatched         = "unmatched"           // no candidate reproduces these packets, but others of their group match
	ReasonTooManyCandidates = "too_many_candidates" // the lookup named more than 32 runs
	ReasonWorkCap           = "work_cap"            // over a verification work cap
)

Machine reasons of a group verdict.

View Source
const (
	// MaxVerifyTagComputations bounds the tag computations of one Verify
	// (packets × candidates × epochs). Groups beyond it are unsupported.
	MaxVerifyTagComputations = 1_000_000

	// DefaultClockTolerance is the default bound on how far the capture
	// clock may lag true time.
	DefaultClockTolerance = time.Second
)

Verification limits (docs/verification.md#limits).

View Source
const (
	DefaultVerifyRequestRate  = 10.0 // requests per second
	DefaultVerifyRequestBurst = 40
)

The dispatcher's documented per-client rate limit of the attribution routes (docs/verification.md#http-api), which Verify paces itself to.

View Source
const (
	// APIVersion is the minimum dispatcher HTTP contract version required by
	// this SDK's operations, as major.minor. It is announced on every request
	// so a server implementing an incompatible contract rejects the request
	// explicitly instead of answering a shape the client cannot read. A server
	// written before the contract was versioned ignores the header.
	APIVersion = "1.3"
)
View Source
const ServerEndpoint = "{server_endpoint}"

ServerEndpoint is replaced only when it is a complete client argument.

View Source
const StateExited = "RunStateExited"

StateExited is the terminal state string reported by the dispatcher. An exited debuglet with an empty Error succeeded; a nonempty Error is a workload failure.

Variables

View Source
var ErrEvidenceDigest = errors.New("client: evidence does not check out: the packets do not match the recorded digest")

ErrEvidenceDigest reports packets that do not match the bundle's digest.

View Source
var ErrNoAttributionHistory = errors.New("client: verify: the dispatcher does not offer the attribution history (GET /attribution/candidates, API 1.11)")

ErrNoAttributionHistory reports a dispatcher without the public attribution routes (API 1.11): it cannot answer dated lookups.

View Source
var ErrNoMatchingExecutor = errors.New("no ready executor matches; check dbl nodes and the requested capability filters")

ErrNoMatchingExecutor reports that no ready executor satisfies a selection.

Functions

func IsEvidence added in v0.3.0

func IsEvidence(prefix []byte) bool

IsEvidence reports whether data starts like an evidence bundle rather than a capture: a JSON object.

func IsTransportError

func IsTransportError(err error) bool

IsTransportError reports whether err is a transport failure of the client: a request that was started could not be sent, or no complete response was read, for example after a connection reset or the request deadline. The server may or may not have processed such a request; the predicate does not say whether it reached the server. An *HTTPError, a protocol error, a local validation failure and a context that was already done before the request was started are not transport failures.

func PacketDigest added in v0.3.0

func PacketDigest(items []EvidencePacket) string

PacketDigest returns the digest of an evidence packet list.

func WriteEvidence added in v0.3.0

func WriteEvidence(w io.Writer, ev Evidence) error

WriteEvidence writes a bundle as indented JSON.

Types

type APICredential added in v0.3.0

type APICredential struct {
	Token        string   `json:"token"`
	CredentialID string   `json:"credential_id"`
	Audience     string   `json:"audience"`
	Scopes       []string `json:"scopes"`
	ExpiresAt    int64    `json:"expires_at"`
	ID           string   `json:"id"`
	Name         string   `json:"name"`
	Role         string   `json:"role"`
}

APICredential is returned once when a browser has approved a device login. Token is usable only at Audience; it belongs in the client's secure store.

type Account

type Account struct {
	ID           string `json:"id"`
	Name         string `json:"name"`
	Role         string `json:"role"`
	AccountKey   string `json:"account_key"`
	RecoveryCode string `json:"recovery_code"`
}

Account is one account together with the credentials an issuing operation returned for it. AccountKey and RecoveryCode are shown by the dispatcher exactly once, at the operation that minted them, and cannot be read back. Treat both as secrets: store them with owner-only permissions and keep them out of logs, command output and receipts.

type Allowance added in v0.3.0

type Allowance = wire.Allowance

Allowance is the account's usage allowance; see Client.Allowance.

type AttributionCandidate added in v0.3.0

type AttributionCandidate = wire.AttributionCandidate

type AttributionCandidates added in v0.3.0

type AttributionCandidates = wire.AttributionCandidates

type AttributionKey added in v0.3.0

type AttributionKey = wire.AttributionKey

type AttributionKeys added in v0.3.0

type AttributionKeys = wire.AttributionKeys

type AttributionSchedule added in v0.3.0

type AttributionSchedule = wire.AttributionSchedule

type CancellationDocument added in v0.3.0

type CancellationDocument = wire.Cancellation

type CaptureError added in v0.3.0

type CaptureError struct {
	// Offset is the byte offset of the offending record, -1 when none.
	Offset int64
	Msg    string
}

CaptureError reports a capture ReadCapture cannot read in full: not a pcap or pcapng file, a malformed or truncated record, or a capture over a limit.

func (*CaptureError) Error added in v0.3.0

func (e *CaptureError) Error() string

type CapturedPacket added in v0.3.0

type CapturedPacket struct {
	// Data is the IP packet, starting at the IPv4 or IPv6 header, without
	// the link-layer header. An IPv4 packet is cut to its Total Length, so
	// link-layer padding and trailers are not part of it; a packet the
	// capture recorded only partly (snap length) is kept as recorded. Data
	// is empty for a frame of a link type ReadCapture does not know.
	Data []byte
	// CapturedAt is the capture's timestamp of the frame: the capture host's
	// clock, which offline verification has to trust.
	CapturedAt time.Time
	// LinkType is the capture's link-layer header type of the frame.
	LinkType uint16
}

CapturedPacket is one frame of a capture.

func ReadCapture added in v0.3.0

func ReadCapture(r io.Reader) ([]CapturedPacket, error)

ReadCapture reads a pcap (microsecond or nanosecond) or pcapng capture and returns its IP packets in capture order. It understands Ethernet (with VLAN tags), raw IP, Linux cooked (SLL and SLL2) and BSD loopback link types; non-IP frames of those (ARP, LLDP, …) are skipped, and frames of any other link type are returned with empty Data so a verifier can report them unsupported. A capture larger than MaxCaptureBytes or holding more than MaxCapturePackets frames, a record whose length is malformed and a capture that ends inside a record are rejected with a *CaptureError: nothing is silently dropped.

type Client

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

Client talks to one dispatcher endpoint. Create it with New.

func New

func New(endpoint string, options Options) (*Client, error)

New validates endpoint and options and returns a Client. The endpoint is an explicit base URL, optionally with a path prefix that is preserved on every route; plaintext HTTP is accepted only for literal loopback IPs.

func (*Client) Allowance added in v0.3.0

func (c *Client) Allowance(ctx context.Context) (Allowance, error)

Allowance returns the authenticated account's usage allowance in TEST units. A dispatcher that does not offer allowances answers 404 with not_found; User.Economics.Allowances tells beforehand.

func (*Client) AttributionCandidates added in v0.3.0

func (c *Client) AttributionCandidates(ctx context.Context, ip string, at time.Time) (AttributionCandidates, error)

AttributionCandidates lists the runs that were active from ip within one epoch of at, with the schedule of each run's chain. It needs no credential and names runs and executors only, never accounts. An empty answer for a time before RetainedFrom is no evidence either way. This optional API 1.11 route is absent on older dispatchers, which answer 404.

func (*Client) AttributionKeys added in v0.3.0

func (c *Client) AttributionKeys(ctx context.Context, executorID, chainID string, fromEpoch, toEpoch int64) (AttributionKeys, error)

AttributionKeys returns one page of the disclosed keys of a chain, from fromEpoch towards toEpoch, spanning at most 1024 epochs; NextEpoch names the fromEpoch of the next page while keys beyond this one exist. A toEpoch of zero sets no bound. Undisclosed epochs are absent, and the caller checks every key against the chain's K0 itself. It needs no credential. This optional API 1.11 route is absent on older dispatchers, which answer 404.

func (*Client) Cancel

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

Cancel asks the dispatcher to abort a debuglet on the given executor. A nil error is an acknowledgement, not proof that execution stopped.

func (*Client) CancelDeviceLogin added in v0.3.0

func (c *Client) CancelDeviceLogin(ctx context.Context, login DeviceLogin) error

func (*Client) Cancellation added in v0.3.0

func (c *Client) Cancellation(ctx context.Context, id string) (CancellationDocument, error)

Cancellation inspects a recorded request without retrying it. This optional API 1.9 route is absent on older dispatchers; Cancel remains compatible.

func (*Client) Connection

func (c *Client) Connection(ctx context.Context) (ConnectionInfo, error)

Connection reads optional local-executor connection metadata. Older servers may return an HTTPError with status 404; their ordinary HTTP API remains usable.

func (*Client) CreateAccount

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

CreateAccount registers an account and returns its first credentials. They are returned exactly once: the dispatcher stores only their digests. The caller is responsible for storing them where only its user can read them.

func (*Client) CredentialStatus added in v0.3.0

func (c *Client) CredentialStatus(ctx context.Context) (CredentialStatus, error)

func (*Client) DeleteProfile added in v0.3.0

func (c *Client) DeleteProfile(ctx context.Context, id string) error

func (*Client) DiscoverExecutors added in v0.3.0

func (c *Client) DiscoverExecutors(ctx context.Context, filter ExecutorFilter) ([]Node, error)

DiscoverExecutors fetches a fresh dispatcher snapshot and returns only ready matches. The dispatcher excludes dead bindings and expires capability reports. Discovery does not hold a reservation; normal submission remains authoritative.

func (*Client) ExecutorEarnings added in v0.3.0

func (c *Client) ExecutorEarnings(ctx context.Context, executorID string) (ExecutorEarnings, error)

ExecutorEarnings returns what an executor the authenticated account owns has earned and the outbound chain transfers that name it. Another account's executor answers 404 with not_found.

func (*Client) Export added in v0.3.0

func (c *Client) Export(ctx context.Context, id string) (Result, error)

Export reads one result snapshot without waiting for execution or output to finish. An unknown outcome or incomplete output remains a successful export.

func (*Client) Login

func (c *Client) Login(ctx context.Context, accountKey string) (Session, error)

Login exchanges an account key for a session. An empty account key asks a dispatcher that serves the local development profile for a credential for its own local account; every other dispatcher refuses it. The returned Session.Token is what Options.Credential takes.

func (*Client) Logout

func (c *Client) Logout(ctx context.Context) error

Logout revokes the session this client presents. The token is refused from then on, before its own expiry. A client without a credential logs nothing out and reports the dispatcher's authentication failure.

func (*Client) Logs

func (c *Client) Logs(ctx context.Context, id string, options LogOptions) (LogPage, error)

Logs returns one page of a debuglet's stored output.

func (*Client) Measurement added in v0.3.0

func (c *Client) Measurement(ctx context.Context, id string) (Measurement, error)

Measurement returns the first page of a measurement's children.

func (*Client) MeasurementRuns added in v0.3.0

func (c *Client) MeasurementRuns(ctx context.Context, id string, limit, offset int64) (Measurement, error)

MeasurementRuns pages bounded references; use RunDetail for a child's config.

func (*Client) MeasurementTemplates added in v0.3.0

func (c *Client) MeasurementTemplates(ctx context.Context) ([]MeasurementTemplate, error)

func (*Client) Measurements added in v0.3.0

func (c *Client) Measurements(ctx context.Context, opts MeasurementOptions) (MeasurementPage, error)

func (*Client) Nodes

func (c *Client) Nodes(ctx context.Context) ([]Node, error)

Nodes lists the dispatcher's registered executors.

func (*Client) Orders added in v0.3.0

func (c *Client) Orders(ctx context.Context, page OrdersPage) (OrderHistory, error)

Orders returns one page of the authenticated account's payment intents, newest first, with their orders and the runs they admitted.

func (*Client) PollDeviceLogin added in v0.3.0

func (c *Client) PollDeviceLogin(ctx context.Context, login DeviceLogin) (DeviceLoginPoll, error)

PollDeviceLogin must be called no faster than the last returned Interval. slow_down increases that interval; denied/expired/consumed end the login.

func (*Client) Probes added in v0.3.0

func (c *Client) Probes(ctx context.Context, statuses ...string) ([]Node, error)

Probes lists the executors whose status is one of statuses (wire.ProbeConnected, ProbeDisconnected, ProbeAbandoned or ProbeNeverConnected), like RIPE Atlas's probe listing; no status lists the connected ones, as Nodes does. Only connected executors can run work. It requires API 1.17: an older dispatcher refuses the request instead of ignoring the filter.

func (*Client) Profile added in v0.3.0

func (c *Client) Profile(ctx context.Context, id string) (Profile, error)

func (*Client) Profiles added in v0.3.0

func (c *Client) Profiles(ctx context.Context) ([]ProfileSummary, error)

func (*Client) Quote added in v0.3.0

func (c *Client) Quote(ctx context.Context, batch *PreparedBatch) (Quote, error)

Quote asks the dispatcher to price batch with the same TEST request body SubmitTEST sends, without creating an intent or reserving anything. A batch the dispatcher would refuse is answered with its problems in the quote's errors and an empty total. A quote is not binding: the dispatcher prices the batch again when SubmitTEST creates its intent, and SubmitTEST does not return that price. A caller that sends the intent itself over HTTP can read the dispatcher's price from the quote field of the intent response.

func (*Client) Recover

func (c *Client) Recover(ctx context.Context, recoveryCode string) (Account, error)

Recover consumes a recovery code and returns the replacement credentials of the one account that code belongs to. Every session of that account is revoked by the dispatcher first. A recovery code can name no other account, so recovering never grants ownership of somebody else's.

func (*Client) Recovery added in v0.3.0

func (c *Client) Recovery(ctx context.Context, id string) (RecoveryDocument, error)

Recovery makes one bounded request for a known run's recovery observation. Unknown classifications and failed workloads are successful inspections; neither an absent row nor a start marker establishes that replay is safe.

func (*Client) RendezvousTEST added in v0.3.0

func (c *Client) RendezvousTEST(ctx context.Context, server, peer Request, opts RendezvousOptions) (result RendezvousResult, failure error)

RendezvousTEST submits a listener once, waits for its bound endpoint, then submits one client on another executor. It never replays an uncertain request. Both known runs are cancelled and inspected on every exit, under an independent bounded cleanup context. Preserve the returned identities even on error.

func (*Client) RetryTEST added in v0.3.0

func (c *Client) RetryTEST(ctx context.Context, parentID, requestID string, batch *PreparedBatch) (Submission, error)

RetryTEST explicitly requests one new attempt. Retain requestID and the same prepared request to recover it after a lost response. No request is retried automatically, and the old run is never resumed or modified.

func (*Client) RunDetail added in v0.3.0

func (c *Client) RunDetail(ctx context.Context, id string) (RunDetail, error)

func (*Client) SaveProfile added in v0.3.0

func (c *Client) SaveProfile(ctx context.Context, id string, config ProfileConfig) (Profile, error)

func (*Client) SelectExecutor added in v0.3.0

func (c *Client) SelectExecutor(ctx context.Context, id string, filter ExecutorFilter) (Node, error)

SelectExecutor returns one ready match, optionally restricted to an explicit ID. Zero or ambiguous matches are errors. This method never submits work.

func (*Client) StartDeviceLogin added in v0.3.0

func (c *Client) StartDeviceLogin(ctx context.Context, label string, scopes []string) (DeviceLogin, error)

StartDeviceLogin requests a credential with explicit scopes. It never sends a provider token or chooses an audience from a remote response.

func (*Client) Status

func (c *Client) Status(ctx context.Context, id string) (State, error)

Status returns the state of one debuglet.

func (*Client) SubmitTEST

func (c *Client) SubmitTEST(ctx context.Context, batch *PreparedBatch) (Submission, error)

SubmitTEST creates a TEST payment intent for the batch and submits it.

func (*Client) Verify added in v0.3.0

func (c *Client) Verify(ctx context.Context, packets []CapturedPacket, opts VerifyOptions) (VerifyReport, error)

Verify attributes captured packets to Debuglet runs (docs/verification.md). It groups the packets by source address and epoch, looks up the runs that were active from each address at the time in the dispatcher's public attribution history, and checks the tags against the disclosed keys offline: packets never leave this process. Groups whose key is not disclosed yet are pending. It needs no credential, and it fails only when the capture or the dispatcher cannot be read; every group verdict, including invalid ones, is part of the report.

The lookups are paced to the dispatcher's per-client rate limit (opts.RequestRate, opts.RequestBurst). A rate-limited request is retried after the dispatcher's Retry-After until ctx ends, and then Verify fails with a *RateLimitedError: give ctx a deadline.

An offline verdict rests on the capture's timestamps: a key is used only if it was still secret at the capture time plus opts.ClockTolerance.

func (*Client) Version

func (c *Client) Version(ctx context.Context) (ServerVersion, error)

Version reports the dispatcher's version identities. It is a report, not an ABI negotiation: the request itself carries APIVersion, and a server that cannot serve it rejects the request. A server written before the contract was versioned answers with Version only, leaving the other fields empty.

func (*Client) Whoami

func (c *Client) Whoami(ctx context.Context) (User, error)

Whoami reports the account this client's credential authenticates as. It is the cheapest way to tell a working credential from an expired or revoked one: the latter answers an *HTTPError with CodeUnauthorized.

func (*Client) WithCredential

func (c *Client) WithCredential(token string) (*Client, error)

WithCredential returns a copy of this client that presents the given session token. The endpoint, transport and timeouts are unchanged, so a credential obtained from one dispatcher cannot be attached to another by accident: a different dispatcher means a different Client.

type ConnectionInfo

type ConnectionInfo struct {
	SchemaVersion int    `json:"schema_version"`
	Mode          string `json:"mode"`
	GRPCAddress   string `json:"grpc_address"`
	YamuxAddress  string `json:"yamux_address"`
}

ConnectionInfo describes the control listeners announced by a local dispatcher. It does not grant access or infer control addresses from an HTTP URL.

type ControlBinding added in v0.3.0

type ControlBinding = wire.ControlBinding

type CredentialStatus added in v0.3.0

type CredentialStatus struct {
	ID        string   `json:"id"`
	Kind      string   `json:"kind"`
	Audience  string   `json:"audience"`
	Scopes    []string `json:"scopes"`
	CreatedAt int64    `json:"created_at"`
	ExpiresAt int64    `json:"expires_at"`
}

CredentialStatus contains no secret and reflects immediate server-side revocation, rather than trusting the local file's expiry alone.

type DeviceLogin added in v0.3.0

type DeviceLogin struct {
	DeviceCode      string   `json:"device_code"`
	UserCode        string   `json:"user_code"`
	VerificationURI string   `json:"verification_uri"`
	Audience        string   `json:"audience"`
	Scopes          []string `json:"scopes"`
	ExpiresAt       int64    `json:"expires_at"`
	Interval        int64    `json:"interval"`
}

DeviceLogin is a short-lived browser approval request. DeviceCode is a secret for polling and cancellation; show only UserCode and VerificationURI.

type DeviceLoginPoll added in v0.3.0

type DeviceLoginPoll struct {
	State      string         `json:"state"`
	Interval   int64          `json:"interval,omitempty"`
	Credential *APICredential `json:"credential,omitempty"`
}

type Economics added in v0.3.0

type Economics = wire.Economics

Economics reports the payment features a dispatcher offers an account, as User.Economics.

type Evidence added in v0.3.0

type Evidence struct {
	Format        string             `json:"format"`
	FormatVersion int                `json:"format_version"`
	CreatedAt     time.Time          `json:"created_at"`
	Tool          EvidenceTool       `json:"tool"`
	TagSpec       int                `json:"tag_spec"`
	Dispatcher    EvidenceDispatcher `json:"dispatcher"`
	// At is the capture time override the verification used, if any; the
	// packets' captured_at already carry it.
	At *time.Time `json:"at,omitempty"`
	// ClockToleranceMS is the capture clock lag bound applied.
	ClockToleranceMS int64           `json:"clock_tolerance_ms"`
	Packets          EvidencePackets `json:"packets"`
	Groups           []EvidenceGroup `json:"groups"`
	// Lookups are the dispatcher's answers to the candidate lookups, one
	// per group formed from them.
	Lookups []EvidenceLookup `json:"lookups"`
	// Chains carry, per executor chain, its schedule and every disclosed key
	// the verification used. Each key hashes to the schedule's k0.
	Chains []EvidenceChain `json:"chains"`
	// Receipts are the dispatcher's signed receipts of server-assisted
	// checks (#341); this client writes none yet.
	Receipts []EvidenceReceipt `json:"receipts"`
}

Evidence is a verification evidence bundle.

func ReadEvidence added in v0.3.0

func ReadEvidence(r io.Reader) (Evidence, error)

ReadEvidence reads a bundle of at most MaxEvidenceBytes and checks its format and version.

type EvidenceCandidate added in v0.3.0

type EvidenceCandidate struct {
	ExecutorID string    `json:"executor_id"`
	RunID      string    `json:"run_id"`
	ActiveFrom time.Time `json:"active_from"`
	ActiveTo   time.Time `json:"active_to"`
	// IPSource is observed or advertised (see AttributionCandidate).
	IPSource         string           `json:"ip_source,omitempty"`
	Schedule         EvidenceSchedule `json:"schedule"`
	DisclosedThrough int64            `json:"disclosed_through"`
}

EvidenceCandidate is one run a lookup named.

type EvidenceChain added in v0.3.0

type EvidenceChain struct {
	ExecutorID string           `json:"executor_id"`
	Schedule   EvidenceSchedule `json:"schedule"`
	Keys       []EvidenceKey    `json:"keys"`
}

EvidenceChain is one chain with the keys a verification used.

type EvidenceDispatcher added in v0.3.0

type EvidenceDispatcher struct {
	URL        string `json:"url"`
	APIVersion string `json:"api_version"`
}

EvidenceDispatcher names the dispatcher whose history a bundle records.

type EvidenceGroup added in v0.3.0

type EvidenceGroup struct {
	Verdict      Verdict      `json:"verdict"`
	Reason       string       `json:"reason,omitempty"`
	Method       VerifyMethod `json:"method,omitempty"`
	Source       string       `json:"source,omitempty"`
	RunID        string       `json:"run_id,omitempty"`
	ExecutorID   string       `json:"executor_id,omitempty"`
	Epoch        int64        `json:"epoch,omitempty"`
	PendingUntil *time.Time   `json:"pending_until,omitempty"`
	Packets      []int        `json:"packets"`
	Matched      int          `json:"matched"`
	Unmatched    int          `json:"unmatched"`
	// Split records the group an entry was split from (VerifyGroup.Split).
	Split    *VerifySplit      `json:"split,omitempty"`
	Schedule *EvidenceSchedule `json:"schedule,omitempty"`
	Keys     []EvidenceKey     `json:"keys,omitempty"`
}

EvidenceGroup is the recorded verdict of one group. Schedule and Keys are those of the named run's chain for the epochs the verdict used.

type EvidenceKey added in v0.3.0

type EvidenceKey struct {
	Epoch int64  `json:"epoch"`
	Key   []byte `json:"key"`
}

EvidenceKey is one disclosed chain key.

type EvidenceLookup added in v0.3.0

type EvidenceLookup struct {
	IP           string              `json:"ip"`
	At           time.Time           `json:"at"`
	RetainedFrom time.Time           `json:"retained_from"`
	Truncated    bool                `json:"truncated,omitempty"`
	Candidates   []EvidenceCandidate `json:"candidates"`
}

EvidenceLookup is the dispatcher's answer to one dated candidate lookup.

type EvidenceMismatchError added in v0.3.0

type EvidenceMismatchError struct {
	Group int
	Msg   string
}

EvidenceMismatchError reports a bundle whose recorded verdicts differ from those its own packets, history and keys yield.

func (*EvidenceMismatchError) Error added in v0.3.0

func (e *EvidenceMismatchError) Error() string

type EvidencePacket added in v0.3.0

type EvidencePacket struct {
	Data       []byte    `json:"data"`
	CapturedAt time.Time `json:"captured_at"`
}

EvidencePacket is one packet: the first 64 bytes of the IP packet (all of a shorter one), and its capture time.

type EvidencePackets added in v0.3.0

type EvidencePackets struct {
	Count int `json:"count"`
	// Digest is "sha256:" and the hex SHA-256 over uint16 length ‖ data ‖
	// int64 captured_at_ns (big-endian) of every packet in order.
	Digest string           `json:"digest"`
	Items  []EvidencePacket `json:"items"`
}

EvidencePackets are the verified packets in order.

type EvidenceReceipt added in v0.3.0

type EvidenceReceipt struct {
	KeyID     string `json:"key_id"`
	Payload   []byte `json:"payload"`
	Signature []byte `json:"signature"`
}

EvidenceReceipt is a signed dispatcher receipt (#341).

type EvidenceSchedule added in v0.3.0

type EvidenceSchedule struct {
	// ChainID identifies the chain.
	ChainID string `json:"chain_id"`
	// K0 is the chain anchor; every key hashes to it.
	K0 []byte `json:"k0"`
	// T0UnixNs is the start of epoch 0.
	T0UnixNs int64 `json:"t0_unix_ns"`
	// EpochSeconds is the epoch length I.
	EpochSeconds int64 `json:"epoch_seconds"`
	// DisclosureDelayEpochs is d; below 2 is refused.
	DisclosureDelayEpochs int64 `json:"disclosure_delay_epochs"`
	// ChainLength is L; zero is unknown.
	ChainLength int64 `json:"chain_length"`
	// TagSpec is the executor-reported tag specification version; 0 is the
	// unversioned pre-v1 tag, which is unsupported.
	TagSpec int64 `json:"tag_spec"`
}

EvidenceSchedule is the public TESLA schedule of one executor chain: the key of epoch e covers [t0 + e·I, t0 + (e+1)·I) and is disclosed from t0 + (e+d)·I.

type EvidenceTool added in v0.3.0

type EvidenceTool struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

EvidenceTool names the program that wrote a bundle.

type ExecutorEarnings added in v0.3.0

type ExecutorEarnings = wire.ExecutorEarnings

ExecutorEarnings is an owned executor's earnings; see Client.ExecutorEarnings.

type ExecutorFilter added in v0.3.0

type ExecutorFilter struct {
	AddressFamilies    []string // ipv4 or ipv6 with a fresh successful controlled observation.
	ReachableListeners []string // tcp, udp or scion; declared support alone is not a match.
	Protocols          []string
	EnforcementMode    string
	MinCapacityBPS     *int64
	// ISDAS requires the executor-reported SCION ISD-AS, such as 1-ff00:0:110.
	// Equivalent spellings match; an unknown ISD-AS does not.
	ISDAS string
	// ASN matches dispatcher-observed control or advertised-host origin. The
	// separate, unverified hello claim never adds a match. Country matches display location.
	ASN     uint32
	Country string
}

ExecutorFilter requires every specified observation. Unknown capabilities do not match requested filters. Capacity is advertised total bandwidth, not a reservation or a promise that a particular run can be admitted.

func (ExecutorFilter) Empty added in v0.3.0

func (f ExecutorFilter) Empty() bool

func (ExecutorFilter) Validate added in v0.3.0

func (f ExecutorFilter) Validate() error

type HTTPError

type HTTPError struct {
	Method      string
	Path        string
	StatusCode  int
	Code        string
	Message     string
	FieldErrors []wire.FieldError

	// RetryAfter is the delay a 429 or 503 response asked for in its
	// Retry-After header; zero when it named none.
	RetryAfter time.Duration
	// contains filtered or unexported fields
}

HTTPError reports a response the client did not accept: any status other than the one expected for the route, including other 2xx codes. Code is the dispatcher's stable failure code, the field to branch on; Message is a bounded, sanitized diagnostic for a human and must not be parsed. A server that sends no documented envelope leaves Code empty. Unrecognized JSON bodies use a generic diagnostic. Recognized auth_key fields and known submission keys are redacted. Path never contains a query or request body.

func (*HTTPError) Error

func (e *HTTPError) Error() string

type IncompleteOutputError added in v0.3.0

type IncompleteOutputError struct {
	Output OutputStatus
}

IncompleteOutputError means the available prefix was drained without proof of complete output. It says nothing about the workload's success or failure.

func (*IncompleteOutputError) Error added in v0.3.0

func (e *IncompleteOutputError) Error() string

type LogEntry

type LogEntry = wire.LogEntry[[]byte]

LogEntry is one stored output chunk. Output holds the exact guest bytes; Timestamp is the server's opaque string.

type LogOptions

type LogOptions struct {
	After int64
	Limit int64
}

LogOptions selects a log page. After is a cursor (entry ID) that must be >= 0; Limit zero defaults to 100, otherwise it must be within 1..1000.

type LogPage

type LogPage = wire.LogPage[[]byte]

LogPage is one page of guest output.

type Measurement added in v0.3.0

type Measurement = wire.Measurement

type MeasurementOptions added in v0.3.0

type MeasurementOptions struct {
	State, Search string
	Limit, Offset int64
}

type MeasurementPage added in v0.3.0

type MeasurementPage = wire.MeasurementPage

type MeasurementTemplate added in v0.3.0

type MeasurementTemplate = wire.MeasurementTemplate

type Node

type Node = wire.Executor

Node is one executor as reported by GET executors.

type Options

type Options struct {
	// HTTPClient supplies transport settings. It is cloned, never mutated,
	// and redirects are always rejected. nil uses a fresh client.
	HTTPClient *http.Client
	// RequestTimeout bounds each request including its body read. Zero
	// defaults to 10 s; a negative value is invalid.
	RequestTimeout time.Duration
	// AllowRemoteTEST permits TEST submissions to endpoints other than a
	// literal loopback IP. It is an accident guard, not server authorization:
	// an SSH-forwarded loopback endpoint is still an operator-selected remote
	// service.
	AllowRemoteTEST bool
	// Credential is the session token this client presents on every request,
	// as an Authorization bearer header. It is obtained from Login and belongs
	// to exactly one dispatcher: a Client is bound to one origin and refuses
	// redirects, so a credential never travels to another one. It is never
	// written to a log, an error message or a returned diagnostic. Empty makes
	// unauthenticated requests, which a dispatcher serving the local
	// development profile still accepts.
	Credential string
}

Options configures a Client. The zero value is valid for a loopback endpoint: a fresh HTTP client, a 10 s per-request timeout and no remote TEST submissions.

type OrderHistory added in v0.3.0

type OrderHistory = wire.OrderHistory

OrderHistory is one page of Client.Orders.

type OrdersPage added in v0.3.0

type OrdersPage struct {
	Limit  int64
	Before string
}

OrdersPage selects one page of Client.Orders. A zero Limit asks for the server's default page size; Before is the Next value of the previous page.

type OutputStatus added in v0.3.0

type OutputStatus = wire.OutputStatus

OutputStatus records output finality; missing metadata from older servers is unknown.

type Policy

type Policy = wire.Policy

Policy is the network policy requested for a debuglet.

type PreparedBatch

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

PreparedBatch is an immutable, validated batch produced by Prepare. The same serialized debuglets array is sent for the payment intent and the submission, so the server's request hash check sees identical values. A zero or nil PreparedBatch is invalid.

func Prepare

func Prepare(requests []Request) (*PreparedBatch, error)

Prepare validates requests and freezes them into one immutable serialized batch used for both submission steps.

type Profile added in v0.3.0

type Profile = wire.Profile

type ProfileConfig added in v0.3.0

type ProfileConfig = wire.ProfileConfig

type ProfileSummary added in v0.3.0

type ProfileSummary = wire.ProfileSummary

type Quote added in v0.3.0

type Quote = wire.Quote

Quote is the dispatcher's price of a batch; see Client.Quote.

type RateLimitedError added in v0.3.0

type RateLimitedError struct {
	// Throttled counts the requests the dispatcher answered 429.
	Throttled int
	// UncheckedGroups is how many groups remain without a verdict (at least
	// this many when Partial is set: the lookups had not reached every
	// packet), and UncheckedPackets how many packets they hold.
	UncheckedGroups  int
	UncheckedPackets int
	Partial          bool
	// Err is the context's error.
	Err error
}

RateLimitedError reports a verification that the dispatcher's rate limit held back until its context ended. The groups it names were not checked.

func (*RateLimitedError) Error added in v0.3.0

func (e *RateLimitedError) Error() string

func (*RateLimitedError) Unwrap added in v0.3.0

func (e *RateLimitedError) Unwrap() error

type RecoveryDocument added in v0.3.0

type RecoveryDocument = wire.Recovery

type RecoveryObservation added in v0.3.0

type RecoveryObservation = wire.RecoveryObservation

type RecoveryObserver added in v0.3.0

type RecoveryObserver = wire.RecoveryObserver

type RendezvousOptions added in v0.3.0

type RendezvousOptions struct {
	ReadinessTimeout time.Duration
	Timeout          time.Duration
	Output           func(role, runID string, page LogPage) error
}

type RendezvousResult added in v0.3.0

type RendezvousResult struct {
	Server   RendezvousRun `json:"server"`
	Client   RendezvousRun `json:"client"`
	Endpoint string        `json:"endpoint"`
}

type RendezvousRun added in v0.3.0

type RendezvousRun struct {
	ID            string `json:"id"`
	ExecutorID    string `json:"executor_id"`
	TransactionID string `json:"transaction_id"`
	State         string `json:"state"`
	Error         string `json:"error"`
	Cleanup       string `json:"cleanup"`
}

type Request

type Request = wire.Request[[]byte]

Request describes one debuglet in a batch. Wasm holds the guest bytes and encoding/json transmits it as base64.

type Result added in v0.3.0

type Result = wire.Result

func ReadResult added in v0.3.0

func ReadResult(r io.Reader) (Result, error)

ReadResult reads a saved export without a dispatcher or credentials. It validates format, bounds and consistency, not the authenticity of its author or the truth of measurements. No network requests are made.

type RetainedRun added in v0.3.0

type RetainedRun = wire.RetainedRun
type RetryLink = wire.RetryLink

type RunDetail added in v0.3.0

type RunDetail = wire.RunDetail

type ServerVersion

type ServerVersion = wire.Version

ServerVersion reports the dispatcher's independent version identities. Every field beyond Version is empty for older dispatchers.

type Session

type Session struct {
	Token     string `json:"token"`
	CSRFToken string `json:"csrf_token"`
	ExpiresAt int64  `json:"expires_at"`
	ID        string `json:"id"`
	Name      string `json:"name"`
	Role      string `json:"role"`
}

Session is an issued session. Token is the bearer credential to put in Options.Credential. CSRFToken is only of interest to a browser client that received the session as a cookie; a native client never needs it. ExpiresAt is Unix seconds.

type State

type State = wire.State

State is a debuglet's reported state. Unknown state strings are preserved.

type Submission

type Submission struct {
	IDs           []string `json:"ids"`
	TransactionID string   `json:"transaction_id"`
}

Submission is the result of an accepted TEST submission. IDs are in batch order. No auth key is exposed.

type SubmissionError

type SubmissionError struct {
	Stage         string
	TransactionID string
	// AdmittedIDs are durable run identities in request order when a failed
	// submission returned a valid complete list. They prove admission, not
	// upload, execution, cancellation or completion. Inspect each run.
	AdmittedIDs    []string
	OutcomeUnknown bool
	Err            error
}

SubmissionError reports a failed SubmitTEST. Stage is "intent" or "submit". TransactionID is retained when the intent had already been created. OutcomeUnknown is set conservatively when the submission may have been accepted by the server although no valid response was observed (transport or read failure after sending, malformed success, an unexpected submission 2xx, or a server 5xx); it is uncertainty, not proof of acceptance. A validated pre-send failure or a 4xx response is a rejection with OutcomeUnknown false, and so is a 503 that carries service_unavailable or payments_disabled at the intent stage: nothing was priced or written.

func (*SubmissionError) Code

func (e *SubmissionError) Code() string

Code returns the dispatcher's failure code when the submission failed on a response that carried one, and "" otherwise. It never changes how the outcome itself is classified: OutcomeUnknown stays the only statement about whether the submission may have been accepted.

func (*SubmissionError) Error

func (e *SubmissionError) Error() string

func (*SubmissionError) Unwrap

func (e *SubmissionError) Unwrap() error

type User

type User = wire.User

User is the account a request authenticated as, as reported by GET me.

type Verdict added in v0.3.0

type Verdict string

Verdict is the outcome of one packet group.

const (
	// VerdictVerified: every packet carries a valid tag of the named run at
	// the named epoch (or the epoch before it).
	VerdictVerified Verdict = "verified"
	// VerdictInvalid: the history covers the time and no candidate run
	// reproduces any of the tags (Reason tag_mismatch or no_run).
	VerdictInvalid Verdict = "invalid"
	// VerdictPending: the key is not disclosed yet; retry after PendingUntil.
	VerdictPending Verdict = "pending"
	// VerdictMissing: the dispatcher holds no schedule or key for the time.
	// This is no evidence either way.
	VerdictMissing Verdict = "missing"
	// VerdictUnsupported: the group cannot be checked; Reason says why.
	VerdictUnsupported Verdict = "unsupported"
)

type VerifyCounts added in v0.3.0

type VerifyCounts struct {
	Verified    int `json:"verified"`
	Invalid     int `json:"invalid"`
	Pending     int `json:"pending"`
	Missing     int `json:"missing"`
	Unsupported int `json:"unsupported"`
}

VerifyCounts counts groups by verdict.

type VerifyGroup added in v0.3.0

type VerifyGroup struct {
	Verdict Verdict `json:"verdict"`
	// Reason is the machine reason of any verdict but verified.
	Reason string `json:"reason,omitempty"`
	// Detail explains the verdict in a sentence.
	Detail string `json:"detail"`
	// Method is how the verdict was established; empty when nothing was
	// checked.
	Method VerifyMethod `json:"method,omitempty"`
	// Source is the packets' source address; empty for frames without IP.
	Source     string `json:"source,omitempty"`
	RunID      string `json:"run_id,omitempty"`
	ExecutorID string `json:"executor_id,omitempty"`
	// Epoch is the capture epoch under the run's (or the address's first
	// candidate's) schedule; zero when there is none.
	Epoch int64 `json:"epoch,omitempty"`
	// Time is the capture time of the group's first packet.
	Time time.Time `json:"time"`
	// PendingUntil is when the last key the group needs is disclosed.
	PendingUntil *time.Time `json:"pending_until,omitempty"`
	// Packets are indices into the verified packets, in capture order.
	Packets []int `json:"packets"`
	// Matched counts the packets whose tag some candidate run reproduces,
	// Unmatched those it does not; a count of matches is only meaningful
	// together with the non-matches (docs/tag-spec.md §7). For an entry of
	// a split group they count the entry's own packets; Split has the
	// group's.
	Matched   int `json:"matched"`
	Unmatched int `json:"unmatched"`
	// Candidates counts the runs the group was checked against.
	Candidates int `json:"candidates"`
	// AmbiguousRuns lists the runs that each reproduce every tag.
	AmbiguousRuns []string `json:"ambiguous_runs,omitempty"`
	// FalseMatchBound bounds the probability that packets not sent by the
	// run match it by chance: N·C(n,k)·(E·2⁻¹⁶)^k for N candidates, E = 2
	// epochs and k of the group's n packets, which is N·(E·2⁻¹⁶)^n for an
	// unsplit group (docs/tag-spec.md §7). It underflows to zero for large k.
	FalseMatchBound float64 `json:"false_match_bound,omitempty"`
	// DisclosedAt is when the latest key the verdict used became due for
	// disclosure; packets captured before it (by a trustworthy clock) cannot
	// have been forged with that key.
	DisclosedAt *time.Time `json:"disclosed_at,omitempty"`
	// Split describes the address-and-epoch group this entry was split
	// from, when not all its packets reproduce one run; nil otherwise.
	Split *VerifySplit `json:"split,omitempty"`
	// contains filtered or unexported fields
}

VerifyGroup is the verdict of the packets of one source address in one epoch.

type VerifyMethod added in v0.3.0

type VerifyMethod string

VerifyMethod names how a group's verdict was established.

const (
	// VerifyMethodOffline: the verifier checked the tags itself against
	// disclosed keys. It shows the packets came from the run only if they
	// were captured before the disclosure, which rests on the capture's own
	// timestamps.
	VerifyMethodOffline VerifyMethod = "offline"
	// VerifyMethodServer is the server-assisted check of #341; this client
	// does not perform it yet.
	VerifyMethodServer VerifyMethod = "server"
)

type VerifyOptions added in v0.3.0

type VerifyOptions struct {
	// At, when set, is taken as the capture time of every packet instead of
	// the capture's own timestamps.
	At time.Time
	// Offline never uploads packets: groups whose key is not disclosed yet
	// are pending. Server-assisted verification (#341) is not implemented
	// yet, so every verification is offline today.
	Offline bool
	// ClockTolerance bounds how far the capture host's clock may lag true
	// time. A key is used only if it was still secret at the capture time
	// plus this. Zero is DefaultClockTolerance.
	ClockTolerance time.Duration
	// RequestRate (requests per second) and RequestBurst pace the history
	// requests of Client.Verify as a token bucket, to stay within the
	// dispatcher's per-client rate limit. Zero is the documented limit,
	// DefaultVerifyRequestRate and DefaultVerifyRequestBurst; a negative
	// rate disables pacing. After a 429 every request waits for the
	// Retry-After either way.
	RequestRate  float64
	RequestBurst int
}

VerifyOptions tune Verify.

type VerifyReport added in v0.3.0

type VerifyReport struct {
	// TagSpec is the tag specification the tags were checked under.
	TagSpec string `json:"tag_spec"`
	// CheckedAt is the time verification ran (for VerifyEvidence, the time
	// the bundle was created).
	CheckedAt time.Time `json:"checked_at"`
	// At is the capture time override, if any.
	At *time.Time `json:"at,omitempty"`
	// Dispatcher is the dispatcher the history came from.
	Dispatcher string `json:"dispatcher,omitempty"`
	// ClockTolerance is the capture clock lag bound applied.
	ClockToleranceMS int64 `json:"clock_tolerance_ms"`
	// Packets counts the packets checked.
	Packets int           `json:"packets"`
	Counts  VerifyCounts  `json:"counts"`
	Groups  []VerifyGroup `json:"groups"`
	// contains filtered or unexported fields
}

VerifyReport is the result of Verify or VerifyEvidence.

func VerifyEvidence added in v0.3.0

func VerifyEvidence(ctx context.Context, ev Evidence) (VerifyReport, error)

VerifyEvidence checks a bundle again, offline: the packet digest, every key against its chain anchor, and every group's verdict recomputed from the packets, the recorded lookups and keys as of the bundle's creation. It returns the recomputed report, with an *EvidenceMismatchError when a recorded verdict differs. The lookups and schedules are the dispatcher's claims; the bundle does not authenticate them (the operator signature of #71(b) will).

func (VerifyReport) Evidence added in v0.3.0

func (r VerifyReport) Evidence() Evidence

Evidence returns the evidence bundle of a verification. Tool names this package; a program writing the bundle may replace it.

type VerifySplit added in v0.3.0

type VerifySplit struct {
	// Packets counts the packets of the whole group.
	Packets int `json:"packets"`
	// Matched counts those some candidate run reproduces, Unmatched those
	// no candidate does.
	Matched   int `json:"matched"`
	Unmatched int `json:"unmatched"`
	// Runs lists the runs packets were attributed to.
	Runs []string `json:"runs"`
}

VerifySplit describes a packet group that was split: its packets of each run, those several runs reproduce (ambiguous) and those no run reproduces (unmatched) are reported as separate entries, each carrying this record, so that every entry's match count can be read against the whole group's (docs/tag-spec.md §7).

Jump to

Keyboard shortcuts

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