member

package
v1.2.9 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Overview

Package member is a fleet member of a sprint: the loop a fleet machine runs against the sprint's fleet table (the machine's queue) and the sprint's verbs, with each card run as one child through a runner. The fleet table is the dispatcher; the member only replays, for real, the sequence the world driver plays in simulation: beat, queue, push and finish what ended, take to its width, start each card taken as a child. A reader runs the same loop against the readers table: begin what was asked, report what ended.

The member speaks to the sprint only through its command line and JSON (Sprint), and runs a card only through a Runner, so the harness underneath (a Claude Code child, an OpenCode child, a test double) is replaceable and the loop is testable without a store or a process.

A work card ends at a local commit inside the wall, which holds no credential; the member, outside the wall, pushes that commit to origin's branch the sprint named (Pusher) before it reports the finish, so the merge finds the work on origin from any machine.

Index

Constants

View Source
const (
	GatePreExisting = cardhdr.EndPreExisting
	GateGreen       = "green"
)

The gate routes the member acts on (native's NATIVE GATE line): a gate red only on pre-existing failures, and a gate whose every failure was flaky and passed its rerun.

View Source
const (
	EndProvider = cardhdr.EndProvider // the sprint's route stats count it apart
	EndStaging  = cardhdr.EndStaging  // no child ran: the sprint deals the card to another member
	EndNoResult = cardhdr.EndNoResult // the child left no result: the sprint deals the card again
	EndBudget   = "budget"
	EndDeadline = "deadline"
	// EndIdleReap is native's mark for a card its idle watch ended (`reason=idle-reap`
	// on the NATIVE line): neither the provider, the budget nor the deadline stopped it,
	// and the finish names the reaping rather than the deadline, because the deadline
	// never fired (docs/roadmap.sexp, swarm-idle-reap-verdict: the verdict states idle
	// reaping).
	EndIdleReap = "idle-reap"
	// EndUnverifiable is native's end=budget-unverifiable (docs/SPEC-SWARM.md, native): the
	// member's usage source, its read of the harness's usage database, stopped answering and
	// native ended the child for a budget it could no longer see. Judge says it as a budget
	// end when the child left a result; a child it ended with none is the member's failure
	// (the source is this machine's), finished staging refused, and the member rests
	// (UsageRest).
	EndUnverifiable = "budget-unverifiable"
)

The ends Judge names first in a failed finish.

View Source
const BeatStall = 5 * time.Minute

BeatStall is how long the work pass may go without advancing before the member stops beating. A pass advances at every sprint verb it gets an answer to, every push that ends and every pass it begins; each verb is bounded (two minutes, the member's own budget), so five minutes without one is a pass that is stuck, not slow.

View Source
const CarryKey = "CARRY:"

CarryKey begins a brief's CARRY: line.

View Source
const DefaultScriptDeadline = 30 * time.Minute

DefaultScriptDeadline bounds a script run whose card names no deadline.

View Source
const DrainMost = 2 * time.Minute

DrainMost is the longest a draining member waits for its children: two minutes. A member that drains does no new work, so a restart that waits longer costs the machine's whole width, while a card killed at the bound is redealt at the cost of one card; past the bound the member reports what finished and stops, and the cards still running are left for the server to redeal as for any member that stops. The stop timeout of the loop units (fleet/templates: TimeoutStopSec, ExitTimeOut) is DrainMost and a minute, so a member always stops by itself before its supervisor kills what is left.

View Source
const LongStall = 30 * time.Minute

LongStall is how long a launch's long work (its start, its result read, its push) may be in flight before the member stops beating. It is above the sum of that work's own budgets (a fetch and a push of up to five minutes each, the push tried again, a pull request of a minute) and above a start's wait behind a width of others, so work that is slow and bounded never stops the beat; only work that outlives every budget does.

View Source
const MaxFindingBytes = 6 << 10

MaxFindingBytes bounds a broken read's finding as the member reports it: under the sprint's bound on a card's text field (sprint.MaxCardTextBytes), so a long review is cut, never refused.

View Source
const NoFinding = "no finding"

NoFinding begins the reason of a read the member hands back because its broken verdict names no defect (docs/SPEC-CARD-CONTRACT.md section 3).

View Source
const ProgressEvery = 3 * time.Minute

ProgressEvery is how often the member stamps progress on a card whose child prints: the sprint's own number (internal/sprint ProgressEvery, inside its RuleProgressWindow of ten minutes with room for a stamp that is late or lost; docs/SPEC-SPRINT.md section 8, the rules table's row late).

View Source
const ProposedKey = "PATHS-PROPOSED:"

ProposedKey begins the one line a held report proposes the PATHS its card lacked by (docs/SPEC-CARD-CONTRACT.md section 4, "recut-widen-r.w1"): PATHS-PROPOSED: <glob>[,<glob>...].

View Source
const ReadStageRetry = 15 * time.Second

ReadStageRetry is how long a read whose stage failed waits before it is run again once by the same reader (docs/SPEC-SPRINT.md, the readers; docs/SPEC-CARD-CONTRACT.md, staging).

View Source
const ReceiptName = "usage.tsv"

ReceiptName is a launch's durable receipt in its job directory: one row per attempt.

View Source
const ScriptReadPrefix = "script read: "

ScriptReadPrefix begins the finding of a script read that found the head the program's own output. The sprint counts reads by it (sprint.ScriptReadPrefix is this constant), so the prefix the member writes and the one the sprint reads are one value.

View Source
const StartGap = 300 * time.Millisecond

StartGap is the least time between two harness starts on one member, so the cards a pass takes do not all start their harness in the same instant (sixteen at once on one machine lost their start).

View Source
const StopReturnReason = "owned process stopped"

StopReturnReason is the reason every stop-return names.

View Source
const StopReturnRetry = time.Minute

StopReturnRetry is how long a refused stop-return waits before it is sent again: the store's verb may be absent or the machine already RUNNING, and a verb a pass is a flood.

View Source
const TmpText = "" /* 149-byte string literal not displayed */

TmpText tells a child where its temp files go. The sandbox denies a write outside the directories it was handed, and /tmp is not one of them: a child that wrote /tmp/gate1.log had its run refused for the denial (fault 1, 2026-10-10). $TMPDIR is its own, writable.

View Source
const UsageRest = 10 * time.Minute

UsageRest is how long a member starts no card after a launch of its ended because its usage source stopped answering (EndUnverifiable: native's read of the harness's usage database, this machine's own): a launch started while it stays so would end the same way, and each such end is the member's failure, reported on the staging kind (Judge). A launch that ends so during the rest begins it again from its end; the rest is a clock's, since no launch runs to read the source again while it holds (the usage source outage of 2026-10-03, 11:46 PM, ended every child on the flash routes together, and each end was judged as its card's).

View Source
const WallFinishShare = 0.8

WallFinishShare is the share of the wall by which the card tells the child to have its RESULT.md written (WallText): the rest is the member's margin to end, push and report.

Variables

This section is empty.

Functions

func BriefOf

func BriefOf(card string) string

BriefOf is the brief a card file (CardText) begins with, the sprint's mechanics after it cut off: what the decide read is asked over, as its bars were calibrated (the work card alone, never the read's mechanics or the worker's report).

func CardText

func CardText(p Packet) string

CardText is the card file a child is given: the brief VERBATIM first (a card's brief is a whole child brief in the card grammar `nova-swarm lint --card` checks, whose line 1 is the contract line), then, appended, the mechanics the sprint adds: the attempt, the branch and base when a base names a repository, the fix of this attempt, the notes, and the exact command that reports it. Nothing is put in front of the brief.

func CarryLine

func CarryLine(c Carry) string

CarryLine is c as its brief header line: CARRY: <card> attempt <n> head=<sha>.

func CarryProposed

func CarryProposed(report string, r Result) string

CarryProposed is a finish's report with the child's PATHS-PROPOSED line, read from its report and else its body, kept at the report's end within the 500-byte cut, so brief --widen reads it off the card (docs/SPEC-SPRINT.md section 2, "recut-widen-r.w1"); the report as it is when the child proposed nothing or the report holds the line already.

func DrainBound

func DrainBound(longest time.Duration) time.Duration

DrainBound is how long a member stopped by its supervisor (SIGTERM) waits for the children it runs: the longest deadline they run to, and LongStall for the push and the report after it, at most DrainMost (nova-tools#5096 item 26).

func IsReadCardID

func IsReadCardID(id string) bool

IsReadCardID says the card id is a read card's, <primary>.r<attempt>.<reader>[.g<n>] (internal/sprint ParseReadCard, which this package may not import).

func PathsProposed

func PathsProposed(text string) (globs []string, ok bool)

PathsProposed is the globs of the first PATHS-PROPOSED line in text, read to the end of its line or a ";", empty ones left out: the paths alone, read before any prose on that line. Each comma-separated item is its first word, trimmed of quotes, emphasis and a closing full stop; an item with words after its first ends the paths ("b.go, c.go because the test needs it" is b.go and c.go). ok is false when text has no such line.

func ReceiptUsage

func ReceiptUsage(job string) (usage cardcost.Usage, found bool, err error)

ReceiptUsage is the cost record of a launch read from its job's receipt (ReceiptName): the rows' tokens summed by class, the provider/model the last row named, and the harness's cost only when every row that reported tokens reported one (a cost for part of the launch is not the launch's; the sprint then prices the tokens). found is false with no receipt or no row; a receipt that does not read is an error, never a zero.

func ResolveStepCommit

func ResolveStepCommit(ctx context.Context, dir, branch, prefix string) (string, error)

ResolveStepCommit resolves prefix, 7 to 40 lowercase hex, to the one full sha of branch in dir (docs/SPEC-SPRINT.md, the verdict per step). The commits are git rev-list of that branch. Two that share the prefix, or a prefix git calls ambiguous, are refused as ambiguous; none is unknown. A full sha is checked the same way. The walk is local: a fetch would run under the checkout's own config, which the child wrote.

func ResultText

func ResultText(r Result) string

ResultText is a child's result as its RESULT.md says it (docs/SPEC-CARD-CONTRACT.md section 3), the fields the member read and its body; "" when it wrote none.

func WallText added in v1.2.7

func WallText(deadlineSeconds int) string

WallText is the paragraph that tells a child the wall it runs under, the deadline the member ends it at (the route's, or the member's override), in whole minutes, and when to have its result written; "" when the packet carries none. It overrides any time the brief names: a child on a slow member planned against a brief's "finish within 120 minutes" and was ended at the route's 40 with no RESULT.md, its commit unpushed (fault 9, 2026-10-10).

Types

type Carry

type Carry struct {
	Card    string
	Attempt int
	Head    string
}

Carry is where a card's next attempt starts when brief --widen widens it in place, or a rule's twin's first: the held card, its attempt and the head that attempt pushed, written into the brief header as its CARRY: line (docs/SPEC-SPRINT.md section 2, "recut-widen-r.w1").

func CarryOf

func CarryOf(brief string) (c Carry, ok bool)

CarryOf is the CARRY: line of a brief's header (line 1 and the lines after it up to the first blank one), ok only with a card, an attempt and a full sha.

type Child

type Child interface {
	// Done says whether the child has ended.
	Done() bool
	// Result is how it ended: ok, the head it finished at (a work card;
	// "" when unknown), and the report (one paragraph, the child's own words).
	Result() Result
}

Child is one running card.

type Config

type Config struct {
	As string // the member's (reader's) name in the fleet (readers) table
	// Width is an override of the most cards it runs at once, a twin's. A
	// worker with none runs the width its fleet row names, read with its
	// queue every tick (the fleet row is the truth): a member's own row, a
	// reader's the row of the machine it is named for (reader-<m> runs at
	// m's width, sprint.ReaderMachine).
	Width  int
	Reader bool // run the readers-table loop instead of the fleet's
	// Room is asked once a tick before any child is started (a recovered card or a taken
	// one): ok false starts none that tick, with why said once when it begins and once when
	// it ends. nil asks nothing (docs/SPEC-SWARM.md, `member`, the disk floor).
	Room func() (ok bool, why string)
	// Now is the clock the work pass's progress is read on (BeatLoop); nil is time.Now.
	Now func() time.Time
	// Meter is the machine's one-second CPU samples, taken by a goroutine of the caller
	// (hostload.Sampler.Run); nil, or with no sample since the last beat, the beat
	// measures the machine itself.
	Meter *hostload.Sampler
	// Sleep waits between two harness starts (StartGap); nil starts them back to back
	// (the tests' member). Clock is the time it measures the gap by; nil is time.Now.
	Sleep func(time.Duration)
	Clock func() time.Time
	// Background takes the long work out of the pass: a launch's start, its result and its
	// push run apart from the pass that began them and are collected by a later pass, and
	// Wake says when one posted or a child exited. false (the tests' member) does each where
	// the pass asks for it, so a pass is one step.
	Background bool
	// Attempt asks the attempt decision over every work take's end (docs/SPEC-SPRINT.md
	// section 2, the attempt decision; the card's bars decide at the server whether it routes
	// the finish, never whether it is asked): the packet,
	// the child's RESULT.md as text and the finish's reason line in; the decision's card line
	// (decide.Decided) and the decision as one JSON record line out, both carried by the
	// finish. It is long (a backend's answer), so it runs in the end's long work, beside the
	// push, never in the pass. nil asks none.
	Attempt func(p Packet, result, reason string) (decided string, decision []byte, err error)
	// ResolveStep resolves a step line's commit (7 to 40 hex) on the card's branch
	// to one full sha (docs/SPEC-SPRINT.md, the verdict per step). nil resolves in
	// the clone StepClone names, or, when that is nil too, in the launch checkout
	// the member verb's --slots or --root names. A member with neither accepts a
	// 40-hex sha as itself and refuses a shorter prefix as unknown.
	ResolveStep func(branch, prefix string) (sha string, err error)
	// StepClone is the checkout whose branch holds the card's step commits.
	// nil discovers it from the process arguments (the member verb).
	StepClone func(p Packet) string
	// ScriptVerify makes this reader a script reader (docs/SPEC-SPRINT.md, the script read):
	// a read of a script card (CLASS: script) is first asked of it, with the card's program
	// and deadline; ok is an ok read, whose finding is the one line why, counted as all the
	// reads the card needs. Not ok is no verdict: the read goes on to a model child as any
	// read does. nil asks none.
	ScriptVerify func(p Packet, class cardhdr.Class) (ok bool, why string)
}

Config is one member's or reader's standing.

type Ender

type Ender interface {
	Ended(p Packet, failed bool)
}

Ender is a Runner told when the member is done with a launch whose child ended: reported, returned or reaped, so nothing reads its working tree again. failed is whether it ended in a way a person may want to inspect (a failed finish, a read returned with no verdict); the runner removes or keeps what the launch staged (docs/SPEC-SWARM.md, `member`).

type Epocher

type Epocher interface {
	Epoch(epoch uint64)
}

Epocher is a Runner told the sprint's epoch each pass, as the queue answered it: its cleaner, apart from the pass, removes what launches of epochs long cleared left behind (docs/SPEC-SWARM.md, `member`). Epoch only records the number; it never waits.

type Finish

type Finish string

Finish is how a work launch ended, as the member judges it (tla/CardContract.tla).

const (
	FinishOK     Finish = "ok"     // reported: the result's head, pushed
	FinishFailed Finish = "failed" // reported --failed, with the reason
	FinishReaped Finish = "reaped" // never reported: the claim moved, or the card left the queue
)

func Judge

func Judge(r Result, pu Push) (fin Finish, why string)

Judge is a work card's finish from its result and its push, in one place (docs/SPEC-CARD-CONTRACT.md section 4; tla/CardContract.tla, Judge): ok only when the result has the shape, its verdict is ok, and the member pushed a commit the child made; otherwise failed, with the reason. Every work card ends with a commit: a child with nothing to do says `verdict: nothing`, and that is a failed finish, nothing to do, for the coordinator to judge. A run the provider failed that left no result, its push not refused, is failed with the kind `provider failure` and the provider's reason, and only that one: the sprint deals that card again and never judges it; a refused push or a result with the shape is failed work whatever the run's end (tla/CardContract.tla, JudgeOf and ProviderFailure). A launch refused at staging ran no child: failed with the kind `staging refused` and the stage's reason, the member's failure and never the card's (StageRefused).

type Member

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

Member is the loop's state: the children running, by card id.

func New

func New(cfg Config, s Sprint, r Runner, pu Pusher, out io.Writer) *Member

New is a member with nothing running. A reader pushes nothing, and its pusher may be nil; a work member's pusher pushes every work card's commit.

func (*Member) Beat

func (m *Member) Beat() error

Beat is one beat of this member's presence, apart from the work pass. A member's is `fleet beat <member>`, naming the highest one-second load sample since the last beat written, so the ten-second highest nova-sprint keeps over its beats (docs/SPEC-SPRINT.md, the fleet) is the highest of the last ten seconds; with no sample it names none and nova-sprint fleet beat measures the machine itself. A reader's is its queue, the verb that is a reader's beat (docs/SPEC-SPRINT.md, the readers), its answer not read. A beat that fails is the error: the next goes at the next interval.

func (*Member) BeatLoop

func (m *Member) BeatLoop(ctx context.Context, every <-chan time.Time, out io.Writer)

BeatLoop beats at every tick of every until ctx ends, while the work pass is going on: once it has gone BeatStall without advancing, the beat stops, said once, and starts again, said once, when the pass goes on. A beat that fails is said and the next is sent at the next tick.

func (*Member) Drain

func (m *Member) Drain()

Drain stops the member taking new cards: from the next tick it beats, reads its queue and reports every child as it ends, and starts nothing (not a taken card, not a recovered one). A member whose binary was replaced drains, and stops when Running is 0.

func (*Member) LastPass

func (m *Member) LastPass() PassTimes

LastPass is where the last pass's time went.

func (*Member) LongestDeadline

func (m *Member) LongestDeadline(override time.Duration) time.Duration

LongestDeadline is the longest deadline of the cards the member runs: each packet's route deadline, or override (the member's own --deadline) for one that names none, and override whenever it is longer (a reader given --deadline runs every read to it).

func (*Member) OwedStopReturns

func (m *Member) OwedStopReturns() int

OwedStopReturns is how many of this member's launches the stop cancelled whose card is not yet handed back: the beat carries it (fleet beat --stop-returns), and start waits on zero. A card the queue holds working under this row with no child of ours is owed too, and returned at once (machineStop), so it is never counted here. The beat calls this on its own goroutine, so the count is owedStopReturns and not a range of m.running.

func (*Member) Running

func (m *Member) Running() int

Running is how many lanes the member holds: one for every launch from its start until its card is reported (a spent launch holds none). A child that has exited holds its lane until the report, so the cards a member has working never pass its width; the sprint's take holds the same bound (internal/sprint, takeOne).

func (*Member) Stalled

func (m *Member) Stalled() time.Duration

Stalled is how long the work pass has gone without advancing, when that is past BeatStall; 0 while it is going on.

func (*Member) Tick

func (m *Member) Tick(now time.Time) (acted int, err error)

Tick is one pass of the loop: collect and push what ended, read the queue, report every child that ended, recover working cards, and take up to the width. When the queue read fails or times out, local completed children are still collected, pushed, reported, and cleaned up so an injected failing queue cannot starve an already-finished child, while new takes are suppressed (docs/SPEC-SWARM.md, member; docs/SPEC-SPRINT.md, the fleet).

func (*Member) WaitLong

func (m *Member) WaitLong()

WaitLong waits for the long work in flight to end: a member run for a bounded number of passes does not leave a start half made or a push cut off when its process exits.

func (*Member) Wake

func (m *Member) Wake() <-chan struct{}

Wake is the word that the next pass is due before the loop's interval: a push ended, or a child exited (a Background member). It holds at most one word.

type Packet

type Packet struct {
	Card       string   `json:"card"`
	Kind       string   `json:"kind"` // work or read
	As         string   `json:"as"`
	Primary    string   `json:"primary"`
	Stream     string   `json:"stream"`
	Attempt    int      `json:"attempt"`
	Gen        int      `json:"gen,omitempty"`
	Epoch      uint64   `json:"epoch"`
	Brief      string   `json:"brief,omitempty"`
	Rules      string   `json:"rules,omitempty"` // the held rules file the card names, "" when it carries its own (sprint.Packet)
	Fix        string   `json:"fix,omitempty"`
	Finding    string   `json:"finding,omitempty"` // a rework's: the readers' words that found the attempt before broken
	Why        string   `json:"why,omitempty"`     // a rework's: how the attempt before ended
	Notes      []string `json:"notes"`
	Branch     string   `json:"branch,omitempty"`
	Base       string   `json:"base,omitempty"`
	BaseHead   string   `json:"base_head,omitempty"`
	BaseFrom   int      `json:"base_attempt,omitempty"` // the attempt BaseHead is the head of
	Worker     string   `json:"worker,omitempty"`
	Head       string   `json:"head,omitempty"`
	WorkBranch string   `json:"work_branch,omitempty"`
	WorkBase   string   `json:"work_base,omitempty"`
	Report     string   `json:"report,omitempty"`
	// A work card's route, as the deal drew it (docs/SPEC-SPRINT.md, the deal's
	// route): the model the child runs on, its budget and deadline (seconds);
	// empty when the store has no route, and the member's own run.
	Route    string `json:"route,omitempty"`
	Model    string `json:"model,omitempty"`
	Tokens   string `json:"tokens,omitempty"`
	USD      string `json:"usd,omitempty"`     // the dollar budget per card, a decimal; "" for none (#5094)
	Harness  string `json:"harness,omitempty"` // the harness the route names (pkg/harness); "" is the member's --harness
	Deadline int    `json:"deadline,omitempty"`
	// RateRPM and RateConcurrent are the route's global limits when the coordinator set
	// them (nova-sprint routes limit): the runner's provider proxy then takes the budget from
	// the sprint's server before every model request; 0 is unlimited and nothing changes.
	RateRPM        int `json:"rate_rpm,omitempty"`
	RateConcurrent int `json:"rate_concurrent,omitempty"`
	// Tier is the tier the route was drawn from when the sprint decided it (a read's
	// read tier, a rework's --tier); empty when the brief's line 1 names it.
	Tier string `json:"tier,omitempty"`
	// A decide read's bars on p(defect), as the ask wrote them on the read card
	// (docs/SPEC-SPRINT.md section 6, the decide read); empty for a strings read.
	DecideBounce string `json:"decide_bounce,omitempty"`
	DecideReview string `json:"decide_review,omitempty"`
	// A work card's gate decision bars, as the deal wrote them on the work card
	// (docs/SPEC-SPRINT.md section 5, the gate verdict); empty for none.
	DecideGateFlaky       string `json:"decide_gate_flaky,omitempty"`
	DecideGatePreexisting string `json:"decide_gate_preexisting,omitempty"`
}

Packet is what a card hands the member, as `nova-sprint queue --json` and `take --json` print it.

func Carried

func Carried(p Packet) Packet

Carried is a work packet as the member stages it: one with no pushed head of its own (sprint.BaseOf found none) whose brief carries a CARRY: line starts from that head, as a rework starts from its last pushed head (docs/SPEC-CARD-CONTRACT.md, "Where a rework starts"), so a card brief --widen widens keeps the held attempt's work; any other as it is.

type PassTimes

type PassTimes struct {
	Queue, Push, Report, Fill time.Duration
}

PassTimes is where one pass's time went: reading the queue, pushing the ended children's commits, reporting them, and filling the lanes (the take and the starts, their stagger with them). A pass is the member's one line of control, so a child that exits while it runs waits for what is left of it: these four say what it waits on.

type Printer

type Printer interface {
	Printed() time.Time
}

Printer is a Child that says when it last printed output (zero: never). The member stamps progress on its card while it prints (stampProgress); a child that is not a Printer is never stamped, and the late rule never returns its card for want of a stamp.

type Push

type Push struct {
	Sha     string // pushed: the full sha origin's branch now holds
	None    string // not pushed: why (the child committed nothing); the finish is failed, no commit
	Refused string // the push failed: git's own line; the finish is a failure
	PR      string // the pull request the member opened for the pushed head, "" when none
	PRNote  string // why a pull request the result asked for was not opened, "" when none was asked or it opened
}

Push is how a push ended: exactly one of Sha, None and Refused is set. A push that landed may also have opened the card's pull request (PR) or said why not (PRNote).

type Pusher

type Pusher interface {
	Push(p Packet, r Result) Push
}

Pusher puts a work card's commit on origin, outside the wall: the commit the child's result names (Result.Head) pushed to the branch the packet names (Packet.Branch), never forced. It is asked once per ended launch.

type Result

type Result struct {
	Ran     bool
	OK      bool
	Shaped  bool
	Verdict string // a work card's "ok" or "not-done"; a read's "ok", "broken", or "" when the reader gave none
	Head    string
	Report  string
	Title   string // the pull request the child asked for (gh pr create), "" when none
	Body    string
	// End is how a run that did not finish ended, as the child's harness said it:
	// EndProvider, EndBudget, EndDeadline, or "" (Judge puts it first in a failed
	// finish's reason). Usage is what it spent, one line (its budget and wall),
	// reported with the finish onto the attempt's record.
	End   string
	Usage string
	// Provider is why End is EndProvider, as native read it from the harness's own log
	// or transcript: the cause, `provider: class=<c> status=<n|-> msg=<words>`
	// (docs/SPEC-CARD-CONTRACT.md section 4; tla/CardContract.tla, ProviderFailure).
	// "" when the end was a launch the provider never accepted, which names no reason.
	Provider string
	// Staging is why End is EndStaging: the reason of native's STAGE FAIL line, the launch
	// refused before any child ran (tla/CardContract.tla, StageRefused).
	Staging string
	// Budget is which budget ended a run whose End is EndBudget, and at what count, as
	// native's NATIVE BUDGET line says it ("tokens 509,940 of 400,000, $0.03"); Judge
	// says it after the end (nova-tools #5094). "" when native named none.
	Budget string
	// Step is why a tree card failed at its first work step: `step <n> <verdict>: <words>`
	// (treeFinish; docs/SPEC-SPRINT.md, a card is a tree of steps). Judge names it as the
	// failed finish's reason; "" for every other card.
	Step string
	// Gate is where native's gate decision sent a not-done child's red gate, its NATIVE GATE
	// line's route (docs/SPEC-SPRINT.md section 5, the gate verdict): GatePreExisting, which
	// Judge names as the failed finish's reason with GateTests; GateGreen (its flaky failures
	// passed their rerun), which the reader of the result takes as the verdict ok; "" for none.
	Gate      string
	GateTests string
	// Carry is where a rework was staged, as native's STAGE CARRY line says it
	// (cardcontract.Carry.Words: the staged commit, the tip of its base branch, and whether
	// the work before it carried); the finish's report carries it, so the card's timeline
	// says it. "" for a first attempt and a read.
	Carry string
}

Result is how a child ended. Ran is whether the child ran to its end (its harness answered); OK is its verdict: a work card's, that the work is done, a read's, the reader's `verdict: ok` in RESULT.md. A read whose child did not run or gave no verdict has no finding to report: the read is left as it is for the sprint's lateness rule, never filed as broken against the work. Shaped is whether RESULT.md has the contract's shape (docs/SPEC-CARD-CONTRACT.md section 3); a work card's finish is ok only with it (Judge).

type Runner

type Runner interface {
	// Start runs the packet as one child and returns a handle for it.
	Start(p Packet) (Child, error)
}

Runner starts a card as a child and reports how it ended.

type ScriptVerifier

type ScriptVerifier struct {
	Mirror string
	Temp   string
	Git    string
	Run    func(ctx context.Context, dir string, argv []string) error
}

ScriptVerifier is a script reader's means (docs/SPEC-SPRINT.md, the script read). Mirror is a repository that holds the attempt's start commit and the head; Temp is a directory the checkout is made in (removed after); Run runs the program's argv in a directory under the wall, with the card's deadline in ctx, and is the one place a program runs: the caller wires the wall, a test a fake. Git is the git program, "" for git on PATH.

func (ScriptVerifier) Verify

func (v ScriptVerifier) Verify(p Packet, class cardhdr.Class) (ok bool, why string)

Verify is Config.ScriptVerify: it checks out the attempt's start commit (the packet's base head, else the merge base of the head and the work's base branch), runs the card's program from the repository root under the card's deadline, and compares the resulting diff with the head's diff byte for byte. Identical is ok, with the one line that says what was compared; a difference, an empty diff, a missing commit or a failed run is not ok, with the reason. The head is never taken on the worker's word.

type Sprint

type Sprint interface {
	Run(args ...string) (code int, out []byte)
}

Sprint runs one sprint verb and returns its exit code and stdout.

type Stopper

type Stopper interface {
	Stop() (pid int)
}

Stopper is a Child the member can end for the machine's stop (docs/SPEC-SPRINT.md section 14, stop cancels jobs): Stop signals the child's process to end, keeping its working tree and its log, and returns the pid it signalled (0 when none is known). The runner escalates to a kill after its own grace; the member reads Done as for any end. A Child that is no Stopper is left to end by itself and is stop-returned when it has.

type Waiter

type Waiter interface {
	Wait() <-chan struct{}
}

Waiter is a child that says when it has ended: a Background member's loop is woken then (Wake), so the child's push begins at once and not at the loop's next interval.

Jump to

Keyboard shortcuts

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