api

package
v1.1.1 Latest Latest
Warning

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

Go to latest
Published: Nov 5, 2026 License: Apache-2.0 Imports: 32 Imported by: 0

Documentation

Overview

Package api exposes the engine over JSON HTTP, on a Unix socket. A remote TLS listener is backlog (design §12.1). Clients, the foreman's MCP tools and runners reach the engine only through this API, never the store directly, authenticating with bearer tokens in the roles of client, foreman, runner and admin. Mutating calls take idempotency keys, because the callers are often LLMs whose tool calls may repeat.

Index

Constants

View Source
const HealthTimeout = 500 * time.Millisecond

HealthTimeout bounds one Health probe when a caller polls for the engine to come up (§13): short, because a socket that is not there refuses at once and a live engine answers in milliseconds.

Variables

This section is empty.

Functions

func AgentsTable

func AgentsTable(snap engine.CapacitySnapshot, now time.Time, style term.Style, width int) []string

AgentsTable is the AGENTS table of CapacityTables alone, as lines.

func CapacityTables

func CapacityTables(snap engine.CapacitySnapshot, now time.Time, style term.Style, width int) string

CapacityTables renders the capacity snapshot (§12.2) as two aligned tables for a terminal. AGENTS: each agent's harness/model, tier, effort, cost weight, running jobs against its effective cap — its own cap folded with the global layer — and the layer that binds it, then its quota — ready, cooling until a local time, or broken. LAYERS: each cap layer's name and key, its cap, use and queue depth. style supplies the colour; with a plain style the text is the same and has no escapes. The last column of each table is cut to fit width.

func DescribeJob added in v1.1.0

func DescribeJob(j engine.StatusJob, now time.Time) string

DescribeJob is one running job in a few words: "task #3 work · claude/sonnet · 1m40s · Edit". A foreman turn names no task; the parts the engine does not know yet are left out. A "tool_start Edit" event shows as the tool's name alone; other events show as they are.

func GlobalCap added in v1.1.0

func GlobalCap(snap engine.CapacitySnapshot) *int

GlobalCap is the snapshot's global layer cap, nil when there is no global layer or the layer is uncapped. Plan layers stay out of an agent's effective cap: they bound a plan, not an agent.

func HeldWait added in v1.1.0

func HeldWait(h engine.HeldJob) string

HeldWait words why one held job waits (§8.1): a runner slot, a free slot on a named layer, its agent's quota — the agent and when its cooling ends — an unnamed agent's cooling, or a foreman turn no runner offers the agent for (no_pair). StatusSections renders it after `held: <what> <kind>: ` per held entry, and top's plans tree reuses it, so the two read the same words.

func LocalClock added in v1.1.0

func LocalClock(stamp string, now time.Time) string

LocalClock is a stored UTC stamp as a clock time in now's zone (the local zone when now is time.Now): the hour and minute on the day of now, the date too on any other day. A stamp that does not parse is shown as it is.

func RetryLine

func RetryLine(r engine.InfraRetry, now time.Time) string

RetryLine words one job waiting on an infra retry (§5.1) for the status and top views: "task #4 work: retry in 5m: could not resolve github.com" — the job or task, its kind, the time left to its not-before and the failure's words.

func RunningCap added in v1.1.0

func RunningCap(a engine.CapacityAgent, global *int) string

RunningCap is an agent's running jobs against its effective cap — the smaller of the agent's own cap and the snapshot's global cap — with the layer that binds it: "1/4 (runner)", "1/8 (global)", or "1/none" when no layer caps it. A tie names the agent's own layer.

func StatusLine

func StatusLine(st Status, now time.Time) string

StatusLine renders the status as one short line for a terminal status bar (§10): the running jobs — the first one described, the rest counted — then what needs the user, or "idle" when nothing runs and nothing waits. An idle line names the latest plan that finished inside status's window, so a bar shows a plan's end even when nothing else announced it.

func StatusSections

func StatusSections(st Status) string

StatusSections renders one status answer's running jobs, plans, foreman report and "needs you" sections (§6.1, §6.2, §3, §10) as plain text, after the pid/uptime and jobs lines: the `running:` lines — one per job a runner holds, with the worker's latest event — then the `plans:` lines — one per plan, its tasks indented beneath it — then the `foreman report:` block — the latest report's time and first lines, the project named — then the `needs you:` queue, "nothing" when it is empty. The client's status command and the MCP bridge's status tool share this rendering, so a user and the foreman read the same lines; a task's branch rides in brackets only once it has one, and a done implement task carries its landing state beside the state — `landed@<sha>` or `not landed`. The plans list the engine trimmed says so in one summary line (§10): the older finished plans counted, the all view (`--all`, all=true) listing them.

Types

type Agent

type Agent struct {
	Adapter string   `json:"adapter"`
	Harness string   `json:"harness"`
	Model   string   `json:"model"`
	Family  string   `json:"family"`
	Account string   `json:"account"`
	Classes []string `json:"classes"`
	// Effort is the agent's reasoning-effort level; empty when unset.
	Effort string `json:"effort,omitempty"`
	// Tools is a claude worker's tool scope (§5.2), "+"-joined or
	// "none"; empty for a harness brigada does not scope.
	Tools string `json:"tools,omitempty"`
}

Agent is one advertised agent as the client sends it (§5.1): an (adapter, harness, model) combination with its family, account label and the classes it can take. The account labels the login whose quota the agent spends (§8: quota cooling covers the whole account); the runner's default is the harness name.

type AttachResult

type AttachResult struct {
	Answer        engine.Answer
	HoldID        int64 // the created hold; a busy answer names the live hold
	JobID         int64 // a busy answer names the live foreman turn; 0 otherwise
	ForemanToken  string
	RepoURL       string
	DefaultBranch string
	LandTarget    string // the effective land target; the default branch when unset
	Harness       string
	Model         string
	Effort        string // the foreman's reasoning-effort level; ” = unset
	SessionID     string // the key's current harness session id; ” = none
	Prompt        string // the opening prompt
	ExpiresAt     time.Time
}

AttachResult is the attach answer as the client reads it (§4.2 item 1): a created hold carries everything the attached session needs; the busy answer carries what made it busy — the live turn's job id, or the live hold's id — so the caller can wait one out and refuse the other without parsing words.

type Client

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

Client is the engine API's client side, the one callers run: the runner speaks the runner protocol (§12.3) through it over the Unix socket, authenticating with a runner token. The engine's protocol answers — ok, lost, gone, cancelled, stale_epoch — come back as engine.Answer values, not errors: they are outcomes the caller branches on. Errors are the transport and the API's own refusals.

func NewClient

func NewClient(socketPath, token string) *Client

NewClient builds a client for the engine's Unix socket, bearing the given bearer token.

func NewClientWithHTTPClient

func NewClientWithHTTPClient(client *http.Client, token string) *Client

NewClientWithHTTPClient uses a supplied transport, including an in-process handler transport. The HTTP client must route http://brigada to the API.

func (*Client) AcceptPlan

func (c *Client) AcceptPlan(ctx context.Context, plan int64, reason, idemKey string) (PlanDecisionResult, error)

AcceptPlan accepts a plan its review parked at needs_foreman as reviewed, with the reason recorded (§6.2, §12.2); the plan proceeds as a spent round's verdict does. idemKey is the call's idempotency key, minted per logical call by the bridge (§12.1). A plan that is not there is the API's not-found error, one not parked its conflict.

func (*Client) AmendPlan

func (c *Client) AmendPlan(ctx context.Context, plan int64, a PlanAmend, idemKey string) (PlanAmendResult, error)

AmendPlan amends a live plan (§12.2). idemKey is the call's idempotency key, minted per logical call by the bridge.

func (*Client) Answer

func (c *Client) Answer(ctx context.Context, task int64, text, idemKey string) (TaskAnswerResult, error)

Answer answers a task worker's question (§3, §12.1, §12.2): the task must be parked at needs_foreman by its question; the answer resumes the author's session, verbatim. idemKey is the call's idempotency key, minted per logical call by the bridge (§12.1).

func (*Client) ApprovePlan

func (c *Client) ApprovePlan(ctx context.Context, plan int64, andStopAsking bool) (PlanDecisionResult, error)

ApprovePlan is the user's yes (§6.3): the plan's first wave queues. andStopAsking also changes the one setting each hold reason maps to, through the `brigada project set` path. A plan that is not there is the API's not-found error, one not awaiting approval its conflict.

func (*Client) ApprovePlanVersion

func (c *Client) ApprovePlanVersion(ctx context.Context, repoURL string, plan, version int64, andStopAsking bool) (PlanDecisionResult, error)

ApprovePlanVersion is ApprovePlan for the plan version the user was shown (§4.6): the plan must belong to repoURL's project and still be at version, else the API refuses with its stale_plan 409 and nothing is applied. andStopAsking is ApprovePlan's.

func (*Client) ArchiveProject

func (c *Client) ArchiveProject(ctx context.Context, repoURL string, cancel bool) (engine.Answer, error)

ArchiveProject removes a repository from active service, preserving history. cancel authorizes cancellation of its live jobs and unfinished plans.

func (*Client) Artifact

func (c *Client) Artifact(ctx context.Context, id int64) ([]byte, error)

Artifact fetches one artifact's blob (§9): the transcript or check log a run left behind.

func (*Client) AskForeman

func (c *Client) AskForeman(ctx context.Context, repoURL, text, idemKey string) (engine.AskResult, error)

AskForeman sends the user's message to a project's foreman (§4.2 item 3) through /v1/foreman/messages and returns what it did: the project, the event that holds it, and the wake's outcome. An empty repoURL names the engine's only project; idemKey, when set, makes a retried call send one message (§12.1).

func (*Client) AskUser

func (c *Client) AskUser(ctx context.Context, text, key string) (int64, error)

func (*Client) Attach

func (c *Client) Attach(ctx context.Context, repoURL string, force bool) (AttachResult, error)

Attach takes the foreman's key for an attached chat (§4.2 item 1), naming the project by its repo URL the way every caller does (§12.1). force cancels a live foreman turn rather than waiting it out. A busy answer — a live turn, or a second live attach — is not an error: it comes back with Answer busy and the id that made it busy, for the caller to branch on.

func (*Client) AttachHeartbeat

func (c *Client) AttachHeartbeat(ctx context.Context, holdID int64) (engine.Answer, error)

AttachHeartbeat extends a live attach hold (§4.2 item 1), the way the runner's heartbeat extends a lease. The engine's answers — ok, gone — ride in the return, not as errors.

func (*Client) CancelJob

func (c *Client) CancelJob(ctx context.Context, jobID int64) (engine.Answer, error)

CancelJob stops a live job (§12.1). The engine's answers — ok, already, gone — come back as engine answers, not errors.

func (*Client) Capacity

func (c *Client) Capacity(ctx context.Context, projectID int64) (engine.CapacitySnapshot, error)

Capacity reads the capacity snapshot (§12.2) through /v1/capacity: per agent the effective cap, the layer that sets it, the running jobs, the quota state and the cost weight; per layer — each runner, each account, each capped model, each active plan of the project and global — the cap, the use and the queue depth. projectID limits the plan layer to one project's active plans; 0 names none, which for a foreman token means its own project (§12.1) and for a client or admin means every project's.

func (*Client) Complete

func (c *Client) Complete(ctx context.Context, jobID int64, leaseID string, comp Completion) (engine.Answer, error)

Complete delivers the run's outcome (§12.3).

func (*Client) CreatePlan

func (c *Client) CreatePlan(ctx context.Context, p PlanCreate, idemKey string) (PlanCreateResult, error)

CreatePlan creates a plan with its tasks and the work job of each task without dependencies queued (§6.2, §12.1). idemKey is the call's idempotency key, minted per logical call by the caller that knows what makes one — the bridge hashes the tool call's arguments — so a repeated call replays the first answer instead of planning twice.

func (*Client) Draining

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

Draining tells the engine the runner has a restart drain pending: it takes no new lease and exits once its running jobs finish, so the status can say the runner is restarting (§5.1).

func (*Client) DueProbes

func (c *Client) DueProbes(ctx context.Context) ([]engine.Probe, error)

DueProbes lists the runner's due broken-agent probes (§8 "Health"): the failure-broken agents whose next probe is due, for the runner to probe and report.

func (*Client) ForemanEvents

func (c *Client) ForemanEvents(ctx context.Context, wait time.Duration) (engine.ForemanInbox, error)

ForemanEvents long-polls the token's project for pending judgment events (§4.2, §12.2): the events tool's call, and a headless turn's token may use it too. wait bounds the long-poll; the engine caps it. The events come back rendered exactly as the wake prompt renders them, consumed by the read — an empty answer says "no new events".

func (*Client) Health

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

Health probes /v1/health (§12.1): the one unauthenticated endpoint, "is the engine up" and nothing more. nil means an engine answered.

func (*Client) HealthProbe

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

HealthProbe is one health probe on a short timeout, the start-on- demand loop's single step (§13).

func (*Client) Heartbeat

func (c *Client) Heartbeat(ctx context.Context, jobID int64, leaseID string, prog Progress) (engine.Answer, time.Time, error)

Heartbeat reports the runner is still on the job, carrying the worker's progress (§5.6).

func (*Client) History

func (c *Client) History(ctx context.Context, q HistoryQuery) (history.Page, error)

History reads one page of the timeline (§9): events and messages merged, oldest first. With Last it is the newest page.

func (*Client) ImportProjectConfig

func (c *Client) ImportProjectConfig(ctx context.Context, repoURL string, content []byte, accept bool) (engine.ImportResult, error)

ImportProjectConfig sends a project.yaml's content for import. With accept false a first import over hand-set values returns them as diffs (NeedsConfirm) and changes nothing.

func (*Client) ImportProjectConfigFull

func (c *Client) ImportProjectConfigFull(ctx context.Context, repoURL string, content []byte, instructions *string, roles map[string]string, skills *[]engine.Skill, accept bool) (engine.ImportResult, error)

ImportProjectConfigFull is ImportProjectConfigRoles for a file that names a skills_dir (§5.10): skills, when not nil, is every skill the client parsed under it and replaces the project's set; an empty set drops them all.

func (*Client) ImportProjectConfigRoles

func (c *Client) ImportProjectConfigRoles(ctx context.Context, repoURL string, content []byte, instructions *string, roles map[string]string, accept bool) (engine.ImportResult, error)

ImportProjectConfigRoles is ImportProjectConfigWith for a file whose nested instructions map names role files: roles holds the text the client read for each (§5.9).

func (*Client) ImportProjectConfigWith

func (c *Client) ImportProjectConfigWith(ctx context.Context, repoURL string, content []byte, instructions *string, accept bool) (engine.ImportResult, error)

ImportProjectConfigWith is ImportProjectConfig for a file that names an instructions_file: instructions is the text the client read from it.

func (*Client) Issue

func (c *Client) Issue(ctx context.Context, number int, comments bool) (engine.Issue, error)

Issue reads one issue or pull request of the token's own project (§12.1 issues, §12.2 issue_read): number names it on the project's own repository, which the token's project alone picks — never an argument — and comments asks for the comments too. A refusal carries the reason in its message: the repository is not on GitHub, gh is missing or not logged in, the number does not exist.

func (*Client) Job

func (c *Client) Job(ctx context.Context, id int64) (engine.JobInfo, error)

Job reads one job (§12.1): its status, and the ids of its transcript and check log artifacts. A job that is not there is a *StatusError with 404.

func (*Client) LandApprove

func (c *Client) LandApprove(ctx context.Context, id int64, andStopAsking bool) (engine.LandDecision, error)

LandApprove releases a task's land-gate hold (§6.3): the landing is re-evaluated and, when nothing else trips, its land job queues. andStopAsking also changes the one setting each hold reason maps to, through the `brigada project set` path.

func (*Client) LandReject

func (c *Client) LandReject(ctx context.Context, id int64) (engine.LandDecision, error)

LandReject cancels a task's landing (§6.3): the branch stays, nothing is squashed or pushed, and the rejection is recorded.

func (*Client) Lease

func (c *Client) Lease(ctx context.Context, wait time.Duration, harnesses, labels []string) (*JobGrant, error)

Lease long-polls for a job the runner may take (§12.3): one whose harness constraint it satisfies — every harness in harnesses is offered — and whose labels it covers. nil comes back when the wait runs out with nothing to do.

func (*Client) ProjectForeman

func (c *Client) ProjectForeman(ctx context.Context, repoURL string) (engine.ForemanSetting, error)

ProjectForeman reads the foreman's harness and model back (§4.1). The API's 404 — the repo has no project — comes back as the call's error.

func (*Client) ProjectReader

func (c *Client) ProjectReader(project int64) *Client

ProjectReader returns a copy of the client whose reads — status, history, stats — name one project, for a caller whose token is not scoped to it (the coordinator's client token).

func (*Client) ProjectSettings

func (c *Client) ProjectSettings(ctx context.Context, repoURL string) (engine.ProjectSettings, error)

ProjectSettings reads the repo's settings. The API's 404 — the repo has no project — comes back as the call's error.

func (*Client) Projects

func (c *Client) Projects(ctx context.Context) ([]engine.ProjectInfo, error)

Projects lists active projects with their foreman, active plans and needs-you count.

func (*Client) PushApprove

func (c *Client) PushApprove(ctx context.Context, repoURL string) (engine.PushApproveResult, error)

PushApprove releases the push gate for the repo's waiting landings (§6.3): each gets a push job, the land job reused as its push phase.

func (*Client) RecordLanded

func (c *Client) RecordLanded(ctx context.Context, repoURL, branch string, landed []engine.LandedCommit) error

RecordLanded reports landings detected from the project's default branch (§7.1): each entry names a task whose Brigada-Task trailer sits on a commit of branch, landed outside the land job. The engine records the ones that belong to repoURL's project and have no landing yet.

func (*Client) Register

func (c *Client) Register(ctx context.Context, agents []Agent, maxParallel int) error

Register registers the runner under its token's name with its advertised agents (§5.1, §12.3) and its own cap on parallel jobs (§8.1); maxParallel 0 means the runner advertised none. A re-register replaces the runner's set.

func (*Client) RejectPlan

func (c *Client) RejectPlan(ctx context.Context, plan int64) (PlanDecisionResult, error)

RejectPlan is the user's no (§6.3): the plan's tasks are cancelled.

func (*Client) RejectPlanVersion

func (c *Client) RejectPlanVersion(ctx context.Context, repoURL string, plan, version int64) (PlanDecisionResult, error)

RejectPlanVersion is RejectPlan for the plan version the user was shown; see ApprovePlanVersion.

func (*Client) Release

func (c *Client) Release(ctx context.Context, jobID int64, leaseID, reason string) (engine.Answer, error)

Release gives a job back (§12.3): queued again for the next runner, with the reason kept.

func (*Client) ReleaseAttach

func (c *Client) ReleaseAttach(ctx context.Context, holdID int64, sessionID string) (engine.Answer, error)

ReleaseAttach ends an attached chat (§4.2 item 1), carrying the harness session id the chat ended on: a resume forks session ids, and the key's row must carry the id the chat reached. The engine's answers — ok; expired for a late release whose hold lapsed but whose session id was still written; gone — ride in the return.

func (*Client) ReportProbe

func (c *Client) ReportProbe(ctx context.Context, agentID int64, ok bool) error

ReportProbe delivers one probe's result (§8 "Health"): ok is whether the agent's CLI answered.

func (*Client) ResetAgent

func (c *Client) ResetAgent(ctx context.Context, harness, model string) (int, error)

ResetAgent clears broken and cooling (§8) on the agents of a harness and model through /v1/agents/reset; it returns how many agents matched. An unknown pair is the API's not-found error.

func (*Client) RestartTask

func (c *Client) RestartTask(ctx context.Context, task int64, note, idemKey string) (TaskRestartResult, error)

RestartTask restarts a parked task (§3, §5.6, §12.1, §12.2): a fresh work attempt from the task's base, the note handed to the worker verbatim when there is one. idemKey as in Answer.

func (*Client) RetireTasks

func (c *Client) RetireTasks(ctx context.Context, tasks []int64, reason, idemKey string) (engine.RetireResult, error)

RetireTasks retires tasks that will not land (§6.2, §12.1): their live jobs stop, their land holds drop, their branches stay untouched and their plans close over them, each retirement recorded with the reason verbatim. idemKey as in Answer.

func (*Client) RetryLanding

func (c *Client) RetryLanding(ctx context.Context, task int64, idemKey string) (LandRetryResult, error)

RetryLanding runs the land rule again for a task parked by a rejected push, an environment failure or a failed land check (#133). A refusal is an outcome, not an error, and it is replayed under idemKey like any answer: a key must not outlive the park it was minted for.

func (*Client) ReviewBranch

func (c *Client) ReviewBranch(ctx context.Context, repoURL, branch, idemKey string) (engine.ReviewBranchResult, error)

ReviewBranch asks the engine for a standalone review of a branch (§7) through /v1/reviews and returns the job it queued. An empty repoURL names the engine's only project; idemKey, when set, makes a retried call queue one review (§12.1).

func (*Client) SetProjectForeman

func (c *Client) SetProjectForeman(ctx context.Context, repoURL, harness, model, effort string) (engine.ForemanSetting, error)

SetProjectForeman chooses the foreman's harness and model for a repo (§4.1), creating the project when the engine has none for the URL. The engine refuses an empty field and a harness that cannot resume headless; those refusals come back as the API's 400s.

func (*Client) SetProjectSettings

func (c *Client) SetProjectSettings(ctx context.Context, repoURL string, values map[string]string) (engine.ProjectSettings, error)

SetProjectSettings applies key=value pairs to the repo's project.

func (*Client) SetRoleInstructions

func (c *Client) SetRoleInstructions(ctx context.Context, repoURL string, roles map[string]string) error

SetRoleInstructions sets the roles' instruction texts as local overrides.

func (*Client) SetWakeBudget

func (c *Client) SetWakeBudget(ctx context.Context, repoURL string, wakes int) (*engine.WakeBudgetInfo, error)

SetWakeBudget sets the project's daily foreman wake budget and re-evaluates the waiting wake (§4.3).

func (*Client) Stats

func (c *Client) Stats(ctx context.Context, projectID int64) ([]engine.ProjectStats, error)

Stats reads the outcome record per project (§8) through /v1/stats: each agent's attempts, successes and score per class, the registered-but-unrecorded ones at attempts 0. projectID names one project; 0 names none, which for a foreman token means its own project (§12.1) and for a client or admin every project.

func (*Client) Status

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

Status reads the engine's own state (§13): which process it is, since when, and the jobs by status. The plans list keeps every live plan and the newest finished ones only.

func (*Client) StatusAll

func (c *Client) StatusAll(ctx context.Context, withText bool) (Status, error)

StatusAll is Status with every finished plan listed, not only the newest few (§10): `all` on /v1/status — the MCP status tool's all parameter, `brigada status --all`. withText is StatusWithInstructions's flag.

func (*Client) StatusWithFileDigests

func (c *Client) StatusWithFileDigests(ctx context.Context, project int64, d FileDigests) (Status, error)

StatusWithFileDigests is Status for one project with the client's current file digests, so the engine can flag what changed since import. The stored snapshots are not touched.

func (*Client) StatusWithInstructions

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

StatusWithInstructions is Status with the full project instruction text (§5.9), for the foreman's status tool.

func (*Client) SubmitTask

func (c *Client) SubmitTask(ctx context.Context, t TaskSubmit) (TaskSubmitResult, error)

SubmitTask creates one task with its first work job queued (§12.1, the debug path until the foreman's plan tools exist).

func (*Client) Task

func (c *Client) Task(ctx context.Context, id int64) (engine.TaskInfo, error)

Task reads one task (§12.1): its repo, base ref, result branch and latest job. A task that is not there is a *StatusError with 404.

func (*Client) TaskLand

func (c *Client) TaskLand(ctx context.Context, id int64) (engine.TaskLandInfo, error)

TaskLand reads what `brigada land` needs of a task (§7.1). A task that is not there is a *StatusError with 404.

func (*Client) UploadArtifact

func (c *Client) UploadArtifact(ctx context.Context, jobID int64, leaseID, kind string, data []byte) (engine.Answer, int64, error)

UploadArtifact uploads one artifact blob of a run the caller holds (§9, §12.3): the session's transcript or the check's log, keyed by job and lease and fenced like a complete. The engine caps the blob and stores it content-addressed; the same content for the same job and kind answers already with the first row's id.

func (*Client) WakeBudget

func (c *Client) WakeBudget(ctx context.Context, repoURL string) (*engine.WakeBudgetInfo, error)

WakeBudget reads the project's foreman wake budget (§4.3): the effective budget, today's use, the reset time and the waiting events. An empty repoURL names the engine's only project.

type Completion

type Completion struct {
	Usage       *adapter.Usage
	WallSeconds *float64
	Result      string
	Error       string
	CheckResult string
	SessionID   string
	Outcome     string
	// ErrorKind sorts an Error: the adapter's kind for a CLI failure
	// ("limit", "auth"…), empty when the failure was none the CLI named.
	// LimitUntil is the reset time of a "limit" (RFC3339, best-effort):
	// empty means unknown.
	ErrorKind  string
	LimitUntil string
	// StaleDropped names the target whose stale waiting ref a land job
	// deleted.
	StaleDropped string
}

Completion is a run's outcome as the client delivers it (§5.4, §5.5): exactly one of Result or Error, the check result when the runner ran the task's check, and the harness session the run ended on. Outcome, when set to stalled or time_cap, names a run the runner stopped itself (§5.6); held or not ready are the land_ready gate's answers (issue #87), a land job's alone. Either way it rides with the Result. Artifacts are not the completion's to name: the runner uploads them through UploadArtifact (§9), which stores them itself.

type FileDigests

type FileDigests struct {
	// Roles maps a role to the digest of its file.
	Roles map[string]string
	// Skills maps a skill name to the digests of its SKILL.md and its tree.
	Skills map[string]engine.SkillFileDigest
}

FileDigests are the client's current digests of the files a project.yaml names (§5.9, §5.10), each over the file text without its version header.

type HistoryQuery

type HistoryQuery struct {
	ProjectID int64
	TaskID    int64
	JobID     int64
	Since     string
	Limit     int
	Last      bool
}

HistoryQuery is one page of the timeline as the client asks for it (§9): the filters, the cursor the previous page ended on, and the page size. Last asks for the newest page instead of the next one; it cannot be combined with Since.

type JobGrant

type JobGrant jobGrant

JobGrant is a lease grant as the runner receives it: the job to run, the lease to speak about it, and the task's workspace fields.

type LandRetryResult

type LandRetryResult struct {
	TaskID  int64
	Outcome string
	JobID   int64
	Reason  string
}

LandRetryResult names what a land_retry did (#133): Outcome is one of engine.LandRetryQueued (JobID the land job), LandRetryHeld, LandRetryStaleBase or LandRetryRefused (Reason says why).

type PlanAmend

type PlanAmend struct {
	Add      []PlanTask
	Cancel   []string
	Retarget []PlanRetarget
	Retier   []PlanRetier
	Respec   []PlanRespec
}

PlanAmend is a plan_amend call as the bridge sends it (§12.2): tasks to add, tasks to cancel, and waiting tasks whose dependencies are re-pointed, tier or effort changes for waiting or parked tasks, and spec edits of pending tasks. Tasks and dependencies name tasks of the plan by name, or by id as a decimal.

type PlanAmendResult

type PlanAmendResult struct {
	PlanID     int64
	State      string
	Added      []PlanCreatedTask
	Cancelled  []int64
	Retargeted []int64
	Retiered   []int64
	Respecced  []int64
	Started    []PlanCreatedTask
	Held       []PlanHeldTask
	Reasons    []string
}

PlanAmendResult names what the amendment did: the plan's state after it, the added tasks, the ids cancelled and re-pointed, the tasks it started (a work job queued), the added or respecified tasks a plan rule held, and why the plan waits for approval, if it does.

type PlanCreate

type PlanCreate struct {
	RepoURL string
	Title   string
	Tasks   []PlanTask
}

PlanCreate is a plan_create call as the bridge sends it (§6.2, §12.1, §12.2): the plan's title, its tasks — each may depend on others of the plan by name — and, for a caller that is not the project's foreman, the repo URL naming the project. A foreman token's own project is the only one it may plan in, so it leaves RepoURL empty.

type PlanCreateResult

type PlanCreateResult struct {
	Answer engine.Answer
	PlanID int64
	TaskID int64
	JobID  int64
	Tasks  []PlanCreatedTask
	// State and Reasons: the plan's state, and why it waits when the
	// approval limit holds it (§6.3).
	State   string
	Reasons []string
}

PlanCreateResult names what the call created: the plan, the first ready task with its queued work job, and every task.

type PlanCreatedTask

type PlanCreatedTask struct {
	TaskID int64
	Name   string
	JobID  int64
}

PlanCreatedTask is one task the plan made; JobID is 0 while the task waits on its dependencies.

type PlanDecisionResult

type PlanDecisionResult struct {
	PlanID   int64
	State    string
	Tasks    []PlanCreatedTask
	Settings []string
}

PlanDecisionResult is what approving or rejecting a plan did (§6.3): the plan's new state, for an approval the first wave's tasks with their queued work jobs, and the key=value pairs a stop-asking approval changed.

type PlanHeldTask

type PlanHeldTask struct {
	TaskID int64
	Name   string
	Reason string
}

PlanHeldTask is one added or respecified task a plan rule held, with the rule's name.

type PlanRespec

type PlanRespec struct {
	Task   string
	Spec   string
	Mode   string
	Skills []string
}

PlanRespec edits the spec of a pending task: Mode replace (the default) or append. Skills, when not nil, replaces the task's recorded skills.

type PlanRetarget

type PlanRetarget struct {
	Task string
	Deps []string
	Base string
	// Continue names the one of Deps whose author's session the task
	// continues (§6.1); ” = the default rule.
	Continue string
}

PlanRetarget replaces one waiting task's whole dependency set.

type PlanRetier

type PlanRetier struct {
	Task         string
	Tier         string
	Effort       string
	ReviewTier   string
	ReviewEffort string
	Caps         map[string]int // merged key by key into the task's caps
	Skills       []string       // nil keeps the recorded skills
}

PlanRetier changes a waiting or parked task's tier, effort, review tier or review effort; empty keeps it. Skills, when not nil, replaces the recorded skills of a task that has not started.

type PlanTask

type PlanTask struct {
	Tier   string `json:"tier,omitempty"`
	Effort string `json:"effort,omitempty"`
	// ReviewTier and ReviewEffort are the task's own tier and effort for
	// its reviews (§7, §8); empty = the engine default.
	ReviewTier   string `json:"review_tier,omitempty"`
	ReviewEffort string `json:"review_effort,omitempty"`
	// Caps overrides the round caps (fix_rounds, review_rounds, restart);
	// absent keys keep the engine default.
	Caps  map[string]int `json:"caps,omitempty"`
	Title string
	Name  string   // the handle other tasks name in Deps; ” = unnamed
	Deps  []string // names of tasks of the same plan this one waits for
	Base  string   // the one of Deps whose branch the work starts from; ” = the default rule
	// Continue names the one of Deps whose author's session the task's
	// first work job resumes (§6.1); ” = start fresh.
	Continue string
	Spec     string
	Check    string
	Class    string
	// ExtraRepos are read-only repositories for the task (§5.8): nil
	// inherits the project default, a non-nil list (even empty) replaces
	// it.
	ExtraRepos []engine.ExtraRepo
	// Skills names, in order, the project's imported skills the task's
	// prompts carry (§5.10); nil or empty = none.
	Skills []string `json:"skills,omitempty"`
}

PlanTask is one task of the plan (§6.1): title, name, spec, check, class and dependencies; an empty class means implement.

type Progress

type Progress struct {
	LastProgressAt time.Time
	LastActivityAt time.Time
	Events         []string
	// Loop reports the worker repeating the same tool call (§5.6);
	// LoopCall names the call. The signal rides every beat once it
	// trips; nothing is stopped for it.
	Loop     bool
	LoopCall string
}

Progress is what a heartbeat carries besides its hold (§5.6).

type Server

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

Server is the engine's HTTP API (design §12.1, §12.3): JSON over a Unix socket (Listen). A remote TLS listener is backlog. Clients, the foreman's MCP tools and runners reach the engine only through here, authenticating with bearer tokens in the roles of client, foreman (scoped to one project), runner and admin.

func New

func New(ctx context.Context, st *store.Store, eng *engine.Engine, log *slog.Logger, tokenFile string) (*Server, error)

New builds the API server: it loads the token file — refusing one looser than mode 0600 — and re-syncs the sha256 hashes into the store's tokens table (§6.4: the secrets stay in the file, the store keeps only hashes). The store is also where idempotency responses live (§12.1).

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns the API's routes behind authentication, so the same mux is served on a Unix socket (Listen).

func (*Server) InFlight

func (s *Server) InFlight() int

InFlight is the number of requests the API is serving right now — §13's "connected long-polls" as a number.

func (*Server) Listen

func (s *Server) Listen(ctx context.Context, socketPath string) error

Listen serves the API on the Unix socket at socketPath (§12.1) until ctx is canceled or serving fails, then removes the socket file it owns. A leftover socket file is replaced only when it is provably stale — a socket nothing answers on — and a live engine's socket is never stolen. On cancel, in-flight requests get a bounded grace period to finish before the listener closes.

type Status

type Status struct {
	Pid       int64              `json:"pid"`
	StartedAt string             `json:"started_at"`
	Jobs      map[string]int     `json:"jobs"`
	Running   []engine.StatusJob `json:"running"`
	// RunnerDraining is true while a runner has a restart drain pending
	// (§5.1): it finishes its running jobs and exits, and the rendered
	// status says the runner is restarting behind them.
	RunnerDraining bool `json:"runner_draining,omitempty"`
	// ForemanMessages counts the user's messages waiting for the
	// foreman (§4.2 item 3).
	ForemanMessages int `json:"foreman_messages"`
	// Slots is who holds the foreman's slot per project (§4.6).
	Slots []engine.Slot       `json:"slots"`
	Plans []engine.StatusPlan `json:"plans"`
	// HiddenFinishedPlans counts the finished plans the plans list left
	// out (§10): the default keeps the newest few, `all` lists every
	// one. Rendered as the one summary line.
	HiddenFinishedPlans int                   `json:"hidden_finished_plans,omitempty"`
	Report              *engine.StatusReport  `json:"report,omitempty"`
	NeedsYou            []engine.NeedsYouItem `json:"needs_you"`
	// ForemanHolds lists the tasks the foreman handles (§10): out of
	// needs_you for a caller that is not the foreman, kept apart so the
	// plan tree still shows the worker's question beside the task.
	ForemanHolds []engine.NeedsYouItem `json:"foreman_holds,omitempty"`
	// Cooling lists the agents held back for quota (§8, §10).
	Cooling []engine.CoolingAgent `json:"cooling,omitempty"`
	// Held lists the queued jobs a full cap layer holds (§8.1).
	Held []engine.HeldJob `json:"held,omitempty"`
	// Retries lists the queued jobs waiting out an infrastructure
	// backoff (§5.1): rendered as `retry in 5m: <failure>`.
	Retries []engine.InfraRetry `json:"retries,omitempty"`
	// Instructions names the projects with project instructions (§5.9):
	// source, version, size and digest; the text only when asked for.
	Instructions     []engine.StatusInstructions     `json:"instructions,omitempty"`
	RoleInstructions []engine.StatusRoleInstructions `json:"role_instructions,omitempty"`
	Skills           []engine.StatusSkill            `json:"skills,omitempty"`
}

Status is the engine's own state as the client reads it (§13): the pid, the start, the jobs by status — and the plans with their tasks, the latest foreman report (§3, §10) and the "needs you" queue (§10), scoped by the token: a foreman token reads its own project, a client or admin every project.

type StatusError

type StatusError struct {
	Method  string
	Path    string
	Status  int
	APICode string // the API's own error code, e.g. unknown_runner
	Message string
	// Body is the refusal's raw body, kept for the callers that read a
	// structured refusal the plain message cannot carry — the attach's
	// busy answer names the turn or hold that made it busy.
	Body []byte
}

StatusError is the API refusing a call: the transport worked, the engine answered, and the answer was no. Callers branch on Status — a 4xx is the caller's own mistake and will not heal with retries, while anything else (the store behind the engine, a socket that vanished mid-request) may.

func (*StatusError) Error

func (e *StatusError) Error() string

func (*StatusError) IsClientError

func (e *StatusError) IsClientError() bool

IsClientError reports whether the refusal is the caller's: a 4xx names a mistake in the call itself, permanent until the caller changes, so retrying it is noise.

type TaskAnswerResult

type TaskAnswerResult struct {
	Answer     engine.Answer
	QuestionID int64
	JobID      int64
	Run        int
}

TaskAnswerResult names what an answer did: the questions row it filled and the job that carries the answer to its worker.

type TaskRestartResult

type TaskRestartResult struct {
	Answer engine.Answer
	JobID  int64
	Run    int
}

TaskRestartResult names what a task_restart did: the fresh work job.

type TaskSubmit

type TaskSubmit struct {
	RepoURL  string
	BaseRef  string
	Title    string
	Spec     string
	CheckCmd string
	Class    string
	Harness  string
	Labels   []string
	// Skills names, in order, the project's imported skills the task's
	// prompts carry (§5.10); nil or empty = none.
	Skills []string
}

TaskSubmit is one task submitted whole, as the debug path sends it (§12.1): the repo and base ref, the spec verbatim, and the check. The worker prompt is the engine's to compose (§1.4), never the caller's.

type TaskSubmitResult

type TaskSubmitResult struct {
	Answer    engine.Answer
	ProjectID int64
	TaskID    int64
	JobID     int64
	Run       int
}

TaskSubmitResult names what the submit created.

Jump to

Keyboard shortcuts

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