Documentation
¶
Index ¶
- Constants
- Variables
- func AIPath(root, name string) string
- func AdapterRemedy(harness string) string
- func AgeString(d time.Duration) string
- func AgentAPI(out string) (json.RawMessage, error)
- func Ago(d time.Duration) string
- func AllowDirs(dir string, paths []string) (bool, error)
- func AntigravityRunner(home string) string
- func BenchRule(friend, card string) string
- func BriefFix(brief string) string
- func BusLogEntries(ctx context.Context, st bus.Store, friend string, since time.Time) (realCount int, lastReal time.Time, err error)
- func CappedWords(limit time.Duration, tier string, overrun time.Duration) string
- func CardText(job LaneJob, n, width int, sendLine string) string
- func CheckFolderRoute(harness, session, adapter, deliveryDir string) error
- func ClaimLane(dir, job, who string, now time.Time) (holder string, err error)
- func ClaudeAsyncBashHook(input []byte) []byte
- func ClaudeInstallLine(harness, friend, wake string) string
- func ClaudeProofArgs() []string
- func ClaudeProofWhy(ctx context.Context, run Exec, dir, configDir, program string) string
- func ClaudeWaitLine(friend, wake string) string
- func ClaudeWakePath(stateDir, friend string) string
- func ClearLaneFault(stateDir string) (bool, error)
- func ClearPause(stateDir string) (bool, error)
- func CodexAddRoot(text, root string) (string, error)
- func CodexRoots(text string) (roots []string, found bool, err error)
- func ContextFull(reason string) bool
- func CopyExecutable(src, dst string) error
- func CostLine(t LaneTokens, rp RoutePrice, model string) (report, tokens, cost string)
- func CostOf(t cardcost.Tokens, rp RoutePrice, model string) string
- func DSHArgs(session string) []string
- func DSHNoPresetRemedy(dir string) string
- func DSHSessionKey(dir string) string
- func DaemonStateDir(home, dir, friend string, mkdir func(string) error) (state, why string)
- func DeadLaneReport(friend, job, end string) string
- func DefaultDenySelf(home, seat string) []string
- func DefaultReadWork(dir string) (inboxCount, outboxCount int, newestName string, newestAt time.Time, err error)
- func DefaultStateDir(home, friend string) string
- func EndReport(friend string, lane int, c Card, end LaneEnd, head, branch string) string
- func ExitTimeout(plist string) time.Duration
- func FaultDownText(friend string, p Pronouns, reason string, until time.Time) (subject, body string)
- func FaultWords(fault, first string) string
- func FindStateDir(home, dir, friend string) string
- func FinishArgv(friend string, c Card, report, head, branch string) []string
- func FinishNote(friend, job, verdictLine, cost string, wall time.Duration) (subject, body string)
- func FixAddressed(report, fix string) (missing []string, ok bool)
- func FixKeyWords(fix string) []string
- func FriendCardsArgv(friend string) []string
- func FundsJudgmentText(friend string, p Pronouns, reason string) (subject, body string)
- func GeminiArgs(session, text string) []string
- func GitHubURL(repo string) string
- func GoRefusal(name string) string
- func GoShimName(argv0 string) (string, bool)
- func GoShims(dir, self string) error
- func GrokInstallLine(harness, session string) string
- func GrokMonitorLine(wake string) string
- func GrokWakePath(home, stateDir, friend string) string
- func HarnessFirstError(out string) string
- func HarnessSpent(d Deliverer) float64
- func Head(s string, n int) string
- func HeldVia(friend string, ask func(ctx context.Context, argv []string) (string, error), ...) func(context.Context) (Row, error)
- func HostPrompt(harness, override string) (re *regexp.Regexp, src string, err error)
- func InLane(ctx context.Context) bool
- func Install(ctx context.Context, a Agent, uid int, run Launchctl, ...) (path string, ran []string, err error)
- func InstalledBinary(home string) string
- func IsRealMessage(subject string) bool
- func JobDir(dir, job string) string
- func JobText(dir string, p Packet, sha string) string
- func Known(harness string) bool
- func LaneCap(tier string, caps map[string]time.Duration) time.Duration
- func LaneContext(ctx context.Context) context.Context
- func LaneDirOf(ctx context.Context, def string) string
- func LaneEnvironmentFault(wall time.Duration, out, report, result, laneDir string) (string, bool)
- func LaneFaultParts(report string) (n int, line string, ok bool)
- func LaneFaultReport(n int, line string) string
- func LaneFaultText(friend string, p Pronouns, fault string) (subject, body string)
- func LaneFilesystemError(out, laneDir string) string
- func LaneMarkEnded(who string) string
- func LaneMarkRunning(who string, at time.Time) string
- func LaneSeed(friend string, n, width int, agents, memory string) string
- func LaneTakeArgv(member string, n int) []string
- func LaneTmpDir(dir string) string
- func LanguageServer(ps, username string) (pid, token string, err error)
- func LastLines(s string, n int) string
- func LastResult(stateDir string) (at time.Time, exit int, err error)
- func LimitAlikeText(friend string, p Pronouns, line string) (subject, body string)
- func LimitDownText(friend string, p Pronouns, until time.Time, reason string) (subject, body string)
- func LimitUnreadText(friend string, p Pronouns, rest time.Duration, text string) (subject, body string)
- func LimitUpText(friend string, p Pronouns) (subject, body string)
- func ListenPorts(lsof string) []string
- func Load1Of(out string) (float64, bool)
- func LogPath(stateDir string) string
- func NewestConversation(rows string, dirs ...string) (string, error)
- func NewestDSHSession(sessions, dir string) (string, error)
- func NewestWrite(fsys fs.FS, roots []string, now func() time.Time, lim ActivityLimits) time.Time
- func NotHers(card, job, friend string, running func() map[string]string) string
- func OutboxFinishArgv(friend string, c Card, verdict, head, branch, report string) []string
- func PacingJudgmentText(friend string, paced, width int, pacing float64, use string) (subject, body string)
- func PacingOf(setting float64) float64
- func PacingText(pacing float64) string
- func ParseJob(job string) (id string, epoch, gen int, ok bool)
- func ParseLaneCaps(answer string) (caps map[string]time.Duration, ok bool)
- func ParseMachine(answer string) (state string, ok bool)
- func ParsePong(text string) (nonce string, queue, working, width int, ok bool)
- func ParseProfile(answer string) (profile string, ok bool)
- func ParseReadSlots(answer string) (n int, ok bool)
- func ParseRow(answer string) (mode string, width int, ok bool)
- func ParseShown(data []byte) (map[string]ShownEntry, error)
- func PauseBeat(marker, model string, now time.Time) (until time.Time, reason string)
- func PermissionRejection(out string) string
- func PlanBinary(binary, home string) (path string, copy bool, err error)
- func PlatformPermitted(context.Context, Exec) (bool, error)
- func PlistArgs(plist string) []string
- func PlistDriftLine(plist string, running []string) string
- func PongLine(nonce string, queue, working, width int) string
- func PongRequest(text string) (kind, nonce string, only bool)
- func ProgressArgv(friend string, cards []Card) [][]string
- func PromptPattern(s string) *regexp.Regexp
- func PronounList() string
- func ProviderLimit(session, out string) error
- func ProviderRefusal(out string) (reason string, ok bool)
- func PublishCost(outbox string, t LaneTokens, rp RoutePrice, model string) error
- func PushedHead(dir string, c Card) (head, branch string)
- func Pushing() []string
- func QuoteWhy(s string) string
- func RateJudgmentText(friend string, p Pronouns, cap, width int, reason string) (subject, body string)
- func Read(readJSON []byte, id string) bool
- func ReadBeginArgv(friend string, r AskedRead) []string
- func ReadLaneFault(stateDir string) string
- func ReadPause(stateDir string) string
- func ReadPrompt(friend, jobDir string) string
- func ReadQueue(dir string) (queue, working int, err error)
- func ReadQueueArgv(friend string) []string
- func ReadReturnArgv(friend string, r AskedRead, reason, usage string) []string
- func ReadText(friend, jobDir string, r AskedRead) string
- func ReadVerdict(result string) (verdict, finding string)
- func ReadVerdictArgv(friend string, r AskedRead, verdict, finding, usage string) []string
- func ReaderOf(friend string) string
- func RealExec(ctx context.Context, dir, name string, args []string, stdin string) (string, int, error)
- func Record(stateDir, line string) error
- func ReportPara(report string) string
- func ReportVerdict(report string) (verdict, head string)
- func RescueStray(job LaneJob) []string
- func ResentLine(d AntigravityDelivery) string
- func ReworkedBrief(brief string) string
- func RowConfigDir(answer string) string
- func RunWall(args, env []string, stdin io.Reader, stdout, stderr io.Writer) int
- func RunnerEnded(log, job string) (end string, dead bool)
- func RunnerLog(dir string) string
- func RunsCards(harness string) bool
- func SessionCheckText(nonce, pong, to string) string
- func SessionCost(export string) (float64, error)
- func SessionMissing(firstError string) bool
- func SnapEpoch(dir string, row Row, keep map[string]bool, asked, now time.Time, ...) (int, error)
- func SpendCapJudgmentText(friend string, p Pronouns, provider string, spent, cap float64) (subject, body string)
- func StageJudgmentText(friend string, n *NotStageable) (subject, body string)
- func Staged(dir, job string) bool
- func StateDirIn(dir string) string
- func StopReturnArgv(row, card string, gen int, epoch string, lane int) []string
- func TakeArgv(friend, card, reason string) []string
- func TakeBackNote(friend, card, job, why string) (subject, body string)
- func TmuxFor(d Deliverer, name, stateDir string) error
- func TmuxSession(name string) string
- func TokenCapOf(answer string) (int64, bool)
- func TokenCapReport(friend string, c int64, tokens int64, turns int, last string) string
- func TokensSQL(session string) (string, error)
- func TypeScript(bundle, text string) string
- func TypedLine(text string) string
- func UnaddressedLand(by, report, brief string) (held string)
- func UnaddressedText(by, fix string, missing []string) string
- func Undriven(d Deliverer, harness string) (why, remedy string, ok bool)
- func Uninstall(ctx context.Context, a Agent, uid int, run Launchctl, ...) (ran []string, err error)
- func WaitReleased(ctx context.Context, run Launchctl, target string, timeout, poll time.Duration, ...) (time.Duration, error)
- func WakeLine(text string) string
- func WakeOf(active, listing, dir, wake string) (string, error)
- func WatchPath(stateDir string) string
- func WithCost(report, line string) string
- func WithLaneDir(ctx context.Context, dir string) context.Context
- func WithOutputSeen(ctx context.Context, seen func()) context.Context
- func WithOutputTail(ctx context.Context, tail func([]byte)) context.Context
- func WorkspaceConversations(rows string, dirs ...string) ([]string, error)
- func WriteHost(stateDir string, h Hosted) error
- func WriteLaneFault(stateDir, report string) error
- func WritePause(stateDir, message string, at time.Time) error
- func WriteStatus(stateDir string, s Status) error
- func WriteWatch(stateDir string, w Watch) error
- type ActivityLimits
- type Agent
- type AgentAPIRefusal
- type Antigravity
- type AntigravityDelivery
- type AntigravityLedger
- type AskedRead
- type BeatWords
- type BusFacts
- type Card
- type CardRunner
- type CardUsage
- type CheckReport
- type CheckResult
- type CheckSeams
- type CheckSummary
- type Claude
- type ClaudeWake
- type Conformance
- type CopyFile
- type Courier
- type DSH
- type Daemon
- type DaemonFacts
- type Deferred
- type Deliverer
- type Entry
- type Evidence
- type Exec
- type FaultWatch
- type Folder
- type FriendCheck
- type GUIWindow
- type Gemini
- type Grok
- type HarnessFacts
- type HarnessSettings
- type HeldAnswer
- type HeldCard
- type HookRecord
- type HostRefused
- type HostResult
- type HostSpec
- type Hosted
- type InboxCounts
- type LaneEnd
- type LaneFaultWatch
- type LaneGovernor
- func (g *LaneGovernor) Cap(width int) int
- func (g *LaneGovernor) Clean(now time.Time)
- func (g *LaneGovernor) Held() string
- func (g *LaneGovernor) Hold(reason string) bool
- func (g *LaneGovernor) PauseUntil(until time.Time, reason string, now ...time.Time) string
- func (g *LaneGovernor) Paused(now time.Time) bool
- func (g *LaneGovernor) RateLimit(now, started time.Time, width int, reason string) (line string, judge bool)
- func (g *LaneGovernor) Release()
- func (g *LaneGovernor) Step(now time.Time, width int) []string
- type LaneHarness
- type LaneHold
- type LaneJob
- type LaneMark
- type LaneRules
- func (r LaneRules) Judge(id, stream, tier string) (LaneVerdict, string)
- func (r LaneRules) LaneWidthUnderLoad(width int, load float64) (n int, held bool)
- func (r LaneRules) Over(row LaneRules) LaneRules
- func (r LaneRules) OverTokenCap(tokens int64) bool
- func (r LaneRules) ProviderStop(err error) (message string, stop bool)
- type LaneState
- type LaneTokens
- type LaneTurn
- type LaneVerdict
- type Launchctl
- type Limit
- type LimitHit
- type Limits
- func (l *Limits) Beat(beat func(ctx context.Context) error) func(ctx context.Context) error
- func (l *Limits) BeatOrDown(beat func(ctx context.Context) error, ...) func(ctx context.Context) error
- func (l *Limits) Gate(d Deliverer) Deliverer
- func (l *Limits) Kind() string
- func (l *Limits) Limited() (until time.Time, reason string, limited bool)
- func (l *Limits) Refuse(kind, reason string, until time.Time)
- func (l *Limits) Watch(run Exec) Exec
- func (l *Limits) WindowUse() string
- type LogFacts
- type NoReport
- type NotServed
- type NotStageable
- type Notices
- type OSFS
- type OpenCode
- func (o *OpenCode) CheckRun(ctx context.Context) error
- func (o *OpenCode) Deliver(ctx context.Context, text string) (int, error)
- func (o *OpenCode) DeliverFresh(ctx context.Context, text string) (int, error)
- func (o *OpenCode) DeliverTo(ctx context.Context, id, text string) (LaneTurn, error)
- func (o *OpenCode) OpenSession(ctx context.Context, seed string) (string, error)
- func (o *OpenCode) RunRead(ctx context.Context, model, prompt string) (LaneTurn, error)
- type OpenCodePriced
- type OutOfFunds
- type Pacer
- type Packet
- type Pronouns
- type PronounsRef
- type ProviderRefused
- type Queue
- type RateLimited
- type ReadHarness
- type ReadPacket
- type Refused
- type RoutePrice
- type Row
- type SessionRefused
- type Setting
- type SettingsFS
- type ShownEntry
- type SpendCap
- type Spender
- type Stager
- type Started
- type Status
- type StopReturn
- type Stub
- type Task
- type Tmux
- type TokenCapped
- type Tokens
- type Unparseable
- type Usage
- type UsageLimited
- type Verdict
- type VerdictFacts
- type Wall
- type Watch
- type WindowRefused
- type WindowUse
- type WorkFacts
Constants ¶
const ( AntigravityPoll = 500 * time.Millisecond AntigravityLandBudget = 30 * time.Second )
AntigravityPoll is how often the mailbox is read while waiting for the sent message to appear in it, and AntigravityLandBudget how long: past it the message agentapi took is in the ledger as delivered, its id read off the mailbox when it lands (Follow).
const ( PongCheck = "session check" // the presence's nonce (SessionCheckText) PongWake = "wake" // the coordinator's challenge nonce (a wake turn, an idle wake, a turn's head) )
The kinds of pong request (PongRequest): each its own series of nonces.
const ( TmuxPoll = 500 * time.Millisecond TmuxAcceptWithin = time.Minute )
Timing of a typed delivery: the pane is polled each TmuxPoll for up to TmuxAcceptWithin for the prompt line to go (the turn started).
const ( AntigravityFollowEvery = 10 * time.Second AntigravityReadBound = SessionBound AntigravityStopped = 3 AntigravitySwitchHold = 10 * time.Minute AntigravityKeptRead = 64 )
The ledger's rules. AntigravityReadBound is the check period: a delivery unread past it, with nothing read since, is a session down (Deliver refuses). A conversation that has left AntigravityStopped deliveries unread past it, and read nothing since the oldest, stopped reading; delivery moves to a conversation that read a delivery since, and never moves again within AntigravitySwitchHold. Follow looks every AntigravityFollowEvery. AntigravityKeptRead bounds the deliveries kept once read or sent again (the newest); one unread is never dropped.
const ( VerdictOK = "ok" VerdictBroken = "broken" VerdictDown = "down" VerdictUntrue = "untrue" )
Verdict constants for the friend health check.
const ( StageDeliver = "deliver" StageAct = "act" StageReply = "reply" )
The stages of the delivery check, in the order they are passed: the adapter took the text (deliver), the session ran the pong line it carries and the pong is on the bus (act; reply is the bus log not read).
const ( DefaultCheckWithin = SessionBound CheckPoll = time.Second )
DefaultCheckWithin is how long the check waits for the session's pong by default: the session check's own bound (SessionBound). CheckPoll is how often it reads the bus and the pong file meanwhile.
const ( RefusalRepeats = 3 RefusalDownFor = 15 * time.Minute )
RefusalRepeats is how many times in a row the server must refuse one verb before the daemon raises it (a down beat and one word to the coordinator), and RefusalDownFor how long her beat says down with it while the server stays refused (a server that answers again clears it at once: docs/SPEC-FRIEND.md, "A refused verb").
const ( SessionOK = "ok" SessionBroken = "broken" )
The session's state, as the status file says it.
const ( FromCards = "friend cards" FromView = "the worker view" )
The sources of a Row.
const ( FriendCardsVerb = "friend cards" FriendBeatVerb = "friend beat" )
The server verbs the daemon counts refusals of, one key per verb in Status.Refused (docs/SPEC-FRIEND.md, "A refused verb").
const ( ViewEvery = 15 * time.Second ServedEvery = time.Minute )
ViewEvery is how often the worker view is read while friend cards is refused: it runs on the server's line (serveView takes the tick's lock), so it is read about as often as friend sync's loop runs, never every loop. ServedEvery is how often friend cards is asked again.
const ( NoGoRoot = "/NO-GO-ON-THIS-MACHINE-run-it-on-a-bench-over-ssh" ShimDirName = "shims" )
The go refusal: no go command runs on the machine that runs the lanes (the owner's rule: it is not a build machine). A lane's PATH carries go and gofmt that refuse, and GOROOT points nowhere.
const ( FaultRepeats = 3 FaultWithin = 10 * time.Minute FaultDownFor = 15 * time.Minute )
The bound on a harness fault: the same fault FaultRepeats times within FaultWithin on one row marks the row down for FaultDownFor, once, with one judgment to the seat.
const ( ModeBatch = "batch" ModeOneShot = "one-shot" )
The delivery modes (pkg/config FriendModes, the friend row's mode).
const ( InstantFail = 5 * time.Second InstantFailRepeats = 2 )
InstantFail is how fast a card run that ends with no REPORT.md and no RESULT.md marks a broken harness rather than the card's own failed attempt: on 2026-10-11 an unsigned config directory ended every claude -p run terminal_reason api_error in about a second. InstantFailRepeats such runs in a row stop the lane's taking and re-prove the harness before any take, instead of finishing a third card FAILED (docs/SPEC-FRIEND.md, "A lane proves its harness").
const ( ReleasePoll = 250 * time.Millisecond DefaultExitTimeout = 20 * time.Second )
ReleasePoll is how often Install asks launchd, after the bootout, whether it still holds the old service; DefaultExitTimeout is how long it asks, the launchd default for a plist with no ExitTimeOut (the time launchd gives a daemon to exit before it kills it).
const ( KindLimit = "limit" KindCredits = "credits" )
The kinds of a limit: the harness's usage window is spent, or the balance that pays for it is empty.
const ( LaneMarkEvery = 30 * time.Second LaneMarkStale = 5 * LaneMarkEvery )
LaneMarkStale is how long a running mark stands unrefreshed: a lane refreshes its mark every LaneMarkEvery while its card runs, so one older than this is a lane gone with its daemon, and a new lane may claim the card.
const ( WindowFiveHour = "five_hour" WindowSevenDay = "seven_day" )
The windows a Claude subscription reports, in its own spelling.
const ( SessionBound = 5 * time.Minute SessionCheckPrefix = "SESSION CHECK " LogBatch = 1000 // log entries read per step; the rest the next )
Whether a friend is there is the nova-hook record's alone: nova-hook serve challenges every hooked name once a minute, only the model answers with nova-hook prove, and two misses unhook it (docs/SPEC-HOOK.md). What is left here is the delivery check's (nova-friend check --harness, Conformance): a SESSION CHECK carrying a nonce goes in through the harness, and the session's pong with that nonce must reach the bus within SessionBound.
const ( PresenceUp = "up" PresenceDown = "down" )
The presence, as check reports it from the nova-hook record (HookRecord.Up).
const ( RateBackoffFirst = 30 * time.Second // the first pause after a rate limit RateBackoffMax = 10 * time.Minute // the pause doubles up to this RateRaiseEvery = 10 * time.Minute // a clean stretch this long raises the cap one lane RateJudgeWithin = time.Hour // RateJudgeAfter lowerings within this are one judgment RateJudgeAfter = 3 )
The lane governor's numbers.
const ( OneThingLeft = "THE ONE THING LEFT: " ReaderFoundLabel = "The reader found: " )
The labels of a reworked brief's first lines, and of the server's lines it is made from.
const ( HeldByDaemon = "the daemon" HeldByFriendSync = "friend sync" )
The holders of an unaddressed LAND, as UnaddressedText names them.
const ( KindDir = "directory" KindFile = "file" KindMissing = "missing" KindSymlink = "symlink" // shown as "symlink to <target>" )
The kinds a path is, as a setting shows it.
const ( JobsDir = "jobs" MirrorsDir = "mirrors" JobFile = "JOB.md" )
The directories under her working directory that staging writes.
const ( StageRetryEvery = time.Minute MirrorFreshFor = 10 * time.Second MirrorCloneBudget = 30 * time.Minute )
StageRetryEvery is how long a job whose stage failed waits before it is staged again; a judgment stands, said once, until a stage of its repository or card succeeds. MirrorFreshFor is how long a fetched mirror serves stages without fetching again, so a burst of cards on one repository is one fetch. MirrorCloneBudget bounds a mirror's fetch: the first, of the whole repository, is the one slow step (every later one fetches only what is new).
const ( FinishedJobsKept = 8 PrunePerPass = 4 )
FinishedJobsKept is how many finished jobs' worktrees the daemon's cleanup keeps, the newest staged; the rest are pruned (Stager.Prune), at most PrunePerPass a cleanup, so the loop that runs it is held a few seconds at most.
const ( StatusFile = "status.json" LogFile = "deliver.log" WatchFile = "watch.json" QueueFile = "inbox/QUEUE.json" )
The friend's files, one writer each. The state files live in the state directory (DefaultStateDir under the home directory, or --state-dir), never on the friend's volume: a background process on this platform may not touch a removable volume without the person's permission (measured 2026-10-04, "operation not permitted" on the mkdir). The daemon writes Status and the log. The queue file is the coordinator's and the session's, under the working directory (SPEC-FRIEND.md, the files).
const ( StatusEvery = 5 * time.Second DaemonStale = 30 * time.Second )
DaemonStale is how old the status file may be while the daemon counts as up: it rewrites the file at least every StatusEvery.
const AccessibilityCheckScript = "use framework \"ApplicationServices\"\nreturn (current application's AXIsProcessTrusted() as boolean) as text\n"
AccessibilityCheckScript asks whether this process is trusted. It calls AXIsProcessTrusted and never AXIsProcessTrustedWithOptions, so it cannot prompt.
const AccessibilityRemedy = "grant Accessibility to this binary in System Settings, Privacy and Security, Accessibility; nova-friend does not ask"
AccessibilityRemedy is what a person does when the window step cannot type. The permission is granted to this binary. The tool never asks for it.
const ActivityEvery = 10 * time.Second
ActivityEvery is how often the daemon walks: the beat goes every BeatEvery and carries the last walk's answer in between.
const AntigravityData = ".gemini/antigravity"
AntigravityData is the harness's app data directory, under the home.
const AntigravityLedgerFile = "antigravity-ledger.json"
AntigravityLedgerFile is the ledger's file in the daemon's state directory.
const AntigravityOpen = "" /* 143-byte string literal not displayed */
AntigravityOpen is what a friend whose Antigravity refuses does.
const AntigravityTitle = "nova-friend"
AntigravityTitle heads every message nova-friend sends.
const BeatEvery = time.Second
BeatEvery is the cadence of the daemon's sprint metadata beat and lane loop. It carries lane configuration and activity, never session liveness.
const BootstrapTries = 5
BootstrapTries is how many times a bootstrap is sent while launchd is still tearing the old agent down (it answers EIO, "Input/output error", for a second or so after the bootout, measured 2026-10-04).
const CapTailLines = 40
CapTailLines is how many of the lane's last output lines a capped card's report quotes.
const CardTurns = 2
CardTurns is how many turns a one-shot lane gives one card: a turn that ends without the card's RESULT.md hands the same card again once, then the card is reported to the coordinator and set aside.
CodexPushUnavailable is the refusal for implicit Codex delivery (SPEC-FRIEND.md, Codex). No flag or environment variable enables queue or exec-resume as push.
const CodexWritableRoots = "sandbox_workspace_write.writable_roots"
CodexWritableRoots is the setting in CODEX_HOME/config.toml that lets a workspace-write sandbox write the friend's directory: [sandbox_workspace_write] writable_roots. The friend's directory is written there by its real path; a symlink there took no writes for ten hours on 2026-10-05.
const DSHPreset = "standard"
DSHPreset is the agent preset a friend's DeepSeek Harness opens new sessions under. A session under "minimal" makes every headless turn exit 1 before any write (measured 2026-10-04 and 2026-10-05, docs/SPEC-FRIEND.md, the dsh row); the owner set the desktop profile's selected default to "standard" by hand on 2026-10-04, and install now writes it. A session keeps the preset it was opened under: one opened under minimal stays so.
const (
DSHPresetEntry = "agent-preset-registry"
)
The patch entry that holds it: the desktop profile's patch layer, DSH_HOME/profiles/desktop/cordis.patch.yml, a YAML list of loader patch entries; the preset registry's config keys default and selectedDefault.
const DSHProgram = "/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh"
DSHProgram is where the DeepSeek Harness desktop app ships its CLI on this platform; the app installs no link on PATH.
const DefaultBrokenAfter = 3
DefaultBrokenAfter is how many turns in a row the provider must refuse with the same reason before the session is broken (--broken-after).
const DefaultLimitWait = time.Hour
DefaultLimitWait is how long a harness that refused at its limit and named no reset is down before a wake is tried.
const DefaultLoadWidth = 3
DefaultLoadWidth is how many lanes run while the load is above the row's bound.
const DefaultPacing = 0.80
DefaultPacing is the fraction of each subscription window the sprint may spend when the row names no pacing.
const DefaultReadSlots = 2
DefaultReadSlots is how many reads a friend runs at once when her row says none.
const DefaultSilentStop = 20 * time.Minute
DefaultSilentStop is how long a turn may print nothing before the daemon stops it (--silent-stop): a turn that prints keeps running however long it takes (the finding of 2026-10-04: a fixed ten-minute cap killed a friend's real work mid-turn).
const DefaultSpendCapUSD = 20.0
DefaultSpendCapUSD is the spend cap in USD per day per provider when the config names none.
const DefaultTokenCap int64 = 6_000_000
DefaultTokenCap is a card's token cap where the friend row names none.
const FinishWait = 10 * time.Second
FinishWait bounds a lane's finish to the sprint server; one not answered is left to friend sync, which reads the REPORT.md the lane wrote.
const HarnessFaultEnvironment = "harness-fault: environment"
HarnessFaultEnvironment is the fault of a lane run the friend's environment broke, never the card's: it ended within InstantFail with no REPORT.md and no RESULT.md and its output names a filesystem error on a path outside its lane.
const HarnessFaultNoReport = "harness-fault: no report"
HarnessFaultNoReport is the fault of a lane run that exited 0 and left no REPORT.md or RESULT.md: the harness's, never the worker's failed attempt.
const HoldersBudget = 10 * time.Second
HoldersBudget bounds the current ownership view asked for an old report.
const HookProven = "proven"
The hook record's state a friend is up in (nova-tools hook.StateProven).
const HostFile = "host.json"
HostFile is the friend's host state in its state directory.
const InboxEvery = BeatEvery
InboxEvery is how often the daemon reconciles her inbox with her row: every loop.
const KillDelay = 5 * time.Second
KillDelay is how long a signalled group gets to end before SIGKILL.
const LaneFaultAlike = 2
LaneFaultAlike is how many identical provider refusals in a row mark the lane faulted: a guard's denial is terminal, never a retry each minute, and the second identical one is the judgment (docs/SPEC-FRIEND.md, the lanes).
const LaneFaultFile = "lane-fault"
LaneFaultFile is the lane's provider-refusal fault report in the state directory (lane-fault=<n> refusal="<first line>"), written by the daemon when a lane faults and removed when the fault is cleared; absent is no fault (docs/SPEC-FRIEND.md, the lanes).
const LaneIdleAsk = 15 * time.Second
LaneIdleAsk is how long a lane the server gave nothing waits before it asks again.
const LaneMarkFile = "LANE"
LaneMarkFile is a job's lane mark, under jobs/<job>/.
const LaneOpenRetry = time.Minute
LaneOpenRetry is how long a lane whose session could not be opened waits before it tries again.
const LaneTmpName = "tmp"
LaneTmpName is the temporary directory inside a lane's own job directory.
const LimitFile = "limit.json"
LimitFile is the friend's limit, in the state directory: the provider's limit the session is at and when it resets. The daemon is its one writer; no file is no limit.
const LimitTail = 2048
LimitTail is how much of the end of a command's output is read for a limit line: a harness says it last, and the body of a reply that only talks about limits is far from the tail.
const MachineStoppedWord = "STOPPED"
MachineStoppedWord is the machine's state word that cancels jobs.
const MaxFixKeyWords = 8
MaxFixKeyWords bounds the key words a report is grepped for: a long fix is checked by its first ones.
const NoticeLimit = 256
NoticeLimit bounds unsent coordinator messages in one daemon. Episode detectors enqueue once per transition; this queue only retries delivery (tla/FriendNotices.tla, Queue and Send; tla/BusSendOnce.tla).
const OpenCodeConfig = "opencode.json"
OpenCodeConfig is the project config file opencode reads in its directory.
const OutboxRetry = time.Minute
OutboxRetry is how long a finish the server did not answer, or refused, waits before it is sent again; the report stays where it is, and friend sync may finish it first.
const OutputKept = 2048
OutputKept bounds how much of a turn's output the daemon keeps in its record: the head, enough to see what the session did with the message.
const PauseBeatAhead = time.Hour
PauseBeatAhead is how far ahead the friend's down beat sets its --until while the pause marker stands. Every beat sends it again, so it never lapses while she is paused; once a person clears the marker the next beat goes without --until and withdraws it.
const PauseFile = "PAUSED"
PauseFile is the marker in the state directory that holds the lanes down: it outlives the daemon, and nothing resumes until a person removes it (nova-friend resume).
const PongSubject = "pong"
PongSubject is the subject of a session's pong on the bus (nova-friend pong): the answer to a reach step or a delivery check, never liveness.
const ProgressEvery = 3 * time.Minute
ProgressEvery is how often the daemon stamps progress on a card whose lane turn prints: the sprint's own number (internal/sprint ProgressEvery, inside the late rule's ten-minute window; docs/SPEC-SPRINT.md section 8, the rules table's row late).
const ReadAskEvery = 10 * time.Second
ReadAskEvery is how often the daemon asks its reader queue, which is the reader's beat.
const ReadBodyKept = 3500
ReadBodyKept bounds the body of a read's RESULT.md recorded as its finding.
const ReportCap = 64 * 1024
ReportCap bounds the REPORT.md the daemon reads (friend sync's own cap): a verdict, a head and 600 characters need far less, and a larger report is noted and never read whole.
const ReportChars = 600
ReportChars is how much of a failed report rides on its finish.
const ReportWait = 2 * time.Minute
ReportWait is how long a lane the server says holds a card whose outbox has the report of a run before that no outbox step can ever finish (a RESULT.md alone, a REPORT.md with no Verdict: a run cut between its writes) waits before it finishes it failed itself. A report with a Verdict is the outbox step's alone, whatever it waits on (a LAND's head not yet origin's tip, a tip that cannot be read, a finish not taken): the lane never finishes it.
const RetiredDir = "inbox/retired"
RetiredDir is where a job whose card left her row goes, under her working directory.
const RetiredEpochs = "retired"
RetiredEpochs is the folder under the friend's working directory that keeps the items the epochs retired, named for its epoch: retired/epoch-<n>/inbox/<job> and retired/epoch-<n>/outbox/<job>.
const RunnerLogCap = 4 << 20
RunnerLogCap bounds the runner log the daemon reads: its last RunnerLogCap bytes.
const SeatCacheFor = 10 * time.Second
SeatCacheFor is how long the daemon keeps the seat holder it read from the sprint server: the authority of a message is never older than this (docs/SPEC-FRIEND.md, bus-authority-labels.w3).
const ServedBy = "daemon-writes-every-taken-card3"
ServedBy is the card that adds friend cards to the sprint server: a daemon whose server refuses the verb names it, so whoever reads the line knows which server change is missing.
const SessionLimited = "limited"
SessionLimited is the status file's session while the harness is down at its limit: `session=limited kind=<k> until=<RFC3339>`.
const StatusErrorEvery = time.Minute
StatusErrorEvery bounds reports of an unwritable daemon status file.
const StopReturnReason = "owned process stopped"
StopReturnReason is the reason every stop-return names.
const StopReturnRetry = StatusErrorEvery
StopReturnRetry is how long a refused stop-return waits before it is sent again: the store's verb may be absent, and the lane step runs every second.
const StopReturnsKept = 200
StopReturnsKept bounds the stop-returns the lane state keeps once sent: the record of the acks, newest last.
const TailKept = 64 << 10
TailKept bounds the output a lane's turn keeps for its tail: its last TailKept bytes.
const TakeRetry = 5 * time.Second
TakeRetry is how long a lane waits after a refused ask, or an answer it cannot run yet (its brief not in her inbox, its job not staged), before it asks again.
const TakeWait = 10 * time.Second
TakeWait bounds one ask to the sprint server.
const TipBudget = 10 * time.Second
TipBudget bounds the one ls-remote of Tip.
const TmuxPrefix = "friend-"
TmuxPrefix starts the name of every hosted session: friend-<name>.
const TokenPoll = 15 * time.Second
TokenPoll is how often a lane reads a running card's usage where the harness prints none as it runs (an OpenCode turn: its session's export).
const TokenPollEvery = 15 * time.Second
TokenPollEvery is how often a running card's tokens are read for the cap.
const ViewWhy = "the server does not serve friend cards, and the worker view names the card and its job with no brief"
ViewWhy is why a card the worker view names has no brief written for it.
const WallVerb = "wall"
WallVerb is nova-friend's verb that runs one command inside a lane's wall: `nova-friend wall --profile <p> --dir <d> --deny <self>... [--config-dir <c>] [--job <j>]... [--read <r>]... -- <command> <args>` (docs/SPEC-FRIEND.md, buds-in-the-wall-r.w5).
Variables ¶
var ActivityRoots = []string{"outbox", "inbox", "jobs", "."}
ActivityRoots are the places the walk reads, in this order, under her working directory: the outbox (her results), the inbox (the cards she was dealt), then the jobs and the rest of the directory, so a large clone cannot use the bound up before the outbox is read.
var AllPronouns = []Pronouns{SheHer, HeHim, TheyThem}
AllPronouns is every set a row may name.
var AppBundles = map[string]string{
"claude": "com.anthropic.claudefordesktop",
"codex": "com.openai.codex",
"cursor": "com.todesktop.230313mzl4w4u92",
"antigravity": "com.google.antigravity",
"windsurf": "com.exafunction.windsurf",
"zed": "dev.zed.Zed",
"warp": "dev.warp.Warp-Stable",
}
AppBundles is the bundle identifier the window step looks up for a GUI harness. These are lookup ids, not a measured survey of installed apps. A harness with no entry, and not tmux, has no window.
var ClaudeTrim = []string{"--strict-mcp-config", "--disable-slash-commands", "--no-chrome", "--tools", "Bash", "Read", "Write", "Edit", "Grep", "Glob"}
ClaudeTrim is the trimmed call of a headless Claude Code run (the owner's finding of 2026-10-04: no MCP servers, no slash commands, no browser, six tools, which cut the context of each call from about 50k tokens to 12.7k). --tools takes every argument after it, so it is last, after the prompt.
var DefaultActivityLimits = ActivityLimits{Files: 2000, Time: 50 * time.Millisecond}
DefaultActivityLimits is what the daemon walks with: two thousand files, fifty milliseconds.
var DefaultLaneCaps = map[string]time.Duration{ "flash": 15 * time.Minute, "pro": 45 * time.Minute, "heavy": 90 * time.Minute, "frontier": 150 * time.Minute, }
DefaultLaneCaps is the wall cap of a lane's card by its tier, where the row names none.
var ErrBinaryOnRemovableVolume = errors.New("binary on a removable volume: launchd starts it and it does nothing")
ErrBinaryOnRemovableVolume is the refusal when the agent's binary is on a removable volume and cannot be copied under the home (docs/SPEC-FRIEND.md). launchd starts that binary and it does nothing.
var ErrLanguageServerNotRunning = errors.New("no antigravity language server is running: is Antigravity open?")
ErrLanguageServerNotRunning is returned when no Antigravity language server is running.
var ErrNoConfigDir = errors.New("harness claude wants --config-dir (or CLAUDE_CONFIG_DIR): the friend's own Claude config directory, written into the agent")
ErrNoConfigDir is the refusal of claude settings with no config directory: a friend on Claude Code has her own CLAUDE_CONFIG_DIR, and install writes it into the agent (run --config-dir) rather than a unit carrying it by hand.
var ErrNoSession = errors.New("no grok session is open")
ErrNoSession is WakeOf's refusal when no grok window is open in the directory.
var ErrNotDue = errors.New("not due")
ErrNotDue is a Held that did not ask this pass (the worker view is read once a ViewEvery): nothing is reconciled and nothing is said.
var ErrNotRealDir = errors.New("not a real directory")
ErrNotRealDir is the refusal when a path a harness setting names is a symlink or not a directory: a harness that resolves it works elsewhere or refuses (Codex took no writes into a symlinked writable root, 2026-10-05). Install never replaces a symlink; the remedy is to name the real path.
var ErrSessionInNoDB = errors.New("no opencode database read holds the session")
ErrSessionInNoDB is a session that none of the databases read holds: its tokens are unread, never zero.
var GoShimNames = []string{"go", "gofmt"}
GoShimNames are the commands the shims stand in for.
var Harnesses = append([]string{"opencode", "codex", "claude", "antigravity", "dsh", "gemini", "grok", "tmux"}, RefusedHarnesses...)
Harnesses are the harness names run and install take, in the order the help lists them; OpenCode, Codex, Antigravity, DSH, Gemini, Grok and tmux (a TUI hosted by nova-friend host) have a deliver command, the rest refuse honestly (Stub), the surveyed ones with their reason.
var HostPrompts = map[string]string{
"opencode": `^\s*[┃>]?\s*Ask anything`,
"grok": genericPrompt,
"aider": `^(\S+ )?>\s*$`,
}
HostPrompts is each hostable harness's idle prompt pattern, matched against the last non-empty line of the captured pane. It is data: --prompt on host overrides it for a harness that draws its prompt differently.
var OpenCodeRunFlags = []string{"--session", "--model"}
OpenCodeRunFlags are the flags of `opencode run` the adapter passes: the session of a turn, and the model of a read. The directory is never one: it is the process's working directory.
var ReadModels = map[string]string{
"frontier": "claude-fable-5-1",
"heavy": "claude-opus-5-5",
"pro": "claude-sonnet-5-5",
"flash": "claude-haiku-5-5",
}
ReadModels is the model of each tier for a claude account's reads, the table the bud runners carried. It is the one claude tier map: nova-friend's ReadModel hook reads it for every claude lane. The owner's rule (2026-10-11): each tier runs the newest model of its class, flash haiku, pro sonnet, heavy opus, frontier fable, and never a bigger class (read_lanes_models_test.go pins both).
var Refusals = map[string]string{
"copilot": "not installed here; the route is `copilot -p <text> --resume <id>`, after `copilot login`",
"cursor": "not installed here; the route is `agent -p --resume <chatId> <text>`, after `agent login`",
"amp": "not installed here; the route is `amp -x --thread-id <id> <text>`, with AMP_API_KEY",
"goose": "not installed here; the route is `goose run -n <name> -r -t <text>`, with a provider key",
"kiro": "not installed here; the route is `kiro-cli chat --resume-id <id> <text>`, after `kiro-cli login`",
"cline": "not installed here; the route is `cline --id <session> <text>` to the hub at 127.0.0.1:25463, after `cline auth`",
"aider": "no route: aider keeps no session to adopt, only a history file replayed into a new process",
"roo": "no route: Roo Code's sendMessage API lives inside VS Code, reachable only from another extension",
"windsurf": "no route: nothing documented reaches a running Cascade conversation from outside the app",
"zed": "no route: Zed is an ACP client; nothing documented reaches a running thread from outside",
"warp": "no route: `oz run message send` reaches cloud runs only; `oz agent run` starts a new run",
}
Refusals are the harnesses of the survey of 2026-10-04 (SPEC-FRIEND.md, the harness survey) with no adapter: each the one-line reason, the route the vendor documents where there is one, and what would make it real. None of them is installed on this machine; one with a route gets its adapter the day its binary and login are there.
var RefusedHarnesses = []string{"copilot", "cursor", "amp", "goose", "kiro", "cline", "aider", "roo", "windsurf", "zed", "warp"}
RefusedHarnesses lists Refusals in a fixed order, for the registry.
Functions ¶
func AIPath ¶ added in v1.2.14
AIPath is the working root of an AI name on a machine: every path nova tools build for an AI sits under <root>/ai/<name>/, its working directory being <root>/ai/<name>/working (docs/FRIENDS.md, the ai/ layout).
func AdapterRemedy ¶
AdapterRemedy is what a friend on a harness with no deliver command does: the adapter card that gives it one, or a harness that has one.
func AgentAPI ¶
func AgentAPI(out string) (json.RawMessage, error)
AgentAPI reads what agentapi printed: its response, or its error (printed at exit 0 like a response).
func AllowDirs ¶
AllowDirs writes into dir's opencode.json that a tool call may touch each of paths and everything under it without a prompt (permission external_directory, a pattern map of path globs to allow), merged into what the file holds, written only when it changes. A headless opencode run auto-rejects a call that would prompt, and the turn ends there (measured 2026-10-04: a friend's working directory reached through its symlink in the home directory). It answers whether it wrote.
func AntigravityRunner ¶ added in v1.2.10
AntigravityRunner is the agentapi program the antigravity adapter's lanes run, the wrapper the harness ships under the home (Home/.gemini/antigravity/bin/agentapi). It is the one path the adapter's agentapi runs and the acceptance run looks up, so the probe executes the daemon's own program (docs/SPEC-FRIEND.md, the acceptance run: the lane's own program). An empty home is the current user's.
func BenchRule ¶
BenchRule is the sentence every read prompt carries: the machine the friend runs on runs no go command, a Linux bench does.
func BriefFix ¶
BriefFix is the fix a brief's prelude asks of its attempt: its THE ONE THING LEFT line, else the server's 'The coordinator asks:' line, on one line; "" for a brief that asks none.
func BusLogEntries ¶
func BusLogEntries(ctx context.Context, st bus.Store, friend string, since time.Time) (realCount int, lastReal time.Time, err error)
BusLogEntries reads the bus store log for real messages from friend since since (docs/SPEC-FRIEND.md "Check": the facts, bus).
func CappedWords ¶
CappedWords is how a capped card's end names the cap, the words the sprint reads off its failed finish (internal/sprint ParseLaneCap): `capped at <cap> (tier <tier>, overrun <d>)`, overrun the card's wall past the cap when the lane ended it.
func CardText ¶
CardText is one lane turn: the card and its three steps, every path absolute, the brief's text inline (a model that reads a path relative still has it). No session bus message rides with the card.
func CheckFolderRoute ¶
CheckFolderRoute keeps the harness and session identity independent of the delivery route. The target must already be watched; the daemon never makes it.
func ClaimLane ¶
ClaimLane claims the job's card for the lane who at now: the mark is created when there is none (only one creator can win), taken over when the one there is stale, and kept when it is who's own. holder is the lane that holds it instead ("" when claimed).
func ClaudeAsyncBashHook ¶
ClaudeAsyncBashHook is the pure PreToolUse response for an opt-in Claude Code project hook (docs/CLAUDE-ASYNC-BASH-CANDIDATE.md). Every Bash call requests a native background task so an omitted timeout cannot hold the session when background tasks are enabled. The response changes only tool input; permission rules still decide whether the command may run.
func ClaudeInstallLine ¶
ClaudeInstallLine is the NOTE install prints for harness claude; every other harness gets none.
func ClaudeProofArgs ¶ added in v1.2.12
func ClaudeProofArgs() []string
ClaudeProofArgs is claude's cheapest no-tool turn: one prompt, JSON out, one turn, no tools. The prompt travels as an argument, never parsed.
func ClaudeProofWhy ¶ added in v1.2.12
ClaudeProofWhy runs claude's cheapest no-tool turn through run (the daemon's own exec, with CLAUDE_CONFIG_DIR=configDir) and answers why the harness cannot answer: "" when it can, else "harness claude cannot answer: <terminal_reason> (config dir <dir>)". A run that answers nothing, exits nonzero, or names a terminal reason that is not a normal end fails.
func ClaudeWaitLine ¶
ClaudeWaitLine is the one line a claude session runs as a background task (docs/SPEC-FRIEND.md, the Claude paragraph): the session's own blocking read of the bus, re-armed with the cursor it printed each time it returns. Claude Code has no command that puts a turn into a running session from outside; a background task's exit re-invokes the session. It is a command run once inside the session, not a flag, an environment variable or a wrapper at app start. wake is the file the daemon appends one line to per message, so a wait that missed nothing still returns.
func ClaudeWakePath ¶
ClaudeWakePath is the wake file of a claude friend: <state>/<friend>.wake, in the daemon's state directory, named on the line the session runs.
func ClearLaneFault ¶ added in v1.2.14
ClearLaneFault removes the lane fault file, the person's clear; whether one was there.
func ClearPause ¶
ClearPause is a person bringing the lanes up: the marker removed; whether one was there.
func CodexAddRoot ¶
CodexAddRoot is the text with root added to writable_roots: the key's lines replaced by one line holding every root there and root, the key added under its table when absent, the table appended when absent.
func CodexRoots ¶
CodexRoots is writable_roots in a Codex config.toml's text; found is false when the key is absent.
func ContextFull ¶ added in v1.2.7
ContextFull says a provider refusal's reason is one of those wordings.
func CopyExecutable ¶
CopyExecutable copies src onto dst and keeps it executable. dst is replaced only after the copy is complete, so a failure leaves a previous dst in place (docs/SPEC-FRIEND.md).
func CostLine ¶
func CostLine(t LaneTokens, rp RoutePrice, model string) (report, tokens, cost string)
CostLine is the Cost: line a REPORT.md carries under its Head: line, and the tokens: and cost: lines a RESULT.md does. The card is priced by the route row; opencode's own figure is kept beside it.
func CostOf ¶
func CostOf(t cardcost.Tokens, rp RoutePrice, model string) string
CostOf prices a card's tokens at the route row, rounded up to the cent; with no row, or a sheet that cannot price them, "unpriced (<why>)": never a guess.
func DSHArgs ¶
DSHArgs is the argument list of one delivery; the text travels on stdin ("-"), so it is never parsed as an argument.
func DSHNoPresetRemedy ¶
DSHNoPresetRemedy is what a friend whose dsh session runs under an agent preset does: nova-friend install and run refuse that session with it (PushProof), since no delivery into it can succeed.
func DSHSessionKey ¶
DSHSessionKey is the store's directory for the sessions of dir: the path with every separator a dash, one more dash in front and two behind (measured 2026-10-04 on the store: /Volumes/nova/ai/zhi is --Volumes-nova-ai-zhi--).
func DaemonStateDir ¶
DaemonStateDir is where a daemon run with no --state-dir keeps its files: StateDirIn(dir), made by mkdir; when that is refused (a background process on macOS may not touch a removable volume without the person's permission), DefaultStateDir, and why names the refusal for the record.
func DeadLaneReport ¶
DeadLaneReport is the REPORT.md the daemon writes for a dead lane: Verdict FAIL, and the runner's END line.
func DefaultDenySelf ¶ added in v1.2.7
DefaultDenySelf is the coordinator's self a lane wall denies when the daemon was given no --deny-self (nor NOVA_FRIEND_DENY_SELF): the seat's working root on this machine, <home>/ai/<seat>/working, which holds the seat's self repository and its copies. A wall that denies nothing is refused (sandbox bad_profile, exit 125 for every lane), so a friend installed without the flag must not run lane-less. nil when the seat is unknown or is no plain name; the wall then refuses as it always did.
func DefaultReadWork ¶
func DefaultReadWork(dir string) (inboxCount, outboxCount int, newestName string, newestAt time.Time, err error)
DefaultReadWork reads directory entries of inbox/ and outbox/ under dir (docs/SPEC-FRIEND.md "Check": the facts, work).
func DefaultStateDir ¶
DefaultStateDir is the home directory's state directory for friend, ~/.nova-friend/<friend>: where a daemon from before the state moved under --dir kept its files, and where one goes when its directory refuses them (DaemonStateDir).
func EndReport ¶
EndReport is the REPORT.md a lane writes for a card whose run ended without one: HOLD with the pushed head when the friend's branch has one (friend sync keeps a HOLD's head when it is origin's tip), else FAIL; one paragraph naming the lane, how the run ended and the head. A card the lane ended at its cap is a HOLD, head or none, and its report quotes the last lines of the lane's output after the paragraph, each indented four spaces (lane_cap.go).
func ExitTimeout ¶
ExitTimeout is the plist's ExitTimeOut, DefaultExitTimeout when it has none.
func FaultDownText ¶
func FaultDownText(friend string, p Pronouns, reason string, until time.Time) (subject, body string)
FaultDownText is the one judgment the seat is told when a row's lanes hit the same harness fault FaultRepeats times within FaultWithin: the subject and the body, naming the reason the row is down with and until when.
func FaultWords ¶
FaultWords is a harness fault as the record and the row say it: the fault and the harness's first error line ("the harness printed no error line" when it printed none).
func FindStateDir ¶
FindStateDir is where a reader looks for friend's state when no --state-dir names it: StateDirIn(dir) when a daemon has written its status there, else the home directory's (a daemon from before the move, or one whose directory refused it).
func FinishArgv ¶
FinishArgv is the sprint server's failed finish of a card whose run ended without the friend's report: `finish --as friend.<name> <card>@<gen> --epoch <n> --failed [--head <sha>] [--branch <b>] --report <text>`, the report as friend sync words it ("friend <name> <verdict>: <paragraph>").
func FinishNote ¶
FinishNote is the bus note to the coordinator at a lane's finish: the subject and body.
func FixAddressed ¶
FixAddressed says a report addresses fix: it names (case-insensitively, anywhere) at least half of the fix's key words, rounded up; a fix with none is addressed. missing is the key words it does not name.
func FixKeyWords ¶
FixKeyWords is what a report on fix is grepped for: its distinct words of four or more letters, digits or underscores, lower case, the empty ones (fixStopWords) left out, the first MaxFixKeyWords of them.
func FriendCardsArgv ¶
FriendCardsArgv is the worker verb the daemon sends the sprint server for her held cards.
func FundsJudgmentText ¶
FundsJudgmentText is what the coordinator is told when a friend's provider is out of funds: one judgment.
func GeminiArgs ¶
GeminiArgs is the argument list of one delivery: the frame, apart from the transport.
func GoShimName ¶
GoShimName says whether argv0 names a shim (this binary run as go or gofmt, by symlink).
func GoShims ¶
GoShims makes dir hold a go and a gofmt that are this binary (self) by symlink, so that run by those names it refuses (GoShimName, GoRefusal): no script, nothing to drift. Links already right are kept.
func GrokInstallLine ¶
GrokInstallLine is the NOTE install prints for harness grok. Every other harness gets none. session is --session, the wake file, empty when the session chooses the path.
func GrokMonitorLine ¶
GrokMonitorLine is the one line the open session runs so a delivery is a turn in that window. An empty wake is the placeholder the session replaces with its own absolute path. It is a command run in the session, not a flag or a wrapper at app start.
func GrokWakePath ¶
GrokWakePath is the wake file install names for a grok friend when --session names none: <state>/<friend>.wake, under the daemon's state directory, so no unit carries a path typed by hand.
func HarnessFirstError ¶
HarnessFirstError is the first line of a harness's output that says an error, one line, at most 200 bytes; "" when none does.
func HarnessSpent ¶ added in v1.2.14
HarnessSpent is a harness's spend so far in USD, as the harness's own usage report says it (docs/SPEC-FRIEND.md, spend caps): DSH's record, OpenCodePriced's priced runs, or Claude's cost. 0 for a harness that reports none, which is never capped by measurement and is stopped by its provider's funds refusal instead.
func HeldVia ¶
func HeldVia(friend string, ask func(ctx context.Context, argv []string) (string, error), view func(ctx context.Context) (string, error), now func() time.Time) func(context.Context) (Row, error)
HeldVia is the daemon's Held over the sprint server: friend cards <friend> (ask), its answer read by ParseHeld, which carries each card's brief. While the server refuses that verb (a server that does not serve it yet: Refused), the worker view (view, GET /api/view/worker?as=<friend>) says which work cards are on her row and the job each is delivered as, with no brief: her inbox is counted against it and a job whose work card left is retired, and a held card with no BRIEF.md is said missing and not written. The view is read once a ViewEvery (ErrNotDue between), and friend cards asked again once a ServedEvery, each refusal said in the Row's Note; with view nil a refusal is NotServed, once a ServedEvery (ErrNotDue between); an ask the server did not answer is its error.
func HostPrompt ¶
HostPrompt is the idle prompt pattern a hosted harness gets: override when given, else the harness's own from HostPrompts; src is its source text, as saved in the friend's state. A harness with none and no override is refused with the names there are.
func Install ¶
func Install(ctx context.Context, a Agent, uid int, run Launchctl, write func(path string, data []byte) error, wait func()) (path string, ran []string, err error)
Install writes the plist and loads it. A binary on /Volumes is copied under the home first (PlanBinary); a copy that cannot be made is refused and nothing is written (docs/SPEC-FRIEND.md). Then a bootout of whatever that label runs now (nothing loaded is fine), a wait until launchd no longer holds the label (WaitReleased), then a bootstrap into the user's domain, sent again after wait() while launchd answers EIO, so running it again replaces the agent with the same result. It answers the plist's path and the commands it ran.
func InstalledBinary ¶
InstalledBinary is the copy of a removable-volume binary, under the home, off /Volumes (docs/SPEC-FRIEND.md).
func IsRealMessage ¶
IsRealMessage reports whether a message subject is a real turn message (not a pong) (docs/SPEC-FRIEND.md "Check": the facts, bus).
func JobText ¶
JobText is a staged job's JOB.md: the card-contract shape (docs/SPEC-CARD-CONTRACT.md), the checkout, the branch, the outbox report and the finish.
func LaneCap ¶
LaneCap is the wall cap of a card of tier: the row's (caps) when it names one above zero, else DefaultLaneCaps'; a tier neither names (none was read for the card) is capped at the longest default, frontier's, so a card whose tier is unknown is never cut shorter than it could be owed.
func LaneContext ¶
LaneContext is ctx marked as a lane's.
func LaneDirOf ¶
LaneDirOf is the job directory ctx carries, else def: a harness's run in a lane goes there.
func LaneEnvironmentFault ¶ added in v1.2.13
LaneEnvironmentFault says a lane run is the friend's environment fault: it ended within InstantFail with no report file and its output names a filesystem error on a path outside the lane. It answers the harness's error line and true.
func LaneFaultParts ¶ added in v1.2.14
LaneFaultParts is LaneFaultReport's inverse, so a reader (nova-friend status, nova-friend lanes) renders the report's count and refusal line as the two fields the card names without re-parsing the wording in two places. ok is false when report is not a LaneFaultReport (docs/SPEC-FRIEND.md, the lanes).
func LaneFaultReport ¶ added in v1.2.14
LaneFaultReport is the one line a faulted lane carries on the beat: lane-fault=<n> refusal="<first line>", where n is how many identical refusals faulted it.
func LaneFaultText ¶ added in v1.2.14
LaneFaultText is the one judgment the coordinator is told when a lane faults on a provider refusal: the subject and body naming the fault, the hold verb that returns the friend's cards, and the harness check (docs/SPEC-FRIEND.md, the lanes).
func LaneFilesystemError ¶ added in v1.2.13
LaneFilesystemError is the first line of a lane run's output that names a filesystem error (EEXIST, EACCES, EPERM, ENOENT) and names a path outside the lane dir; "" when none does. A run that trips on the shared /tmp names its path there, outside every lane.
func LaneMarkEnded ¶
LaneMarkEnded is the mark of a finished card: "ended: card finished by <who>".
func LaneMarkRunning ¶
LaneMarkRunning is the mark of a running lane: "running: <who> at <RFC3339>".
func LaneSeed ¶
LaneSeed is the first turn of a lane's new session: who the friend is, from her own files, and what each later turn will be.
func LaneTakeArgv ¶ added in v1.2.7
LaneTakeArgv is lane n's ask of the sprint server: what it holds, else its next card. It names the worker's row and the lane and nothing else: no card, no epoch.
func LaneTmpDir ¶ added in v1.2.13
LaneTmpDir is the private temporary directory of the lane whose job directory is dir: <lane dir>/tmp. Wall.Exec makes it 0700 before the run and removes it after; RunWall names it at TMPDIR, TMP, TEMP and CLAUDE_CODE_TMPDIR, so two lanes get two directories and no harness run reaches the shared /tmp.
func LanguageServer ¶
LanguageServer finds the antigravity language server in `ps -axo user=,pid=,args=` belonging to username: its pid and CSRF token.
func LastResult ¶
LastResult is the newest turn's line of the daemon's log (the line a turn's end writes, "<RFC3339> lane=<n> ... exit=<n>"): when it ended and its exit. No log, or no turn in it, is the zero time.
func LimitAlikeText ¶
LimitAlikeText is the one judgment the coordinator is told when three lanes in a row ended with the same first error line and none names a limit or a credit or quota refusal the daemon's table knows (cmd/nova-friend/limit.go, RefusalWatch): the line, so the wording is added or the cause is found, never a silent fourth retry.
func LimitDownText ¶
func LimitDownText(friend string, p Pronouns, until time.Time, reason string) (subject, body string)
LimitDownText is what the seat is told when friend's harness hits its limit: the subject, and a body with the line that shows why and until when on her row (nova-sprint friend down --reason --until).
func LimitUnreadText ¶
func LimitUnreadText(friend string, p Pronouns, rest time.Duration, text string) (subject, body string)
LimitUnreadText is the one judgment the coordinator is told when friend's harness refused at its limit with a text that names no reset this reads: the text, the rest she is held for, and the line that sets the true reset.
func LimitUpText ¶
LimitUpText is what the seat is told when friend's harness's reset passed.
func ListenPorts ¶
ListenPorts reads the ports out of `lsof -Fn` (one n<host>:<port> line per socket), in the listing's order.
func Load1Of ¶
Load1Of reads the one-minute load off `sysctl -n vm.loadavg` ("{ 1.23 1.50 1.60 }") or /proc/loadavg ("1.23 1.50 1.60 1/300 12345").
func LogPath ¶
LogPath is the daemon's own log in the state directory: one line per delivery (launchd's own log is elsewhere: Plist).
func NewestConversation ¶
NewestConversation picks the first conversation of the summaries query (newest first, as `sqlite3 -json` printed it) whose workspaces hold one of dirs.
func NewestDSHSession ¶
NewestDSHSession is the most recently modified session of dir under the sessions root: the directory names are the session ids.
func NewestWrite ¶
NewestWrite is the newest modification time of a file under the roots of fsys, zero when there is none (a root that is not there, an empty tree). It reads at most lim.Files files and runs at most lim.Time by now's clock, never descends into activitySkip, and reads a root named earlier once.
func NotHers ¶
NotHers is the refusal of a report on a card that is no longer hers: never finished, with the line naming who holds it now, as the beat's running list says (a card id or job to the friend whose lane runs it), else that no row the daemon reads names one.
func OutboxFinishArgv ¶
OutboxFinishArgv is the finish a friend's report gives her card c (its job's card, epoch and generation): LAND with a full sha Head finishes at that head with the report's first paragraph, as friend sync words it; any other verdict (HOLD, FAIL, a LAND with no full sha Head) is --failed, with a HOLD's or FAIL's full sha Head kept, and the report's first ReportChars characters. The branch is the brief's.
func PacingJudgmentText ¶
func PacingJudgmentText(friend string, paced, width int, pacing float64, use string) (subject, body string)
PacingJudgmentText is what the coordinator is told when a friend's lanes are paced below half her row's width: one judgment.
func PacingOf ¶
PacingOf is the pacing a row's setting gives: the setting when it is a fraction in (0, 1], else DefaultPacing.
func PacingText ¶
PacingText is a pacing fraction as a percent: "80%".
func ParseJob ¶
ParseJob reads a friend's job directory name, <id>~<epoch> with .g<gen> after it from the card's second generation (nova-sprint friendJobOf); gen is 1 when it has none.
func ParseLaneCaps ¶
ParseLaneCaps reads the row's lane caps off her beat's answer (row_lane_caps=flash:15m,pro:45m,heavy:1h30m,frontier:2h30m, beside row_mode and row_width); ok is false when the answer carries none, or one with a pair that is no tier:duration above zero.
func ParseMachine ¶
ParseMachine reads the machine's word off a beat's answer (`machine=RUNNING` or `machine=STOPPED`); ok false when the answer carries none (a server before the word).
func ParseProfile ¶
ParseProfile reads the friend's wall profile off her beat's answer (row_profile=<name>, beside row_mode and row_width); ok is false when the answer carries none.
func ParseReadSlots ¶
ParseReadSlots reads the friend's read slots off her beat's answer (row_read_slots=<n>, beside row_mode and row_width); ok is false when the answer carries none.
func ParseRow ¶
ParseRow reads the friend's row off her beat's answer (nova-sprint friend beat prints row_mode=<mode> row_width=<n>, as friend sync last wrote her nova-config row); ok is false when the answer carries none.
func ParseShown ¶
func ParseShown(data []byte) (map[string]ShownEntry, error)
ParseShown parses JSON representing shown state.
func PauseBeat ¶
PauseBeat is the friend's beat while the pause marker (its line, ReadPause) stands: down until PauseBeatAhead from now, with the provider's exact message as the reason. `friend beat <friend> --until <t> --reason <r>` is a worker's verb the sprint server serves; while her last beat says so she is down and the dealer deals her nothing (docs/SPEC-SPRINT.md).
func PermissionRejection ¶
PermissionRejection is the first line of out that says a permission was refused, one line, at most 200 bytes; empty when none does.
func PlanBinary ¶
PlanBinary is the path the plist will name. A binary on /Volumes is copied to InstalledBinary before the plist is written (copy=true); a binary off /Volumes is used as-is (copy=false). A home that is empty or itself on /Volumes is refused, because a copy there would stay on the wall (docs/SPEC-FRIEND.md).
func PlatformPermitted ¶
PlatformPermitted is false where the platform cannot hold the permission. It does not call run and it does not ask. The window step then refuses with the same remedy as a missing grant (docs/SPEC-FRIEND.md, Reach).
func PlistArgs ¶
PlistArgs is the ProgramArguments array of a launchd plist, in order; nil when the plist has none or cannot be read as XML.
func PlistDriftLine ¶
PlistDriftLine is the line a daemon says on start when its own arguments (running, after the program's name) differ from the installed plist's: a launchctl kickstart restarts the agent launchd loaded, with the arguments it read then, so an edit to the plist is lost until it is booted out and bootstrapped again (the finding of 2026-10-05). The daemon's part of each is compared, from its verb "run" on (the secrets wrap and the binary's path are the plist's own). Empty when there is no plist, it names no run, or the two agree.
func PongLine ¶
PongLine is a session's pong as it travels on the bus: pong <nonce> queue=<n> working=<n> width=<n>. A session sends it to answer a reach step or a delivery check (nova-friend pong); liveness is the nova-hook record's alone, never a pong.
func PongRequest ¶
PongRequest reads a delivery's text for the pong it asks for: its kind (PongCheck for a session check, else PongWake), the nonce of its pong command, and whether it asks for nothing else (a session check, a wake turn, an idle wake, which a newer request of its kind supersedes). A delivery carrying a bus message is never only a request.
func ProgressArgv ¶
ProgressArgv is the sprint server's verbs that stamp progress on the cards, one for the cards of each epoch, in the order of the epochs: `progress --as friend.<friend> <card>... --epoch <n>`, her row as the holder, as FinishArgv names it. Only the holder's stamp is taken: the server refuses one for a card she does not work, and one sent as her bare name (held by friend.<name>, not <name>).
func PromptPattern ¶
PromptPattern compiles a prompt pattern, panicking on a bad constant.
func PronounList ¶ added in v1.2.16
func PronounList() string
PronounList is the three sets a row may name, for a flag's help and refusal.
func ProviderLimit ¶
ProviderLimit reads the tail of a lane turn's output (the last LimitTail bytes: a harness says it last) for a rate limit or out of funds, out of funds first: OutOfFunds, RateLimited, or nil. A line with its reset beside it ("Insufficient AI Credits ... will refresh 6:52 PM") is the harness's own limit (Limits: down until the reset, then woken), never out of funds here.
func ProviderRefusal ¶
ProviderRefusal reads a failed turn's output for a provider's refusal: the error type and the head of its message, one line; ok is false when the output carries none, or only a transient one.
func PublishCost ¶
func PublishCost(outbox string, t LaneTokens, rp RoutePrice, model string) error
PublishCost writes the card's cost into its outbox: the Cost: line into REPORT.md, which friend sync reads, and the tokens: and cost: lines onto RESULT.md when it is there. A report not there is not made.
func PushedHead ¶
PushedHead is the head the friend pushed for card c: the branch its brief's STATUS line names, read as origin's remote-tracking ref in a clone under dir's jobs/<job>/ (a push writes it; no network is asked). Empty when the brief names no branch or no clone holds the ref; branch is the brief's either way.
func Pushing ¶
func Pushing() []string
Pushing is the harnesses whose adapter has a deliver command, in the order of Harnesses.
func RateJudgmentText ¶
func RateJudgmentText(friend string, p Pronouns, cap, width int, reason string) (subject, body string)
RateJudgmentText is what the coordinator is told when a friend's lane cap was lowered RateJudgeAfter times within RateJudgeWithin: one judgment.
func ReadBeginArgv ¶
ReadBeginArgv begins an asked read.
func ReadLaneFault ¶ added in v1.2.14
ReadLaneFault is the lane fault report, or "" when there is none.
func ReadPrompt ¶
ReadPrompt is the one turn a read runs: do READ.md, stop when RESULT.md is written.
func ReadQueue ¶
ReadQueue is the queue file's counts; a file that is not there counts zero, and a file that is no queue is an error the caller shows.
func ReadQueueArgv ¶
ReadQueueArgv is the sprint verb that is the reader's beat and answers its queue.
func ReadReturnArgv ¶
ReadReturnArgv returns a read that has no verdict, with why.
func ReadVerdict ¶
ReadVerdict reads a read's RESULT.md: its verdict (ok or broken; "" when there is none), and the finding recorded with it, the report line then the body.
func ReadVerdictArgv ¶
ReadVerdictArgv records a read's verdict (ok or broken) with its finding and usage.
func RealExec ¶
func RealExec(ctx context.Context, dir, name string, args []string, stdin string) (string, int, error)
RealExec runs the command through os/exec: the program directly, never a shell, so a message's text is never interpolated. No clock bounds it: a turn that prints keeps running however long it takes, and the daemon stops one silent past its SilentStop by cancelling ctx (the finding of 2026-10-04: a fixed ten-minute cap killed real work mid-turn). Every write to stdout or stderr is said to the watch in ctx (WithOutputSeen). The command is its own session leader (Setsid), and on a cancel the whole group is signalled, SIGTERM then SIGKILL after KillDelay: a harness that forks (opencode run does) leaves no orphan behind a stop. On a nonzero exit the output carries the head of stderr after stdout: a harness says why it refused there (dsh does).
func Record ¶
Record appends one line to the daemon's log; a log that cannot be written is not a reason to stop delivering, so the error is answered for the status file and nothing else.
func ReportPara ¶ added in v1.3.16
ReportPara is a report's first line that is no Verdict or Head line and no heading, on one line.
func ReportVerdict ¶ added in v1.3.16
ReportVerdict is a report's verdict (the first word of its first Verdict: line, upper case, with markdown and punctuation trimmed; "" for none) and its head (the first word of its first Head: line, lower case), read as friend sync reads them.
func RescueStray ¶
RescueStray moves a report a run wrote under a relative spelling of the outbox (the job directory joined with the outbox path less its leading slash: the stray tree of 2026-10-07) into the outbox, REPORT.md and RESULT.md each when the outbox lacks it; it answers the files moved.
func ResentLine ¶
func ResentLine(d AntigravityDelivery) string
ResentLine heads a delivery sent again into the conversation that reads.
func ReworkedBrief ¶
ReworkedBrief is a reworked card's brief with its fix first: STATUS; THE ONE THING LEFT, the fix; The reader found, the finding (or why the attempt exists when no reader found anything); the carried head and the branch it is carried onto; how the report is checked; then the rest of the prelude as the server wrote it, and the card with its STOP the fix alone. A brief that asks no fix, and one already reworked, are answered as they are.
func RowConfigDir ¶
RowConfigDir reads the friend row's config_dir off her beat's answer (row_config_dir=<dir>, the directory her claude lanes run with as CLAUDE_CONFIG_DIR); empty when the answer carries none.
func RunWall ¶
RunWall is the wall verb: args are its flags, "--", and the command; env is the environment the command gets inside the wall (its HOME is the one the deny list is under). It prints nothing on stdout but the command's own, so a harness's answer is read through it as it is; a refusal is one WALL REFUSED line per problem on stderr and sandbox.ExitRefused. The answer is the command's exit.
func RunnerEnded ¶
RunnerEnded reads a runner's log for the job: dead is true when the job's last event is an END whose last word is report=no and no LIMIT came after the START before it; end is that END line.
func RunnerLog ¶
RunnerLog is the log of the runner beside her working directory dir, its last RunnerLogCap bytes: dir's runner.log, else the one in the directory her working directory (its links resolved) is in; "" when there is none.
func RunsCards ¶
RunsCards says harness runs each card as a process of its own (a CardRunner) when its row is one-shot: it has no session to push a turn into, so install and run owe it no deliver-command refusal. The session's nova-hook owns delivery and proof independently of these lane processes. NewDeliverer answers its batch adapter, the wake file (ClaudeWake); NewClaude is the one that runs cards.
func SessionCheckText ¶
SessionCheckText is the delivery check as the session reads it: the nonce, and the one line to run with nothing to fill in, sent to to (the seat, else the coordinator; the pong verb's own default when empty).
func SessionCost ¶
SessionCost is the cost of a session from its export: the sum of its assistant messages' costs. The export may be preceded by a line of its own (opencode says what it exports on stderr); the JSON starts at the first '{'.
func SessionMissing ¶ added in v1.2.7
SessionMissing says a turn's first error line says the session is gone.
func SnapEpoch ¶ added in v1.2.7
func SnapEpoch(dir string, row Row, keep map[string]bool, asked, now time.Time, record func(string)) (int, error)
SnapEpoch moves every older-epoch inbox and outbox item under dir to the retired folder named for its epoch, at the sprint's epoch now (Row.Epoch, her row's answer): every inbox and outbox job whose name parses to an epoch older than it (ParseJob), that no lane runs (keep) and that no card on her row holds (row.Cards), and whose directory stood before the ask began (asked, as the inbox's retire guards friend sync's write), is moved whole, so finished work is kept, never deleted, and the live folders start the new epoch empty. A job whose name parses to no epoch, and one that is no single path element, is never moved (a job any other hand put there: docs/SPEC-FRIEND.md, the inbox). record gets one line per move; the first error is answered, the rest still moved. It answers how many moved. Zero is a sprint epoch of no card's naming: nothing is retired on it.
func SpendCapJudgmentText ¶ added in v1.2.14
func SpendCapJudgmentText(friend string, p Pronouns, provider string, spent, cap float64) (subject, body string)
SpendCapJudgmentText is what the seat and the owner are told when a friend's spend has passed its cap: one judgment naming the friend, the provider and the spend.
func StageJudgmentText ¶
func StageJudgmentText(friend string, n *NotStageable) (subject, body string)
StageJudgmentText is what the coordinator is told of a stage that waits on a person: one judgment, with its remedy.
func StateDirIn ¶
StateDirIn is the daemon's state directory under the friend's working directory, <dir>/.nova-friend: inside the directory her session may write, so a sandboxed session's pong lands where the daemon reads it (the finding of 2026-10-05).
func StopReturnArgv ¶
StopReturnArgv is the store's verb for one stop-return, as the wire of 2026-10-08 says it.
func TakeArgv ¶
TakeArgv is the coordinator's verb that takes a dealt, unstarted card back from the friend for the dealer: `friend take <friend> <card> --reason <why>`. The sprint server does not serve it to a friend's daemon (it is the coordinator's class, and the server runs only the workers' verbs), so the lanes never send it: they ask the coordinator (TakeBackNote).
func TakeBackNote ¶
TakeBackNote is the bus note that asks the coordinator to take a card back for the dealer: the subject, and a body naming the card, why, and the exact verb to run (TakeArgv).
func TmuxFor ¶
TmuxFor points a Tmux deliverer at the friend's hosted session: the session and prompt host saved in stateDir, else friend-<name> and the generic prompt. Any other deliverer is left alone.
func TmuxSession ¶
TmuxSession is the tmux session that hosts the friend name.
func TokenCapOf ¶
TokenCapOf reads the row's token cap off her beat's answer (row_token_cap=<n>, beside row_mode and row_width; 0 is no cap); ok is false when the answer carries none, or one that is no whole number at or above zero.
func TokenCapReport ¶
TokenCapReport is the REPORT.md of a card whose lane was stopped at the per-card token cap: HOLD with no head, one paragraph naming the cap, the tokens and turns it had spent and the last step; the card goes to a bud and whatever was pushed is a draft only.
func TokensSQL ¶
TokensSQL is the query for the tokens of a session and its children from opencode's database.
func TypeScript ¶
TypeScript is the osascript that brings bundle frontmost, types text and submits it with Return (key code 36). It never asks for permission.
func TypedLine ¶
TypedLine is text as the one line a TUI is typed: each newline shown as " ⏎ ", as the Grok adapter does (SPEC-FRIEND.md, "Hosted in tmux").
func UnaddressedLand ¶
UnaddressedLand is the one fix check of a LAND, the daemon's outbox pass's and friend sync's: held is UnaddressedText when report does not address the fix the brief asks (BriefFix, in either form), "" when it does or when brief asks none. A held LAND is finished as a HOLD, its head kept.
func UnaddressedText ¶
UnaddressedText is the first words of the finish the holder by (the daemon, or friend sync) sends for a LAND whose report does not address THE ONE THING LEFT.
func Undriven ¶
Undriven says nova-friend can push nothing into a session of harness through d: a Stub, with why and the remedy (AdapterRemedy); ok is false for an adapter with a deliver command.
func Uninstall ¶
func Uninstall(ctx context.Context, a Agent, uid int, run Launchctl, remove func(path string) error) (ran []string, err error)
Uninstall boots the agent out and removes its plist; an agent that is not there is fine.
func WaitReleased ¶
func WaitReleased(ctx context.Context, run Launchctl, target string, timeout, poll time.Duration, sleep func(time.Duration)) (time.Duration, error)
WaitReleased waits until launchd no longer holds the service target (gui/<uid>/<label>) after its bootout: `launchctl print <target>` asked every poll, until it no longer finds the service (anything but exit 0 with the service's own `<target> = {` block), at most timeout. A bootstrap sent while launchd is still removing the old service is refused with "37: Operation already in progress" for as long as the old daemon takes to exit (about 5 s, the seat's adopt runs of 2026-10-07), more than BootstrapTries one second apart. It answers how long it waited, and on timeout an error naming the label and the seconds.
func WakeLine ¶
WakeLine is text as the one line a monitor event is: the monitor makes an event per line, and a flood of lines is how the harness stops a monitor (its guide's "Volume Control"), so a newline in the text becomes " ⏎ ".
func WakeOf ¶
WakeOf is the wake file a delivery goes to: the file a `tail` tails under the grok session open in dir, from the harness's active_sessions.json (pid and cwd per open window) and the process listing (`ps -axww -o pid=,ppid=,args=`). A named wake must be that file. A session whose pid is not in the listing is a stale record, not a session. No window in dir is ErrNoSession.
func WithCost ¶
WithCost is report with line under its Head: line (at the end when it has none); a report that already carries a Cost: line is returned as it is.
func WithLaneDir ¶
WithLaneDir is ctx carrying dir, the job directory the lane's harness runs in (LaneJob.Dir).
func WithOutputSeen ¶
WithOutputSeen is ctx carrying seen, called each time the command a delivery runs prints to stdout or stderr: a turn that prints is working, and only a turn silent past the daemon's SilentStop is stopped.
func WithOutputTail ¶
WithOutputTail is ctx carrying tail, handed each write the command a delivery runs prints to stdout or stderr.
func WorkspaceConversations ¶
WorkspaceConversations is every conversation of the summaries query, in its order (newest first), whose workspaces hold one of dirs.
func WriteLaneFault ¶ added in v1.2.14
WriteLaneFault records a lane's provider-refusal fault report; an empty report removes the file (a clear, or a stale file a restart cleared).
func WritePause ¶
WritePause records the exact provider message that held the friend down.
func WriteStatus ¶
WriteStatus is the daemon's write of its state.
func WriteWatch ¶
WriteWatch saves the cursor atomically (write a temporary file, rename it over the old), so a run killed in the middle leaves the old cursor whole.
Types ¶
type ActivityLimits ¶
ActivityLimits bounds one walk: the files it reads the time of (a directory costs time, not files) and the time it may take on the clock it is given. A walk that reaches either answers with the newest write it has read.
type Agent ¶
type Agent struct {
Friend, Harness, Dir, Session string
Adapter, DeliveryDir string // explicit Codex folder route; session remains the real harness session
StateDir string // the daemon's state files, when not the default under Home
Binary string // this tool, by absolute path
Copy CopyFile // places a removable-volume binary under Home; nil refuses it
Redis, Server string // the bus store and the sprint server
Home, Path string // the environment the agent runs in
LaunchdLog string // launchd's own stdout and stderr path, off the friend's volume
// Secrets are the names of the secrets the daemon needs in its environment
// (never values); with any, the command is wrapped in nova-secrets exec as
// the seat Seat, with SecretsTool and Sops by absolute path, the store under
// Home/nova-bench/secrets and the key under Home/.config/nova-secrets.
Secrets []string
Seat, SecretsTool, Sops string
// Coordinator, SilentStop and BrokenAfter are the daemon's flags of the
// same names, written only when set and not the default.
Coordinator string
SilentStop time.Duration
BrokenAfter int
// ConfigDir is the friend's harness config directory (CLAUDE_CONFIG_DIR),
// the daemon's --config-dir, written only when set.
ConfigDir string
// Pronouns are the friend's pronouns (the row's pronouns setting), the daemon's --pronouns,
// written only when set.
Pronouns string
// DenySelf is the coordinator's self the daemon's lane wall never writes inside, the
// daemon's --deny-self, written only when set (the daemon's default, DefaultDenySelf,
// stands when it is not).
DenySelf string
// WallReads is what the harness reads inside the lane's wall beyond the system roots and its
// own directory (a pinned harness shim under the home), the daemon's --wall-reads, written only
// when set.
WallReads string
// Command, when set, is what the agent runs in place of the daemon: this tool's
// own verb and flags, after Binary.
Command []string
// Sleep is how Install waits between two looks at the old service after the
// bootout (ReleasePoll); nil is time.Sleep. A test passes its own clock.
Sleep func(time.Duration)
}
Agent is one friend's launchd agent: the daemon as launchd runs it, never started by the model (SPEC-FRIEND.md, the daemon).
func (Agent) Args ¶
Args is the daemon's command line: with Secrets, nova-secrets exec opens exactly those names for the daemon (--only) and refuses to start it without every one (--require), then the daemon itself after the --.
func (Agent) BinaryPlan ¶
BinaryPlan is where the agent's binary is placed, and whether it is copied there (PlanBinary).
func (Agent) Plist ¶
Plist is the agent's plist: RunAtLoad and KeepAlive, so it starts at login and is restarted when it dies (pending messages redeliver first, nova-bus's rule). launchd opens its own log itself, before the daemon runs, and cannot open one on a network volume (EX_CONFIG, measured 2026-10-03), so that log is LaunchdLog, under the home directory, and so are the daemon's state files and record (DefaultStateDir).
type AgentAPIRefusal ¶
type AgentAPIRefusal string
AgentAPIRefusal is the error agentapi printed in its JSON, at exit 0: the harness said no (a wrong conversation, a missing token).
func (AgentAPIRefusal) Error ¶
func (r AgentAPIRefusal) Error() string
type Antigravity ¶
type Antigravity struct {
Dir, Session string
Run Exec
Out io.Writer // the daemon's record, when set
Home string // the user's home ($HOME when empty): app data under Home/.gemini/antigravity
User string // daemon's username (current process user when empty)
FS fs.FS // rooted at Home (os.DirFS(Home) when nil): the mailbox is read through it
Wait func(context.Context) bool // one poll interval; false once ctx has ended (real time when nil)
Now func() time.Time // the daemon's clock, every time in the ledger (time.Now when nil)
State string // the daemon's state directory: the ledger's file (AntigravityLedgerFile); "" keeps it in memory
// contains filtered or unexported fields
}
Antigravity delivers through the harness's own agent-message channel: `agentapi send-message --title=nova-friend <conversation> <text>`, a client of the running language server (the wrapper under ~/.gemini/antigravity/bin, which execs the app's language_server). The server writes the text into the conversation's mailbox (~/.gemini/antigravity/brain/<conversation>/.system_generated/messages/) as a high-priority message and its watcher starts a turn on it; the session marks the message read in read.json there as it takes it. Measured 2026-10-04 08:52 ET: sent at :28, the turn's first step at :32, the friend's "got it" on nova-bus2 at :35.
The server's address and CSRF token are read off the language_server process each delivery (ps, then lsof for its listening ports; the one that answers get-conversation-metadata is the plaintext one). The conversation is the live one (Follow), else the one named by Session, else the newest root conversation whose workspace is Dir, from the harness's conversation_summaries.db (read immutable, through sqlite3).
The mailbox queues: a turn the message starts runs on, and a second message waits in the mailbox for it, the harness's own order for its agents. So Deliver answers 0 once agentapi has taken the message into the mailbox, and never waits for the session to read it (the finding of 2026-10-05 and 06: a delivery that waited two minutes for the read held every other message and the session check behind it while the friend worked through a long turn, and three such waits gave a message up that was already in her mailbox). Every delivery is kept in the ledger (antigravity_ledger.go): who read it, and what to send again if its conversation stops reading. agentapi exits 0 on an error too (a wrong conversation, a missing token): the JSON it prints is the truth, never its exit code. What the harness refuses (no language server, no token, no conversation, no port that answers for it, no mailbox), and a session that has read nothing delivered for the check period, is a SessionRefused naming why, never a Deferred: the daemon marks the session broken with the reason, said once, and keeps every message pending on the bus.
func (*Antigravity) Deliver ¶
Deliver: find the server and the conversation; refuse while the conversation has read nothing delivered for the check period (the session is down: the message stays pending on the bus); send; and answer 0 once agentapi has taken the message into the mailbox, kept in the ledger.
func (*Antigravity) Follow ¶
func (a *Antigravity) Follow(ctx context.Context, now time.Time)
Follow reads, at most every AntigravityFollowEvery, who has read the deliveries (observe), and moves delivery to the conversation that reads: when the live conversation has left AntigravityStopped deliveries unread past AntigravityReadBound and read nothing since the oldest of them, a conversation the daemon delivered to that read one of those deliveries since then is the live one (the one that read last), said once ("antigravity: live conversation is now <id> (the named one stopped reading)"), and never moved again within AntigravitySwitchHold. Every delivery the old conversation left unread is sent again into the new one, headed by ResentLine; one whose send fails is sent again at the next look.
func (*Antigravity) Live ¶
func (a *Antigravity) Live() string
Live is the conversation deliveries go to: the one delivery was moved to, else the one the last delivery went to, else the one named by Session; "" before the first delivery when none is named.
type AntigravityDelivery ¶
type AntigravityDelivery struct {
ID string `json:"id"`
Conversation string `json:"conversation"`
DeliveredAt time.Time `json:"delivered_at"`
ReadAt time.Time `json:"read_at,omitzero"`
ResentTo string `json:"resent_to,omitempty"`
Text string `json:"text,omitempty"`
}
AntigravityDelivery is one delivery: its message id in the conversation's mailbox ("" until it lands), when it went in and when the daemon saw it read, the conversation it was sent again into, and its text while it may be sent again.
type AntigravityLedger ¶
type AntigravityLedger struct {
Followed string `json:"followed,omitempty"`
From string `json:"from,omitempty"`
Since time.Time `json:"since,omitzero"`
Deliveries []AntigravityDelivery `json:"deliveries"`
}
AntigravityLedger is the ledger's file: the conversation delivery follows (Followed, moved to while the named session was From, at Since) and every delivery, oldest first.
type AskedRead ¶
type AskedRead struct {
ID string
Epoch string
Gen int // the read card's generation as the queue carries it (0: a queue before it); a stop-return names it
Packet ReadPacket
Col string // its column on the reader queue (asked, reading)
Lane int // the read lane the server says holds it (take --as reader-<friend> --lane <n>); 0 none
}
AskedRead is one card of the reader queue in the asked column.
func ParseReadQueue ¶
ParseReadQueue reads `queue --as reader-<friend> --json`: the asked reads, in the queue's order, each with the queue's epoch.
func ParseReadQueueAll ¶ added in v1.2.7
ParseReadQueueAll is every read on the reader queue, whatever its column, each with the queue's epoch: a read lane that holds a read begun before it finds its packet here.
type BeatWords ¶
type BeatWords struct {
StopReturns int
}
BeatWords are what a beat carries beside the friend's name: how many stop-returns the lanes owe (stop.go, OwedStopReturns), said while it is above zero (friend beat --stop-returns).
type BusFacts ¶
type BusFacts struct {
Friend string `json:"friend"`
RealSince int `json:"real_since"`
LastReal string `json:"last_real"` // RFC3339 or "-"
}
BusFacts carries facts about real messages on the bus.
type Card ¶
type Card struct {
ID string `json:"id"`
Brief string `json:"brief"`
Outbox string `json:"outbox"`
// Lane, ServerEpoch and ServerGen are what the server's answer to a lane's ask named
// (lane_take.go): the lane that holds the card, the epoch and the generation it holds it
// at. A card a lane holds is reported by these, never by its directory's name.
Lane int `json:"lane,omitempty"`
ServerEpoch string `json:"server_epoch,omitempty"`
ServerGen int `json:"server_gen,omitempty"`
}
Card is one card a lane hands: its id (the queue file's), its brief, and the outbox directory its REPORT.md and RESULT.md go to.
func NextCard ¶
NextCard is the first card of dir's queue file (inbox/QUEUE.json, in its order) that is queued, delivered (inbox/<id>~<epoch>/BRIEF.md), not done (no outbox/<id>~<epoch>/RESULT.md, and no REPORT.md: a card with a report is friend sync's to finish) and not skipped (held by another lane, or set aside); found is false when there is none.
func (Card) Epoch ¶
Epoch is the sprint epoch alone, without the job's generation (docs/FRIENDS.md): the server's, when its answer named one, else the job directory's.
func (Card) Gen ¶
Gen is the card's generation, its directory's .g<gen> (friend sync names a card dealt again to the same friend <id>~<epoch>.g<gen>); 1 when it has none.
type CardRunner ¶
type CardRunner interface {
Deliverer
// RunCard runs card c to its end: its exit, and an error naming what the
// outbox lacks when the run wrote no REPORT.md or RESULT.md there.
RunCard(ctx context.Context, c Card) (LaneTurn, error)
// Refusal is why no card can run now, with its remedy; empty when one can.
Refusal() string
}
CardRunner is a Deliverer whose one-shot lane runs each card as a process of its own: no session to open or keep, the card's brief the whole prompt, no bus message riding along, and the card's result read from its outbox, never from the process's output (docs/SPEC-FRIEND.md, one-shot lanes; the owner, 2026-10-04: four Claude accounts as heavy-tier friends). Claude is one.
type CardUsage ¶
CardUsage is a running card's tokens so far, read from its harness's own record. A test hands a fake; a lane hands the harness's stream or export.
type CheckReport ¶
type CheckReport struct {
Friends []FriendCheck `json:"friends"`
Summary CheckSummary `json:"summary"`
}
CheckReport is the top-level report for JSON serialization.
func (CheckReport) Lines ¶
func (cr CheckReport) Lines() []string
Lines renders all output lines for the full report.
type CheckResult ¶
type CheckResult struct {
Harness string `json:"harness"`
Nonce string `json:"nonce"`
Stage string `json:"stage,omitempty"`
Why string `json:"why,omitempty"`
Took time.Duration `json:"took"`
}
CheckResult is one run of the check: Stage empty is a pass.
func PushProof ¶
func PushProof(ctx context.Context, c Conformance) (res CheckResult, remedy string, undriven bool)
PushProof runs the check c once as the push proof: an undriven harness is refused before anything is delivered; otherwise the round trip runs, and a failure whose delivery the adapter answered with a Deferred carrying a Remedy (a session it cannot drive) answers that remedy with undriven set. remedy is empty for any other failure: the caller names its own.
func (CheckResult) Line ¶
func (r CheckResult) Line() string
Line is the result as nova-friend check prints it.
type CheckSeams ¶
type CheckSeams struct {
Now func() time.Time
Home string
Launchctl Launchctl
ReadStatus func(friend string) (Status, bool, error)
ReadHook func(friend string) (HookRecord, error) // her nova-hook record; nil reads none
ReadLog func(friend string) ([]string, error)
BusLog func(ctx context.Context, friend string, since time.Time) (realCount int, lastReal time.Time, err error)
ReadWork func(friend string, dir string) (inboxCount, outboxCount int, newestName string, newestAt time.Time, err error)
ListFriends func() ([]string, error)
HarnessDir func(friend string) (harness, dir string, err error)
}
CheckSeams provides external dependencies for friend check facts.
type CheckSummary ¶
type CheckSummary struct {
Friends int `json:"friends"`
OK int `json:"ok"`
Broken int `json:"broken"`
Down int `json:"down"`
Untrue int `json:"untrue"`
}
CheckSummary is the counts across all checked friends.
func ComputeSummary ¶
func ComputeSummary(checks []FriendCheck) CheckSummary
ComputeSummary aggregates verdicts across friends (docs/SPEC-FRIEND.md "Check": the summary).
func (CheckSummary) Line ¶
func (s CheckSummary) Line() string
Line renders the CHECK OK summary line.
type Claude ¶
type Claude struct {
Stub
Friend, Dir string
// ConfigDir is the friend row's config_dir as the daemon last read it;
// nil or empty refuses every card.
ConfigDir func() string
Run Exec
Program string // "claude" when empty
Out io.Writer // where the run's output goes, when set: the daemon's record
Now func() time.Time // time.Now when nil: the clock a limit's reset is read against
// TokenCap is the friend row's per-card token cap as the daemon last read
// it (TokenCapOf; 0 none); nil is DefaultTokenCap (tokencap.go).
TokenCap func() int64
// contains filtered or unexported fields
}
Claude is the claude harness: no deliver command in batch (Stub, passive: the daemon reads nothing for it), and in one-shot mode each card run as `env CLAUDE_CONFIG_DIR=<dir> claude -p <brief> --output-format stream-json --verbose` and the trim (ClaudeTrim) in Dir with stdin from /dev/null, priced and its limit read from its stream-json (adapter_claude.go). The config directory is the friend row's config_dir, so each friend is its own account's login and settings (its permission mode among them); stream-json prints as the run works, so the daemon's silence watch sees a working run.
func NewClaude ¶
NewClaude is the claude harness's card runner over run, in the friend's directory dir, its runs' output going to out when set.
func (*Claude) Refusal ¶
Refusal names the missing config_dir and its remedy: a claude friend in one-shot mode runs only as her own account.
func (*Claude) RunRead ¶
RunRead is one read of the friend's reader row (ReadHarness; docs/SPEC-FRIEND.md, the reader row): a card run's call with the prompt for the brief and the model of the read's tier ("" is the account's own) before the trim, as her own account, priced and its limit read as a card's run is.
type ClaudeWake ¶
type ClaudeWake struct {
Dir, Name string
Now func() time.Time // time.Now when nil
Out io.Writer // the daemon's record, when set
}
ClaudeWake is the claude adapter: Claude Code has no command that puts a turn into a running session from outside, so Deliver puts nothing in. It appends one line per push to the wake file in Dir, the friend's state directory (ClaudeWakePath(Dir, Name)): the clock, then the pushed text on one line, which carries the nonce or message id and the path of what was pushed. The session's own wait (ClaudeWaitLine), running as a background task, returns when the file grows, and its exit re-invokes the session. The file is made when absent, synced, and never truncated; a missing Dir is a refusal naming it, and nothing is made. Name is the session's name for the file, else the friend of Dir's status file. It is Passive: the daemon takes nothing off the stream for claude.
func (*ClaudeWake) Passive ¶
func (*ClaudeWake) Passive()
Passive marks the claude adapter: the session's own wait reads the stream.
type Conformance ¶
type Conformance struct {
Friend, Harness string
Deliver Deliverer
Store bus.Store
Within time.Duration
Now func() time.Time
Wait func(ctx context.Context) bool // one CheckPoll; false once ctx has ended
Nonce func() string
Text func(nonce string) string // the session check as the session reads it (SessionCheckText)
}
Conformance is the one promise every harness adapter makes, checked end to end (docs/SPEC-FRIEND.md, delivery-conformance-r.w1; the presence model's Ask then Answer within the bound, tla/FriendPresence.tla): a session check carrying a fresh nonce goes in through the adapter, the session runs the exact pong line it carries, and a pong with that nonce from the friend is on the bus within Within. The unit tier runs it over a fake Exec and bus's Fake; nova-friend check and install run it against the live session.
func (*Conformance) Run ¶
func (c *Conformance) Run(ctx context.Context) CheckResult
Run delivers the check and reads for its pong until Within has passed. A Stub's refusal, a Deferred and a nonzero exit are stage deliver, each with the adapter's own reason.
type CopyFile ¶
CopyFile copies src onto dst. CopyExecutable is the one install uses; a test passes its own, and nil refuses a removable-volume binary.
type Courier ¶
type Courier struct {
// Bus is the bus every send goes on; Open, when set, dials one for each
// send instead (the server's way: one connection per note) and its
// failure is watched like a send's.
Bus *bus.Bus
Open func(ctx context.Context) (*bus.Bus, func(), error)
Watch *bus.Watch
Now func() time.Time
}
Courier is how the sprint server sends its notes to friends: each send on the bus, its result watched, so a store that refuses the login or cannot be reached is one alarm to the coordinator, raised at the first failure and cleared at the next success, and never only a log line (the finding of 2026-10-04: 54 failures in 30 minutes, WRONGPASS for the server's bus user, and nothing said so; docs/SPEC-FRIEND.md, fr-delivery-receipts.w1). Every note is owed its friend's receipt like any message to her (docs/SPEC-BUS.md, fr-delivery-receipts.w1).
type DSH ¶
type DSH struct {
Dir, Session string
Run Exec
Program string // DSHProgram when empty
Sessions string // the sessions root; DSH_HOME/sessions, else ~/.dsh/sessions, when empty
Out io.Writer // where the turn's output goes, when set: the daemon's record
// contains filtered or unexported fields
}
DSH delivers through `dsh headless --session-id <id> -` run in Dir, the text on stdin: the headless profile adopts the persisted session (the same session directory under ~/.dsh/sessions/<key>/<id>, its record grows by one turn; measured 2026-10-04, v0.2.0-rc.2) and exits when the turn ends. An unknown id, a session recorded in another directory, and a missing provider key each exit 1. Without a session named, the newest session of Dir from the store (DSH_HOME, else ~/.dsh). The desktop app the friend sits in shares the store. Measured 2026-10-04 and 2026-10-05 (docs/SPEC-FRIEND.md, the dsh row): a session under an agent preset is refused by the one-shot runner whatever the text, exit 1 before any write, its transcript hash unchanged (the runner adopts only a session with no preset, and a session never returns to none). Measured 2026-10-06: the same refusal also comes with exit 0. The refusal, and MISSING_CREDENTIAL, are read from the output whatever the exit (DSHRefusal): a SessionRefused, so the message stays pending instead of being given up after three refusals, and the daemon marks the session broken at once until a turn succeeds. On the survey machine, deliver.log records 1339+ deferred deliveries against Zhi's real open session, and the desktop app exposes no local listener or IPC socket. No route into the open desktop session exists, so Route answers defer; the session reads the bus itself with nova-bus wait or nova-bus recv.
func (*DSH) Route ¶
Route is what status and check say: push. Every delivery goes into the friend's session as a headless turn (dsh headless --session-id), the session check included; none waits on the open desktop app, which no route reaches (docs/SPEC-FRIEND.md, the dsh row). line is that turn's command.
func (*DSH) SpentUSD ¶ added in v1.2.14
SpentUSD is the cost of every run so far, in US dollars, as the harness's own usage report says it (docs/SPEC-FRIEND.md, spend caps). Each turn's output is read for the cost it names (dshCost): the stream-json result line's total_cost_usd, else a `cost_usd=<n>` token. A turn that names no cost is not counted, and the provider's funds refusal stops the daemon instead of the cap.
type Daemon ¶
type Daemon struct {
Friend, Harness, Dir string
// Pro holds the friend's pronouns (the row's pronouns setting): every text the daemon
// writes about the friend says them through d.say. Nil is they/them.
Pro *PronounsRef
Notices *Notices
Store bus.Store
Deliver Deliverer
Beat func(ctx context.Context, active time.Time) error // one beat to the sprint server, carrying the session's last activity (zero: none known)
StepBeatForTests bool // deterministic fake-clock seam; production has one independent beat caller
// Activity is the newest write of the session's files, read by the
// independent beat cadence at most once an ActivityEvery and carried on
// each beat; nil knows no write.
Activity func() time.Time
Now func() time.Time
// Pause waits between lane steps while the independent beat continues.
Pause func(ctx context.Context, d time.Duration)
Record func(line string) // one line per delivery, to the daemon's log
// MachineStopped says the machine's word, as the owner last read it off the beat's
// answer (ParseMachine), is STOPPED: the lanes cancel what runs, owe and send
// stop-returns, and start nothing (stop.go). nil: never stopped.
MachineStopped func() bool
// StopReturn sends one stop-return (StopReturnArgv) to the sprint server; nil sends it
// through Sprint.
StopReturn func(ctx context.Context, argv []string) error
// Limited is the harness's limit now: its kind and reset, and whether there is one
// (Limits.Limited, Limits.Kind); nil: none. While there is one the status says
// session=limited with them, and the turns the Gate defers stay pending.
Limited func() (kind string, until time.Time, limited bool)
// Status receives the daemon's state whenever it changes, and every
// StatusEvery (WriteStatus over the state files).
Status func(Status) error
// SilentStop is how long a running turn may print nothing before it is
// stopped (DefaultSilentStop when zero); BrokenAfter how many turns in a
// row the provider refuses the same way before the session is broken
// (DefaultBrokenAfter when zero); Coordinator who is told of a broken
// session when the sprint server names no seat.
SilentStop time.Duration
BrokenAfter int
Coordinator string
// Row is the friend's nova-config row as the daemon last read it (from
// its beat): her delivery mode (ModeBatch or ModeOneShot) and width,
// read every step so a change takes effect without a restart; nil, or
// empty answers, deliver in batch, and a width of 0 runs no lane: the width
// is nova-config's alone, answered by the server (row).
Row func() (mode string, width int)
// Pacing is the row's pacing as the daemon last read it: the fraction of each
// subscription window the lanes may spend, read every step; nil, or out of
// (0, 1], is DefaultPacing (pacing.go). No beat carries the row's pacing yet,
// so nova-friend leaves it nil.
Pacing func() float64
// LaneCaps is the row's wall cap of a lane's card by its tier as the daemon last read
// it (ParseLaneCaps off its beat), read every step; nil, or a tier it names none for,
// is DefaultLaneCaps (lane_cap.go).
LaneCaps func() map[string]time.Duration
// LoadLanes and SaveLanes let tests carry lane state between loop instances.
// Production keeps that state in memory; the sprint server owns lane records.
LoadLanes func() (LaneState, error)
SaveLanes func(LaneState) error
// CardDone is the one bus line a lane's session sends when its card is
// done (nova-bus send by path, as this friend, to the coordinator).
CardDone func(card, to string) string
// Progress stamps progress on the cards whose lane turn printed (ProgressArgv to the
// sprint server); nil stamps none.
Progress func(ctx context.Context, cards []Card) error
// Finish sends one finish verb to the sprint server: a lane's card whose run ended with
// no REPORT.md (FinishArgv, lane_end.go), and every working card on her row whose job's
// REPORT.md says a verdict, whoever wrote its brief (OutboxFinishArgv, outbox.go). Nil,
// or a finish not answered, leaves it to friend sync, which reads the same REPORT.md.
Finish func(ctx context.Context, argv []string) error
// Take sends one take to the sprint server (LaneTakeArgv), its refusal an
// error: a lane starts a card only once the server has it working on her row (lane_take.go).
// Nil (a test's world) takes nothing, and a lane runs any card on her row as before.
Take func(ctx context.Context, argv []string) (string, error)
// The lanes' parity with the runner scripts they replace (lane_parity.go); Rules nil
// turns every one off. Rules is her row's lane rules as her beat last answered them,
// Load the machine's one-minute load (nil: no load rule), Tokens a session's tokens
// from opencode's database (nil: no cost and no token cap), Route the store's route row
// for her model and Model its name, LaneHold the pause marker's line (the lanes held
// down by a provider failure until a person clears it) and LaneHoldDown writes it: her
// beat then says her down with its message (PauseBeat).
Rules func() LaneRules
Load func() float64
Tokens func(ctx context.Context, session string) (LaneTokens, error)
Route func() RoutePrice
Model string
LaneHold func() string
LaneHoldDown func(ctx context.Context, message string) error
// Fault is the lane's provider-refusal fault report in the state directory
// (ReadLaneFault), and FaultWrite records or clears it (WriteLaneFault): the
// loop's poll sees a fault it holds whose file a person cleared and releases
// the lanes, and a stale file a restart cleared. The friend's main wires it
// to the state directory; nil (a test's world) leaves the fault in memory
// only, cleared by a restart (docs/SPEC-FRIEND.md, the lanes).
Fault func() string
FaultWrite func(report string) error
// FaultExternal is a lane fault the limit detector counted itself (lanes
// failing alike): the loop adopts it as the same record a provider's refusal
// writes, then clears it. The friend's main wires it to the detector; nil:
// no such fault.
FaultExternal func() string
// FaultDown marks her row down until until with reason: the same harness fault
// FaultRepeats times within FaultWithin on her lanes (lane_parity.go); her beat says
// her down with them until then (friend beat --until --reason). Nil: her lanes are
// held here alone.
FaultDown func(until time.Time, reason string)
// RefusalDown marks her row down until until with reason: a server that refused one
// of her verbs RefusalRepeats times in a row (inbox.go, "A refused verb"). RefusalUp
// clears it when the server answers again. Nil: the refusal is said, never beaten down.
RefusalDown func(until time.Time, reason string)
RefusalUp func()
// Prove runs the harness's cheapest no-tool turn and answers its terminal reason
// (harness_proof.go): "" when the harness can answer, the reason when it cannot. Nil
// proves nothing (every harness can answer; a test's world). Until it answers, the
// daemon takes no card, beats down with the reason, tells the coordinator once, and
// re-proves every ServedEvery (docs/SPEC-FRIEND.md, "A lane proves its harness").
Prove func(ctx context.Context) string
// Held is every card on her row as the sprint server says it (HeldVia: friend cards
// <friend>, else the worker view), asked once an InboxEvery; her inbox is reconciled with
// the answer (SyncInbox, inbox.go). Nil leaves her inbox to friend sync alone.
Held func(ctx context.Context) (Row, error)
// Sprint sends one verb to the sprint server and answers what it printed: the reader row's
// queue, begin, verdict and return (read_lanes.go). Nil runs no reads. ReadSlots is the
// row's read slots, read each step (nil: DefaultReadSlots), and ReadModel the model of a
// read's tier ("": the harness's own).
Sprint func(ctx context.Context, argv []string) (string, error)
ReadSlots func() int
ReadModel func(tier string) string
// Stage stages a held work card's job (Stager.Stage: jobs/<job>/repo and its JOB.md) and
// answers the commit staged (stage.go); nil stages none, and a lane is handed a card with
// its brief alone.
Stage func(ctx context.Context, p Packet) (string, error)
// Prune removes finished jobs' worktrees past FinishedJobsKept (Stager.Prune), given the
// jobs that are live (held on her row, run by a lane, being staged), after each inbox
// cleanup, and answers the jobs it removed; nil prunes none.
Prune func(ctx context.Context, live map[string]bool) ([]string, error)
// Tip is origin's tip of a branch of a repository (owner/name), "" when origin has no
// such branch (Stager.Tip: one git ls-remote): a report's LAND finishes only at that tip,
// as nova-sprint collect's does (outbox.go). Nil reads none, and a LAND finishes at its
// Head.
Tip func(ctx context.Context, repo, branch string) (string, error)
// Running is the beat's running list as the sprint server last said it, every friend's:
// a card id or job to the friend whose lane runs it. A lane is never started for a card
// it names another friend running, and a lane whose card left her row names its friend
// on the job's lane mark (one_lane.go). Nil says none; the lane marks still hold.
Running func() map[string]string
// Holders reads the server's current card-to-holder map (view cards), once
// per outbox pass that finds a report outside her row. Nil uses Running's
// known holders; an error refuses with the explicit unknown-holder remedy.
Holders func(ctx context.Context) (map[string]string, error)
// Seat is the coordinator seat holder as the sprint server says it: who the
// daemon tells (coordinator), else Coordinator. An error, an empty name or a
// nil Seat is the seat unknown.
Seat func(ctx context.Context) (string, error)
// contains filtered or unexported fields
}
Daemon runs one friend's lanes, reader slots, and sprint metadata beat. Session messages belong to nova-hook, which owns the bus delivery lease. Everything it reaches outside itself is a field, so a test runs it over bus's Fake, a fake harness and its own clock.
func (*Daemon) Idle ¶ added in v1.2.14
Idle reports whether the last step has no running lane or read. The spend cap uses it to avoid launching work while there is nothing to run.
func (*Daemon) OwedStopReturns ¶
OwedStopReturns is how many stop-returns the lanes owe now: the beat carries it.
func (*Daemon) Run ¶
Run is the loop until ctx ends. Each step: the clock; the friend's row (Row: her mode and width); each running lane turn's output watched, and a turn silent past SilentStop stopped; the ended lane turns, reads and finishes applied; her inbox reconciled with her row; then, in one-shot mode, each free lane handed its next card (lanes.go) and the reader row served (read_lanes.go); an independent beat; the status. The daemon reads nothing off her bus stream and delivers nothing into her session: a message to her reaches her through nova-hook (pkg/harness/notice), and whether she is there is the nova-hook record's alone.
type DaemonFacts ¶
type DaemonFacts struct {
Friend string `json:"friend"`
Agent string `json:"agent"` // loaded, not-loaded, none
PID string `json:"pid"` // numeric string or "-"
Status string `json:"status"` // the daemon's status file: ok, stale, none
Hook string `json:"hook"` // the hook record's state (none, armed, proven, unhooked, ...), or "-" when not read
Since string `json:"since"` // how long it has been in it, e.g. "4m", or "-"
Answer string `json:"answer"` // the age of her model's last answer to a challenge, or "-"
Misses int `json:"misses"` // challenges in a row left unanswered
Presence string `json:"presence"` // up while the record proves her there, else down
Reason string `json:"reason"` // why the record reads down, or "-"
}
DaemonFacts carries facts about the launchd agent, the daemon, and her nova-hook record: the one truth of whether she is there.
type Deferred ¶
type Deferred struct{ Reason, Remedy string }
Deferred means the harness cannot take this turn now. Remedy names what must change when retry alone cannot succeed (PushProof).
type Deliverer ¶
Deliverer pushes one text through a harness for delivery checks and reach. LaneHarness and CardRunner extend it for the daemon's card turns.
func NewDeliverer ¶
NewDeliverer is the adapter for harness, in the friend's directory, into session (empty: the newest session of that directory where the harness can name one). An unknown harness is refused with the names there are.
func SelectDeliverer ¶
func SelectDeliverer(friendName, harness, dir, session, adapter, deliveryDir string, run Exec, out io.Writer) (Deliverer, error)
SelectDeliverer chooses the explicit folder route, or the harness's supported adapter. Codex has no implicit delivery route (SPEC-FRIEND.md, Codex).
type Entry ¶
type Entry struct {
Kind string // KindDir, KindFile, KindSymlink or KindMissing
Target string // a symlink's target
}
Entry is what a path is, the path itself and never what a symlink names.
type Evidence ¶
type Evidence struct {
DaemonUp bool // the daemon's status file is fresh; shown, never deciding up
Hook HookRecord // her nova-hook record: the one truth of whether she is there
Limit string // the limit's name, when the provider said one
LimitUntil time.Time // the limit's reset; zero, or past, is no limit
Undelivered int // messages waiting on the friend's stream; negative is not counted
BusBlocked string // why the bus cannot deliver to the friend; empty when it can
LastResult time.Time // the end of the last turn; zero is none yet
LastExit int // that turn's exit
}
Evidence is what a friend's status is decided from.
type Exec ¶
type Exec func(ctx context.Context, dir, name string, args []string, stdin string) (stdout string, exit int, err error)
Exec runs one command for an adapter: the program, its arguments and its working directory, with the text on stdin, answering what it printed and its exit code. The daemon passes the real one (RealExec); a test its own.
func ShimExec ¶
ShimExec is run with the shim directory first on the PATH of every lane child and GOROOT pointing nowhere: a command whose context is a lane's runs as `env PATH=<shims>:<path> GOROOT=<nowhere> <name> <args>`; any other runs as it was. Put it outside Wall.Exec so the env runs inside the wall.
type FaultWatch ¶
type FaultWatch struct {
// contains filtered or unexported fields
}
FaultWatch counts one row's harness faults: the FaultRepeats-th of the same fault within FaultWithin is one down until FaultDownFor later; a fault while that down stands adds nothing, and the count starts again once it has passed. The zero value is ready; it reads no clock of its own.
type Folder ¶
type Folder struct {
Dir, Session, Friend, WorkDir string
}
Folder is an explicit delivery route for a real Codex session whose watcher reads Dir. Writing a file is acceptance by the folder, never a session pong. The native proof still requires the session's own nonce-bearing bus reply.
type FriendCheck ¶
type FriendCheck struct {
Friend string `json:"friend"`
Daemon DaemonFacts `json:"daemon"`
Harness HarnessFacts `json:"harness"`
Bus BusFacts `json:"bus"`
Work WorkFacts `json:"work"`
Verdict VerdictFacts `json:"verdict"`
}
FriendCheck is the full fact sheet for one friend.
func CheckFriend ¶
func CheckFriend(ctx context.Context, friendName string, seams CheckSeams, since time.Duration, shown *ShownEntry) FriendCheck
CheckFriend gathers the facts through the seams over the window and decides the verdict for one friend (docs/SPEC-FRIEND.md "Check").
func (FriendCheck) Lines ¶
func (fc FriendCheck) Lines() []string
Lines renders the five CHECK lines for one friend.
type GUIWindow ¶
GUIWindow types one message into a GUI harness's composer and submits it. Permitted, when set, answers whether the accessibility permission is held. Nil asks the platform (PlatformPermitted), which never prompts.
type Gemini ¶
type Gemini struct {
Dir, Session string
Run Exec
Program string // "gemini" when empty
Out io.Writer // where the turn's output goes, when set: the daemon's record
}
Gemini delivers through `gemini --skip-trust --resume <id> --prompt=<text>` in Dir, which resumes the persisted session (the same session id and the same chat file under ~/.gemini/tmp/<project>/chats/, read from the CLI's ChatRecordingService.initialize on 2026-10-04, v0.46.0) and blocks for the whole turn. Without a session named, "latest": the CLI's own newest session of the project that Dir is, so a friend who starts a fresh session is still reached. --skip-trust trusts Dir for this process only; the friend's own session already trusts it. The text goes as --prompt=<text>, one argument, so a message beginning with a dash is never read as a flag. Exit codes are the CLI's: 42 when the session is not found, 55 untrusted, 1 an error.
type Grok ¶
type Grok struct {
Dir string // the friend's directory: the session's cwd
Wake string // the wake file, when named; else the one the session's monitor tails
Run Exec // runs ps
Out io.Writer // the daemon's record, when set
Home string // the grok home, ~/.grok when empty
// contains filtered or unexported fields
}
Grok delivers into the Grok Build TUI (xAI's `grok`), which has no deliver verb, no leader socket unless leader mode is on, and no way to send into an open window: `grok -p <text> --resume <id>` runs the turn in a second process over the same transcript, not in the window the friend is in. What the window has is the monitor tool: a background task whose every new output line "becomes a notification delivered to the conversation" and wakes the agent for a turn (the harness's own guide, ~/.grok/docs/user-guide/20-background-tasks.md). The friend's session runs one over a wake file, `tail -n 0 -F <file>.wake`, and a line appended to that file arrives in the session as a <monitor-event> user turn (measured 2026-10-04 in a friend's session: a user_message_chunk at a new promptIndex in its updates.jsonl). So Deliver appends the text, as one line, to the wake file the open session's monitor is tailing. A backlog is many Deliver calls. Lines written with no gap are the flood that stops the monitor, so each line after the first waits out what remains of wakePace. It is accepted (exit 0) once the line is in the file and the tail was running under that session; the turn runs after Deliver returns, since nothing hands its end back. While no monitor runs (no window, or a window with no tail) Deliver defers: nothing is written, the message stays pending, and the reason carries the one line the session runs. A wake path that is not absolute is a refusal and nothing is written.
func (*Grok) Route ¶
Route is what status says. push: a tail of an absolute .wake file runs under the open window's pid, so a delivery now is a turn in that window. defer: no such tail; line is the monitor line the session runs. A listing or session file that cannot be read is defer, never a silent push, and err says why.
type HarnessFacts ¶
type HarnessFacts struct {
Friend string `json:"friend"`
Harness string `json:"harness"`
Route string `json:"route"` // push, mailbox, queue or passive
Last string `json:"last"` // RFC3339 or "-"
LastExit string `json:"last_exit"`
FailedOfLast20 int `json:"failed_of_last20"`
Deferred int `json:"deferred"`
Delivered int `json:"delivered"` // deliveries in the window (JSON only)
Failed int `json:"failed"` // of those, the ones that failed (JSON only)
Broken string `json:"broken"` // RFC3339 or "-"
Reason string `json:"reason"` // one line or "-"
}
HarnessFacts carries facts about the harness, deliveries and breaks: every delivery count is of the --since window (docs/SPEC-FRIEND.md "Check").
func (HarnessFacts) Line ¶
func (hf HarnessFacts) Line() string
Line renders the CHECK HARNESS line.
type HarnessSettings ¶
type HarnessSettings struct {
Harness, Friend, Dir string
Home string // the friend's home: ~ of every default below
StateDir string // the daemon's state directory; DefaultStateDir when empty (grok's default wake file)
Wake string // grok: the wake file the session's monitor tails; <state>/<friend>.wake when empty
ConfigDir string // claude: CLAUDE_CONFIG_DIR, the friend's own config directory
Model string // opencode: the model, provider/model; empty leaves it alone
CodexHome string // codex: CODEX_HOME; Home/.codex when empty
DSHHome string // dsh: DSH_HOME; Home/.dsh when empty
FS SettingsFS
}
HarnessSettings is what install writes for one friend's harness and what check compares: the friend's directory and, per harness, the flags that name a setting. The writer of each harness is one small function (settings_<harness>.go).
func (HarnessSettings) Check ¶
func (h HarnessSettings) Check() ([]Setting, error)
Check is every setting with what is there now; nothing is written.
func (HarnessSettings) Plan ¶
func (h HarnessSettings) Plan() ([]Setting, error)
Plan is what Write would write, with Write's refusals; nothing is written (install --dry-run).
func (HarnessSettings) WakePath ¶
func (h HarnessSettings) WakePath() string
WakePath is the wake file these settings name for grok.
func (HarnessSettings) Write ¶
func (h HarnessSettings) Write() ([]Setting, error)
Write makes every setting what install wants and answers the ones it wrote. Every path is checked first: a symlink, the wrong kind, or a missing path install does not make is refused (ErrNotRealDir) and nothing is written. Each write is read back; a setting that still differs is an error naming it.
type HeldAnswer ¶
HeldAnswer is the server's answer to friend cards <friend>: every card on her row, the ready ones dealt behind her working ones and her reads among them.
type HeldCard ¶
type HeldCard struct {
Card string `json:"card"`
Job string `json:"job"`
Col string `json:"col"`
Kind string `json:"kind,omitempty"`
Branch string `json:"branch,omitempty"`
Tier string `json:"tier,omitempty"`
Stream string `json:"stream,omitempty"`
Attempt int `json:"attempt,omitempty"`
Gen int `json:"gen,omitempty"`
Epoch uint64 `json:"epoch"`
Repo string `json:"repo,omitempty"`
Base string `json:"base,omitempty"`
Brief string `json:"brief"`
// Lane is the lane of her row the server says holds the card (take --lane), 0 for none.
Lane int `json:"lane,omitempty"`
Why string `json:"-"`
}
HeldCard is one card on the friend's row as the server answers it: the card, the job it is delivered as (inbox/<job>), its column (ready or working) and its BRIEF.md whole, with its packet (its kind, work or read, the branch it is pushed to, its tier, attempt, generation and epoch, and the repository and base its checkout is staged from: PacketOf reads the brief's REPO: and BASE: lines when the server sends neither); Why is, for a card the answer sends no brief for, why not (the worker view's, ParseView).
type HookRecord ¶ added in v1.3.16
type HookRecord struct {
State string // none, armed, proven, unhooked, ...; "" when not read
Since time.Time // when it was hooked, or unhooked; zero when never
LastAnswer time.Time // when her model last answered a challenge; zero is never
Misses int // challenges in a row left unanswered
Down string // why it reads down whatever its state (unhooked, no server, no answer), "" when it stands
ReadError string // why the record could not be read; "" when it was
}
HookRecord is a friend's nova-hook record as status and check read it (nova-tools hook.Status): its state, since when, the last answer to a challenge, the challenges missed in a row, and why it reads down.
func (HookRecord) Up ¶ added in v1.3.16
func (h HookRecord) Up() bool
Up says the record proves her there: proven, and nothing reads it down.
type HostRefused ¶
type HostRefused struct{ Session string }
HostRefused is host's refusal: the session runs already.
func (HostRefused) Error ¶
func (h HostRefused) Error() string
type HostResult ¶
type HostResult struct {
Session, Attach, Line string
}
HostResult is what host started (or, on a dry run, would start).
type HostSpec ¶
HostSpec is one host: the friend, its directory, the launch command and whether to only print.
type Hosted ¶
type Hosted struct {
Session string `json:"session"`
Harness string `json:"harness"`
Prompt string `json:"prompt"`
}
Hosted is what host saves so run and install need no flag: the tmux session, the harness it hosts and the idle prompt pattern (source text).
type InboxCounts ¶
type InboxCounts struct {
Held, Inbox, Missing int
}
InboxCounts is what one reconcile found: the cards held on her row, the sprint jobs in her inbox, and the held cards whose BRIEF.md is still not there after it.
func SyncInbox ¶
func SyncInbox(dir string, row Row, keep map[string]bool, asked, now time.Time, record func(string)) (InboxCounts, error)
SyncInbox reconciles her inbox under dir with row, the cards on her row as the server answered an ask begun at asked: each held card's inbox/<job>/BRIEF.md is written when it is not there (written whole, never over a file there; a rework's with its fix first, ReworkedBrief), and each sprint job in the inbox that no held card names, that no lane runs (keep), whose kind the answer covers (row.Reads), and whose BRIEF.md was written before asked, is moved to inbox/retired/. A brief written since the ask began is friend sync's for a card dealt after the server answered, and the next pass decides it (without this, the TLA+ model InboxReconcile retires a held card's brief: docs/SPEC-FRIEND.md). asked is the wall clock, as the file times are; zero retires none. record gets one line per write and per retirement, and one per held card it could not write. The counts are what the inbox holds after the pass.
type LaneEnd ¶
type LaneEnd struct {
Exit int
Err string // the harness's error, when the run did not end with an exit
Wall time.Duration // the run's wall, its start to its end
Cap string // the cap that stopped it, when one did
Rejected string // a permission the harness refused
Turns int // the turns the card had in the lane
Restart time.Time // not zero: the run was found gone by a daemon starting up at this time
Started time.Time // when the lane began the card
NoReport bool // the run wrote RESULT.md and no REPORT.md
// Capped is the card's wall cap by its tier when the lane ended the card at it
// (lane_cap.go), Tier that tier, Overrun the card's wall past the cap at its end, and
// Tail the last CapTailLines lines of the lane's output.
Capped time.Duration
Tier string
Overrun time.Duration
Tail string
}
LaneEnd is how a card's last run in a lane ended, as its finish says it.
type LaneFaultWatch ¶ added in v1.2.14
type LaneFaultWatch struct {
// contains filtered or unexported fields
}
LaneFaultWatch counts one lane's provider refusals: the LaneFaultAlike-th of the same refusal is the fault, with the first refusal line; a different line starts the count again. The zero value is ready.
func (*LaneFaultWatch) Clear ¶ added in v1.2.14
func (f *LaneFaultWatch) Clear()
Clear clears the lane fault, the release: the lane may take cards again and a fresh run of alike refusals is counted anew. The loop calls it on a restart and when the fault file a person removed is gone (docs/SPEC-FRIEND.md, the lanes).
func (*LaneFaultWatch) Faulted ¶ added in v1.2.14
func (f *LaneFaultWatch) Faulted() bool
Faulted answers whether the lane is faulted: after the LaneFaultAlike-th identical provider refusal the lane holds its card; it is released only by a restart or a clear (docs/SPEC-FRIEND.md, the lanes).
func (*LaneFaultWatch) Observe ¶ added in v1.2.14
func (f *LaneFaultWatch) Observe(line string) (string, bool)
Observe adds one provider-refusal line and answers the lane fault on the LaneFaultAlike-th identical one, once per run of alike refusals.
func (*LaneFaultWatch) Report ¶ added in v1.2.14
func (f *LaneFaultWatch) Report() string
Report is the lane-fault report (lane-fault=<n> refusal="<first line>") the lane last faulted on, for the daemon's beat; "" when the lane is not faulted (docs/SPEC-FRIEND.md, the lanes).
func (*LaneFaultWatch) Set ¶ added in v1.2.14
func (f *LaneFaultWatch) Set(report string)
Set marks the lane faulted with report as given, for a detector that counted its own bound (the limit detector's lanes failing alike): the same record a provider refusal's Observe writes, never counted again.
type LaneGovernor ¶
type LaneGovernor struct {
Rand func() float64 // pseudo-random in [0, 1); nil is math/rand/v2.Float64 (docs/SPEC-FRIEND.md #rate-limit-backs-off-not-down.w1)
Now func() time.Time // clock; nil is time.Now
// contains filtered or unexported fields
}
LaneGovernor is the lanes' live cap under rate limits, and their hold when out of funds. Its zero value is the row's width, never paused. RateLimit lowers the cap by a quarter (at least one lane, never below one) and pauses new turns for the backoff, which doubles from RateBackoffFirst to RateBackoffMax; turns that started before the last lowering are the same episode and change nothing. Step resumes after the pause and raises the cap one lane per clean RateRaiseEvery, measured: a turn ended clean in it (Clean). Back at the row's width the backoff starts over. Each change is one line.
func (*LaneGovernor) Cap ¶
func (g *LaneGovernor) Cap(width int) int
Cap is the live cap at width: the row's width unless a rate limit has lowered it, never above the row.
func (*LaneGovernor) Clean ¶
func (g *LaneGovernor) Clean(now time.Time)
Clean is a lane turn that ended at now without a rate limit: the measurement a raise waits for.
func (*LaneGovernor) Held ¶
func (g *LaneGovernor) Held() string
Held is why the lanes are held, out of funds; "" when they are not.
func (*LaneGovernor) Hold ¶
func (g *LaneGovernor) Hold(reason string) bool
Hold is out of funds: the lanes start nothing more until the daemon restarts. It answers whether this is the first hold, the one to say.
func (*LaneGovernor) PauseUntil ¶
PauseUntil is a usage limit with its reset: no new turn or open before until, jittered by adding up to 20% of the remaining wait, never earlier than the reported reset itself (docs/SPEC-FRIEND.md #rate-limit-backs-off-not-down.w1). The cap is left alone. It answers the line that says it, empty when the pause already reaches until.
func (*LaneGovernor) Paused ¶
func (g *LaneGovernor) Paused(now time.Time) bool
Paused says whether no new turn or open may start now: a backoff under way, or out of funds.
func (*LaneGovernor) RateLimit ¶
func (g *LaneGovernor) RateLimit(now, started time.Time, width int, reason string) (line string, judge bool)
RateLimit is a rate limit met at now by a turn (or open) started at started, at the row's width: the line that says the change, and whether it is a judgment (the RateJudgeAfter-th lowering within RateJudgeWithin). A turn started before the last lowering is the same episode: no line. Every lane resume after a rate limit is spread by a jitter of +/-20% of the pause (docs/SPEC-FRIEND.md #rate-limit-backs-off-not-down.w1).
func (*LaneGovernor) Release ¶
func (g *LaneGovernor) Release()
Release lifts a hold: a person brought the lanes up (the pause marker is gone).
func (*LaneGovernor) Step ¶
func (g *LaneGovernor) Step(now time.Time, width int) []string
Step is the governor at now and the row's width: the pause's end said once, and a clean RateRaiseEvery with a clean turn in it raising the cap one lane; back at the width, the cap is the row's again and the backoff starts over. It answers the lines of what changed.
type LaneHarness ¶
type LaneHarness interface {
Deliverer
// OpenSession starts a new session of the friend with seed as its first
// turn, and answers the new session's id.
OpenSession(ctx context.Context, seed string) (session string, err error)
// DeliverTo pushes text into session as one turn and blocks until it
// ends: its exit, and a permission the harness refused without asking,
// read from the turn's output (empty when none). A rate limit is
// RateLimited and out of funds OutOfFunds (ProviderLimit); a provider's
// refusal is ProviderRefused, as Deliver answers it.
DeliverTo(ctx context.Context, session, text string) (LaneTurn, error)
}
LaneHarness is a Deliverer that can open a session of the friend and deliver into a session it names: what a one-shot lane needs, each lane its own session in the same harness and directory (docs/SPEC-FRIEND.md, one-shot lanes; the owner, 2026-10-04: "so [she] can still be wide, it's just 8 [of her]"). OpenCode is one.
type LaneHold ¶ added in v1.2.7
LaneHold is the server's answer to a lane's ask: the lane, the epoch the server holds, and the card the lane holds there (Card "" for none) at its generation, its kind (work or read) and its job (<id>~<epoch>, .g<gen> from the second generation).
func ParseLaneHold ¶ added in v1.2.7
ParseLaneHold reads the server's LANE line for member's lane n out of an ask's answer. An answer with no such line, or one naming another member or lane, is a refusal: the lane runs nothing (the fault of 2026-10-10 21:42Z: a take answered OK and the lane said "took" while the server still showed the card ready). A line for this lane that holds a card but lacks its generation, kind or job is Unparseable, naming the field (the fault of 2026-10-14 03:51Z: rank= between holds= and kind= left a reader-only friend's lanes refusing every read card's line, once every TakeRetry, all night).
type LaneJob ¶
type LaneJob struct {
Dir string // <friend dir>/jobs/<job>: the harness's working directory
Card Card // Brief and Outbox absolute
Brief string // the brief's text, inline in the prompt; "" when it is not read yet
}
LaneJob is a card as its lane hands it to the harness: the job directory the harness runs in, the card with its brief and outbox absolute, and the brief's text, which the prompt carries.
func LaneJobOf ¶
LaneJobOf is card c of the friend's working directory dir as its lane hands it: every path made absolute by abs (filepath.Abs in the daemon), the job directory dir/jobs/<job>. A path abs cannot make absolute is refused: the error is one REFUSED line naming the path, and the lane does not start.
type LaneMark ¶
LaneMark is a job's lane mark as read: Who runs it (Ended false) or ended it (Ended true), and At, when a running mark was last refreshed.
func ReadLaneMark ¶
ReadLaneMark is the job's lane mark; found is false when there is none or it says neither word.
type LaneRules ¶
type LaneRules struct {
Tiers []string // row_tiers=flash,pro: the tiers she works; a dealt card of another tier is taken back; none: every tier
Streams []string // row_streams=security*,fp-sec*: patterns a card's stream or id must match; none: every card
TokenCap int64 // row_token_cap=<n>: tokens one card may spend, all kinds; 0 none
LoadMax float64 // row_load_max=<load>: above this one-minute load the lanes are held to LoadWidth; 0 none
LoadWidth int // row_load_width=<n>: lanes while the load is above LoadMax; DefaultLoadWidth when unset
PauseOn string // row_pause_on=funds|any: funds (the default) holds only for out of funds; any holds for a rate limit too
RefuseGo bool // row_refuse_go=1: the lane's PATH carries go and gofmt that refuse
}
LaneRules is what a friend's row says about which cards her lanes take and how hard they run: the zero value is no filter, no cap, no load rule, and a rate limit that backs off.
func LaneRulesOf ¶
LaneRulesOf reads the lane rules off the friend's beat answer; a word it does not know is ignored and a value that does not parse leaves the field unset.
func (LaneRules) Judge ¶
func (r LaneRules) Judge(id, stream, tier string) (LaneVerdict, string)
Judge is the card filter: a card of a tier outside Tiers (an unknown tier is outside) is taken back; a card whose stream and id match none of Streams is skipped; any other runs. The reason is a sentence for the record and for friend take.
func (LaneRules) LaneWidthUnderLoad ¶
LaneWidthUnderLoad is how many lanes may start with the machine's one-minute load at load: the row's width, held to LoadWidth while the load is above the row's LoadMax (a width at or below LoadWidth is never raised). held says it was lowered.
func (LaneRules) Over ¶
Over is r with every field row sets in place of its own: the flags give the defaults and the friend row, as her beat answers it, wins.
func (LaneRules) OverTokenCap ¶
OverTokenCap says a card has spent its cap; a rule with no cap is never over.
func (LaneRules) ProviderStop ¶
ProviderStop is the provider failure that stops every lane, and the message to hold the friend down with, as the provider said it: out of funds (402) always; a rate limit (429) only when the row says pause_on=any (otherwise it backs off, rate-limit-backs-off-not-down).
type LaneState ¶
type LaneState struct {
Sessions map[int]string `json:"sessions"`
Epoch uint64 `json:"epoch,omitempty"`
GivenUp []string `json:"given_up,omitempty"`
Started map[string]Started `json:"started,omitempty"`
// StopReturns is every card the machine's stop took out of a lane and the stop-return
// owed or taken for it (stop.go): the next loop pass sends what is owed first.
StopReturns []StopReturn `json:"stop_returns,omitempty"`
}
LaneState is the running daemon's in-memory lane connections and unfinished outcomes. It never decides what a lane holds: the sprint server owns those records (tla/FriendLaneClient.tla). Sessions are reused during this daemon's life; an epoch change forgets them so a stale session cannot cross a clear (epoch.go). No lanes.json file restores this cache after restart.
type LaneTokens ¶
type LaneTokens struct {
cardcost.Tokens
USD string // opencode's own reported cost, a decimal; "" unknown
Sessions int
}
LaneTokens is what a session and its children spent, as opencode's own database says it, and what opencode itself priced it at.
func TokensFromOpenCode ¶
TokensFromOpenCode reads a session's tokens (and its children's) from opencode's own database through the sqlite3 CLI, read only (the tree has no sqlite driver).
func TokensFromOpenCodeIn ¶ added in v1.2.7
func TokensFromOpenCodeIn(ctx context.Context, run Exec, dbs []string, session string) (LaneTokens, error)
TokensFromOpenCodeIn reads a session's tokens from the first of dbs that holds it (a row for the session or a child). A lane's opencode runs inside the wall with the wall's HOME (the friend's config directory, else her working directory: sandbox.LaneProfile), so it writes its sessions under that HOME, not the daemon's; a batch turn writes under the daemon's (--db). A session in none of them is ErrSessionInNoDB, naming each database and why, never the all-zero tokens the sums give for no row (2026-10-10: every walled opencode lane read zero tokens from the daemon's database, and its runs were judged empty).
func TokensOf ¶
func TokensOf(out string) (LaneTokens, error)
TokensOf reads the one row TokensSQL prints (sqlite3's default, | between columns).
func (LaneTokens) Sub ¶
func (t LaneTokens) Sub(base LaneTokens) LaneTokens
Sub is the tokens spent after base: a lane's session serves many cards, so a card's are the session's totals at its end less its totals at its start.
type LaneTurn ¶
type LaneTurn struct {
Exit int
Rejected string // the line of the output where the harness refused a permission, if any
// Windows is the subscription windows' use the harness reported in the turn
// (a Claude Code run's rate_limit_event lines, ReadRateLimitEvents); nil when
// it reported none. The lanes are paced by it (pacing.go).
Windows []WindowUse
// FirstError is the first line of the turn's output that says an error
// (HarnessFirstError), "" when none does: a run that exits 0 with no report
// is a harness fault said with it (lanes.go, faultTurn).
FirstError string
}
LaneTurn is how one lane turn ended.
type LaneVerdict ¶
type LaneVerdict int
LaneVerdict is what the rules say of a dealt card.
const ( LaneRun LaneVerdict = iota // the lanes may run it LaneSkip // not hers to run: left on her row, never started LaneTake // outside her tiers: taken back for the dealer (friend take) )
type Launchctl ¶
Launchctl runs launchctl with args and answers what it printed; the installer passes the real one, a test its own.
type Limit ¶
Limit is what a command's output says of the harness's limit: Limited, until when and why; Usage when the output measured it; Overage when the harness is spending paid overage (a limit only if the owner does not allow it, Limits.AllowOverage).
func ReadLimit ¶
ReadLimit reads a command's output at now for the harness's limit: the last rate_limit_event anywhere in it (Claude Code), else a limit line in its tail with the reset beside it (a clock time, today or else tomorrow in now's zone or the zone it names, on the date it names; "in N hours"; an epoch after "limit reached|"; resetOfText). found is whether the output said anything of the limit at all. A provider's transient rate_limit_error is no limit (ProviderRefusal passes it).
type LimitHit ¶
LimitHit is a limit read from a failed turn's output: its kind, the reset (the text's own when Named, else now plus the rest), and the line.
func ParseLimit ¶
ParseLimit reads the tail of a failed turn's output (the last LimitTail bytes: a harness says it last) for harness's own wording of a usage limit or an empty balance: the kind, and the reset when the line names one, else now plus rest (DefaultLimitWait when rest is zero). A harness it has no words for, or a text it does not recognise, is not a limit. A reset that is not after now is no reset. The newest matching line wins.
type Limits ¶
type Limits struct {
Now func() time.Time
Down func(until time.Time, reason string)
Up func()
// Notice is the single coordinator message for a detected limit episode.
// unread asks it to include the unread-reset judgment in that message.
// A funds refusal delegates its notification to Funds when configured.
Notice func(until time.Time, reason string, unread bool)
// Unread is the judgment when a limit's text names no reset this reads: the
// friend is held for Rest and the text goes to the coordinator, once until
// a turn runs clean, so the reset is set by a person (friend down --until)
// and not guessed again each Rest (usage-limit-reset-read-from-the-message-b.w1).
Unread func(text string)
// Funds, when set, is handed a failed turn's own wording of a provider
// refusal for funds with no reset to wake at (an insufficient balance, a
// 402): the reason (ratelimit.ProviderLimit's rule, one layer up). The
// daemon wires it to the spend cap, so the refusal stops the turns at once
// with the spend-cap judgment instead of the limit's own Rest retry
// (docs/SPEC-FRIEND.md, spend caps).
Funds func(reason string)
// Harness is the harness whose own wording a failed turn is read in
// (ParseLimit), and Rest how long it is down when the text names no
// reset (DefaultLimitWait when zero): --limit-rest.
Harness string
Rest time.Duration
// AllowOverage is the owner's word that this friend may spend paid
// overage; without it a harness on overage reads down.
AllowOverage bool
// Pacing is the row's pacing (the fraction of each subscription window the
// sprint may spend), read at each batch turn; nil, or out of (0, 1], is
// DefaultPacing. Every output's rate_limit_event feeds the pacer, and a batch
// turn while a window is at the pacing is Deferred until it resets
// (pacing.go).
Pacing func() float64
// contains filtered or unexported fields
}
Limits is one friend's harness limit: up, or down until a reset, which lapses at the reset (tla/FriendLimit.tla is owed). Watch reads every command's output for it; Gate holds turns while it is down. The daemon pushes nothing into her session to wake it: the next lane turn after the reset is the test, and a turn that hits the limit again is down again. The hooks say the change to the sprint: Down once per limit with its reset (friend down --until), Up when the reset passed.
func (*Limits) Beat ¶
Beat is beat held back while the harness is at its limit: no beat goes to the sprint server, so her row reads down, from the turn that hit the limit until its reset.
func (*Limits) BeatOrDown ¶
func (l *Limits) BeatOrDown(beat func(ctx context.Context) error, down func(ctx context.Context, until time.Time, reason string) error) func(ctx context.Context) error
BeatOrDown is beat while the harness answers, and down while it is at its limit (limits-mean-down-w-r5.w1~15): her beat says down with the until and the reason (nova-sprint friend beat --until --reason), so her row reads down and why rather than going silent, until the reset. A nil down holds the beat back as Beat does; a down the sprint server refuses is an error, and her row reads down by the lapse as before.
func (*Limits) Gate ¶
Gate is d held by the limit: a delivery while the harness is down is Deferred without running it; a turn that hits a limit is Deferred too. A passive d is d. A LaneHarness stays one (gatedLanes): its batch Deliver is held, and its lanes are not. docs/SPEC-FRIEND.md, silent-turn stop and refusals
func (*Limits) Limited ¶
Limited is the limit now: until when and why, and whether there is one. A limit whose reset has passed lapses here, said once by Up.
func (*Limits) Refuse ¶
Refuse is a credit or quota refusal a caller read where this harness's own wording parse (ParseLimit) and the limit tail found none: the daemon's per-harness table in cmd/nova-friend/limit.go reads a lane's evidence and hands the hit here (docs/SPEC-FRIEND.md, every harness's credit and quota refusal). It takes the same state and hooks see takes for a limit a harness's own wording names: the friend is down until the refusal's until, her turns and beats are held, Down says it to the sprint once, and status reads session=limited limit_kind=kind limit_until=until. A refusal equal to the one that already holds her is not a second down.
type LogFacts ¶
type LogFacts struct {
Last string // RFC3339 of the newest delivery in the window, or "-"
LastExit string // its exit, or "-"
FailedOfLast20 int // failures among the newest 20 deliveries in the window
Deferred int // deferrals in the window
Delivered int // deliveries in the window
Failed int // of those, the ones that exited non-zero
}
LogFacts is what the daemon's log says inside a window.
type NoReport ¶
type NoReport struct {
Run string // the harness as the run names it, "claude -p"
Exit int
Outbox string
Lacks []string // the files the outbox lacks
}
NoReport is a card runner's run that ended with its outbox holding neither REPORT.md nor RESULT.md (the Claude lane's), its words as the run says them.
type NotServed ¶
type NotServed struct{ Why string }
NotServed is a sprint server that refused friend cards (Refused) where the daemon has no worker view to fall back on; it is said once a ServedEvery, each time the verb is asked again.
type NotStageable ¶
type NotStageable struct {
Repo, Card, Why, Remedy string
Job string // the job it was staging, when there was one
}
NotStageable is a stage that waits on a person: her account cannot reach the repository (Card empty: every card on it waits), or the card's packet names what is not there. It is one judgment to the coordinator, its Remedy what clears it.
func (*NotStageable) Error ¶
func (n *NotStageable) Error() string
type Notices ¶ added in v1.3.16
type Notices struct {
Bus *bus.Bus
To func(context.Context) (string, error)
Record func(string)
Now func() time.Time // nil uses the monotonic process clock
Wait func(context.Context) bool // nil waits one second; false means cancelled
// contains filtered or unexported fields
}
Notices retains coordinator messages until the bus returns a receipt. Each message keeps its token, including after a lost response, so retry cannot duplicate a message. The queue is volatile: a shutdown reports its unsent count. A full queue holds its caller until delivery frees space or shutdown cancels the call; the independent metadata beat continues. Libraries considered: bus.Message.Token supplies idempotency; sync.Mutex serializes the lane-output callbacks and the daemon's retry step.
func (*Notices) Flush ¶ added in v1.3.16
Flush retries each pending message (FriendNotices.Send). A refused message cannot block independent episodes. Retries stop before the bus token can expire; an unknown old receipt stays visible for manual resolution. The target is fixed before the first send, so a retry cannot change a token's arguments.
type OpenCode ¶
type OpenCode struct {
Dir, Session string
Run Exec
Program string // "opencode" when empty
Out io.Writer // where the turn's output goes, when set: the daemon's record
// Allow is every other path the friend's directory is reached by (a
// symlink in the home directory): with Dir and its real path, allowed in
// the project config before a turn (AllowDirs), so a headless run never
// auto-rejects a tool call there. Nil: the config is left alone.
Allow []string
// Standalone passes --standalone to every run: opencode 2.0.25 (the
// background service, 2026-10-09) makes `opencode run` attach to a shared
// background service (`opencode serve --service`, started once, detached)
// instead of a private server, so a sealed provider key (nova-secrets exec)
// reaches no provider ("Incorrect API key provided"); --standalone keeps the
// run in this process, with this environment. CheckRun sets it when the
// installed run lists the flag, so an older opencode is never handed it.
Standalone bool
}
OpenCode delivers through `opencode run --session <id> <text>` run with Dir as its working directory (the process's, never a flag: opencode v2.0.20's run has no --dir, and every delivery that passed one exited 1, "Unrecognized flag: --dir", 2026-10-06), which blocks for the whole turn; without a session named, the newest session whose directory is Dir, from `opencode session list --format json`, so a friend who starts a fresh session is still reached. CheckRun, at the daemon's start, refuses an opencode whose run lacks a flag the adapter passes.
func (*OpenCode) CheckRun ¶
CheckRun reads the installed opencode once, at the daemon's start: its version (`opencode --version`) and its run verb's flags (`opencode run --help`), and is a one-line refusal naming the version when the help lacks a flag the adapter passes (OpenCodeRunFlags), so the next change of the CLI is a named refusal and not a silent exit 1 on every delivery (the finding of 2026-10-06: --dir, gone from run in v2.0.20). A help that lists no flag at all, or that cannot be read, cannot tell, and is nil: the deliveries say what they meet.
func (*OpenCode) DeliverFresh ¶ added in v1.2.7
DeliverFresh is one fresh turn of the friend's opencode, a session of its own that no listing is read for and none is grown: `opencode run <text>` in Dir with no --session. It is the daemon's presence check for a one-shot friend (docs/SPEC-FRIEND.md, presence: a tiny fresh turn per check; FriendPresence.tla, OneShotNeverDownBySession), so a session that is full or missing is never the reason she is down. Its output is read as a lane turn's is.
func (*OpenCode) DeliverTo ¶
DeliverTo is one card's turn in a lane's session: `opencode run --session <id> <text>` in Dir, its output read for a refused permission, and its tail for a rate limit or out of funds (ProviderLimit, whatever the exit: the lanes heed it only when the card has no RESULT.md) before a provider's refusal of the session.
A lane's turn runs in the card's job directory, the one its context carries (WithLaneDir), so a path the model reads relative is read inside the job; with none it runs in Dir.
func (*OpenCode) OpenSession ¶
OpenSession runs the seed as the first turn of a new session in Dir (`opencode run <seed>` in Dir, no --session) and answers the session that appeared in the listing of Dir, the newest the listing before it did not hold. The lanes' directories are allowed in the project config first.
type OpenCodePriced ¶
type OpenCodePriced struct {
*OpenCode
// Friend is the friend's name, as a capped card's report says it.
Friend string
// TokenCap is the friend row's per-card token cap as the daemon last read
// it (TokenCapOf; 0 none); nil is DefaultTokenCap.
TokenCap func() int64
// Tick is the clock a running turn's usage is polled on (every TokenPoll);
// a real ticker when nil.
Tick func(time.Duration) (<-chan time.Time, func())
// contains filtered or unexported fields
}
OpenCodePriced is an OpenCode friend's lanes with every run priced from opencode's own session record (docs/SPEC-FRIEND.md, the Claude lanes, the OpenCode lane): after each turn `opencode export <session>` is read, and the run's cost is what the session's assistant messages gained since the last read (each message's cost is opencode's own figure), said on the record as one line per run. The daemon wraps the friend's OpenCode in it; a bare OpenCode runs no export. A card's turn is capped by its tokens, read from the same record (tokencap.go).
func (*OpenCodePriced) DeliverTo ¶
DeliverTo is OpenCode's under the card's token cap (deliverCapped), then the run priced, whatever it answered.
func (*OpenCodePriced) OpenSession ¶
OpenSession is OpenCode's, then the first run priced.
func (*OpenCodePriced) SpendLine ¶
func (p *OpenCodePriced) SpendLine() string
SpendLine is every run's cost so far and, when the last run stopped at a usage limit, its reset: `spend: harness=opencode runs=<n> cost_usd=<sum> [limited_until=<t>]`. An API friend has no five-hour or weekly window to read; her limit is what the run said (Spender).
func (*OpenCodePriced) Spent ¶
func (p *OpenCodePriced) Spent() float64
Spent is the cost of every run priced so far, in US dollars.
type OutOfFunds ¶
type OutOfFunds struct{ Session, Reason string }
OutOfFunds is a lane's answer when the provider refused for want of funds or credit (a 402, insufficient balance): the lanes hold until the daemon restarts, and the coordinator is told once (LaneGovernor.Hold).
func (OutOfFunds) Error ¶
func (o OutOfFunds) Error() string
type Pacer ¶
type Pacer struct {
// contains filtered or unexported fields
}
Pacer is a friend's lanes paced by her subscription windows. Its zero value knows no window and paces nothing.
func (*Pacer) Observe ¶
Observe takes a turn's report: each window replaces its last report. A report with no utilization (under the harness's warning threshold) keeps the use last read for the same reset, since use does not fall within a window.
func (*Pacer) Step ¶
Step is the pacer at now: the effective width, the line that says a change of it (empty when none), and whether this step owes the coordinator the judgment (paced below half her row, said once until she is back at half or more).
func (*Pacer) Use ¶
Use is the live windows' use as the table says it: "5h 62% 7d 31%", empty when none is live.
func (*Pacer) Width ¶
Width is the lanes' effective width at now for the row's width and the pacing fraction, and the window that decided it ("" when none did). A window at or past the pacing, or that the harness rejected, allows none until it resets; below it, the width is the row's scaled by the share of the paced budget left, rounded up: the lanes thin as the window fills.
type Packet ¶
Packet is what a held work card says about its checkout: the repository (owner/name), the base it starts at (a branch, a tag or a full sha) and its pin (BaseSha, the commit a `BASE: <ref>@<sha40>` names; "" when unpinned), the branch its work is pushed to, and its attempt.
type Pronouns ¶ added in v1.2.16
type Pronouns string
Pronouns are the pronouns a friend goes by: the friend row's `pronouns` setting (pkg/config/kind.go, "friend"), one of the three sets below. Pronouns are read, never inferred: a friend whose pronouns are not stated goes by they/them, and no text a daemon writes calls a friend "it". The zero value is they/them, so a Daemon or a text built without them is already right.
const ( SheHer Pronouns = "she/her" HeHim Pronouns = "he/him" TheyThem Pronouns = "they/them" DefaultPronouns = TheyThem )
The pronoun sets a friend row may name, and the default a row without one has. pkg/config's FriendPronounSets lists the same three (TestPronounSetsMatchConfig holds the two lists equal).
func ParsePronouns ¶ added in v1.2.16
ParsePronouns is the set a row's or a flag's text names: "" is the default, the three sets are themselves, and anything else is false with the default, never a guess.
func RowPronouns ¶ added in v1.2.16
RowPronouns reads the friend row's pronouns off the beat's answer (row_pronouns=she/her, beside row_mode and row_width); ok is false when the answer carries none or names a set that is not one of the three.
func (Pronouns) Say ¶ added in v1.2.16
Say is the one helper every text about a friend renders its pronouns with: s with {they}, {them}, {their}, {theirs} and {themself} (and {They}, {Them}, {Their}, {Theirs}, {Themself} at the head of a sentence) replaced by the forms of p. A text is written once in terms of those words, and a verb that would change with the subject ("she beats", "they beat") is not written after one: the text names the friend, or has the possessive ("{their} beat says down").
type PronounsRef ¶ added in v1.2.16
type PronounsRef struct {
// contains filtered or unexported fields
}
PronounsRef holds a daemon's pronouns where several goroutines read them and a beat's answer may change them: the flag's (or the plist's) first, the row's once the beat names them. A nil ref and a ref never set are they/them.
func NewPronounsRef ¶ added in v1.2.16
func NewPronounsRef(p Pronouns) *PronounsRef
NewPronounsRef is a ref holding p.
func (*PronounsRef) Get ¶ added in v1.2.16
func (r *PronounsRef) Get() Pronouns
Get is the pronouns held, they/them when none were set.
func (*PronounsRef) Set ¶ added in v1.2.16
func (r *PronounsRef) Set(p Pronouns)
Set replaces the pronouns held.
type ProviderRefused ¶
type ProviderRefused struct{ Session, Reason string }
ProviderRefused is a Deliverer's answer when the turn reached the session's model provider and the provider refused the request itself (an invalid_request_error, an authentication_error): the session is at fault, not the message. The daemon counts it toward nothing a message owns; the same refusal on BrokenAfter turns in a row marks the session broken (the finding of 2026-10-04: a friend's session refused every turn for two hours and nothing said so).
func (ProviderRefused) Error ¶
func (p ProviderRefused) Error() string
type Queue ¶
type Queue struct {
Tasks []Task `json:"tasks"`
}
Queue is the friend's queue file: one record per task; the coordinator writes assignments into it, the session marks them working or done.
type RateLimited ¶
type RateLimited struct{ Session, Reason string }
RateLimited is a lane's answer when the provider rate-limited the turn (a 429, "rate limit reached", "too many requests", "input token limit exceeded"): the turn's card stays in hand, counted toward nothing, and the lanes back off (LaneGovernor.RateLimit).
func (RateLimited) Error ¶
func (r RateLimited) Error() string
type ReadHarness ¶
ReadHarness is a harness that runs one read as a one-shot of its own: a new session with the prompt as its only turn, on model ("" is the harness's own), blocking until it ends. A harness without it runs the prompt as the seed of a new lane session (LaneHarness).
type ReadPacket ¶
type ReadPacket struct {
Tier string `json:"tier"`
Head string `json:"head"`
WorkBranch string `json:"work_branch"`
Attempt int `json:"attempt"`
Brief string `json:"brief"`
Report string `json:"report"`
}
ReadPacket is what the reader queue says of one asked read.
type Refused ¶
type Refused struct{ Why string }
Refused is the sprint server's refusal of a verb it answered (a non-zero exit), as against a server that did not answer: a refused friend cards is a server that does not serve it yet.
type RoutePrice ¶
RoutePrice is the store's route row for the friend's exact provider/model: its name and price sheet; Found is false when there is none.
func RoutePriceOf ¶
func RoutePriceOf(routesJSON, provider, model string) RoutePrice
RoutePriceOf finds the route row for provider/model in the sprint's `routes --json` answer: the first object anywhere in it that has a prices object and this provider and model. A route that does not say reasoning_as_output bills reasoning as output.
type Row ¶
type Row struct {
Cards []HeldCard
Reads bool
From string
Note string
Epoch uint64
// Refused is why the server refused friend cards this pass (a refusal it
// answered, Refused); "" when it answered, or was not asked this pass. The
// daemon counts these per verb and raises the third consecutive one
// (inboxStep; docs/SPEC-FRIEND.md, "A refused verb").
Refused string
}
Row is one answer of what is on her row: the cards, whether her reads are among them (a job no card names is retired only when the answer covers its kind: the worker view lists her work cards and none of her reads), where the answer came from, and Note, a line the daemon says with it ("" for none: the server's refusal of friend cards, once a ServedEvery). Epoch is the sprint's epoch as the answer said it: the highest on her row, every card on her row being dealt at the sprint's current epoch, and on a view answer the view's own; zero when the answer names no card and the epoch is unknown (an empty row: nothing is retired on it, and the next deal names the new one).
type SessionRefused ¶
type SessionRefused struct{ Session, Reason, Detail, Remedy string }
SessionRefused means the harness cannot take the turn, whatever its exit code. The delivery check and reach surface its reason and remedy.
func DSHRefusal ¶
func DSHRefusal(session, dir, out string) (SessionRefused, bool)
DSHRefusal reads one headless turn's output, whatever its exit code, for an answer that the session cannot take a turn at all: the agent preset refusal, or MISSING_CREDENTIAL. Either is a failed delivery (SessionRefused), never a delivered turn: the finding of 2026-10-06, Zhi's session under preset "minimal" printed the refusal and exited 0, and four hours of messages counted as delivered while her row read up. The reason is fixed text; the output itself, which may name a credential, is never carried.
func (SessionRefused) As ¶
func (s SessionRefused) As(target any) bool
As answers a SessionRefused as the Deferred it also is: the message stays pending, and a session it cannot drive carries its Remedy.
func (SessionRefused) Error ¶
func (s SessionRefused) Error() string
type Setting ¶
type Setting struct {
Harness, File, Name, Want, Have string
}
Setting is one setting a harness needs: the file (or directory) it lives in, its name, the value install writes and the value there now. A setting whose Have is not its Want has drifted.
type SettingsFS ¶
type SettingsFS interface {
Lstat(path string) (Entry, error)
ReadFile(path string) ([]byte, error)
WriteFile(path string, data []byte, perm fs.FileMode) error // whole, atomically
MkdirAll(path string, perm fs.FileMode) error
}
SettingsFS is the filesystem the settings are read and written through: OSFS for install and check, friendtest.MemFS (the in-memory twin) for a test.
type ShownEntry ¶
ShownEntry is the shown status of a friend (passed via --shown).
func LookupShown ¶
func LookupShown(shown map[string]ShownEntry, friend string) *ShownEntry
LookupShown returns the ShownEntry for friend, checking friend name then wildcard.
type SpendCap ¶ added in v1.2.14
type SpendCap struct {
Friend string
Provider string
// Now is the daemon's clock (a fake in tests).
Now func() time.Time
// DayStart is the start of the spend day containing now; when nil the day
// resets at UTC midnight.
DayStart func(now time.Time) time.Time
// Cap is the day's spend cap in USD for this provider; nil, or not
// positive, is DefaultSpendCapUSD.
Cap func() float64
// Spent is today's spend in USD as the harness's own usage report says it
// for the day that starts at dayStart. It is read before every turn launch.
Spent func(dayStart time.Time) float64
// Judgment is the one judgment raised to the seat and the owner when the cap
// is passed; it returns the line naming the friend, the provider and the
// spend. It is called once per spend day until the day resets, and once on a
// provider refusal for funds.
Judgment func(dayStart time.Time, spent, cap float64) string
// Idle is whether the friend has no dealt work and no live session; when it
// is set and tells, no turn launches at all, with no judgment (docs/SPEC-FRIEND.md,
// idle). It is checked before the spend cap.
Idle func() bool
// Halt, when set, is called when the cap is passed or the provider refused
// for funds, with the reason and the instant the stop ends: cmd/nova-friend
// wires it to the harness's own limit gate (Limits.Refuse), so every turn
// stops, the session liveness check included, not only the ones this gate
// wraps. Nil: this gate's deliveries alone are stopped.
Halt func(reason string, until time.Time)
// contains filtered or unexported fields
}
SpendCap is a friend's spend cap per day and per provider (docs/SPEC-FRIEND.md, spend caps). A friend daemon has a cap for each provider, read from its config, $20 a day by default. Spend is measured from the harness's own usage report, never estimated. At the cap the daemon stops launching turns and raises one judgment to the seat and the owner naming the friend, the provider and the spend; a provider refusal for funds (an insufficient balance, a 402) stops the turns at once with the same judgment rather than retrying hourly.
func (*SpendCap) Check ¶ added in v1.2.14
Check is the daemon's per-step read of the cap, for the steps where no delivery is attempted at all (a friend with nothing dealt): it raises the one judgment and halts the wired gate when the day's spend has passed the cap or the provider refused for funds, exactly as a delivery attempt does (docs/SPEC-FRIEND.md, spend caps). cmd/nova-friend calls it from its row hook, which the daemon's loop runs before it launches any turn.
func (*SpendCap) Gate ¶ added in v1.2.14
Gate wraps a Deliverer so that no turn is launched on a day whose measured spend has passed the cap, or after a provider refusal for funds: Deliver answers Deferred, the message kept in hand, and the one judgment for the day is raised. It is used exactly where Limits gates a harness at its limit (limit.go), so a spend-cap day stops launching turns the same way a limit does. A LaneHarness stays one (spendCappedLanes): its batch Deliver is held, and its lanes are not.
func (*SpendCap) Judged ¶ added in v1.2.14
Judged is the judgment raised for the day now, "" when none is.
func (*SpendCap) Refuse ¶ added in v1.2.14
Refuse marks the daemon stopped by a provider refusal for funds (an insufficient balance, a 402): the same judgment is raised to the seat and the owner, and no turn launches until the daemon restarts (docs/SPEC-FRIEND.md, spend caps). The judgment is the hook's own when it is set, so the refusal tells the seat and the owner exactly as a spent-out day does.
type Spender ¶
type Spender interface {
SpendLine() string
}
Spender is a lane harness that prices its runs (docs/SPEC-FRIEND.md, the Claude lanes, on the beat): SpendLine is what its runs have cost so far and the limit it last read, one line the daemon says on its beat when it changed; empty before any run.
type Stager ¶
type Stager struct {
Dir string
URL func(repo string) string
Env []string
// contains filtered or unexported fields
}
Stager stages jobs under Dir, her working directory, with the git credentials of the process that runs it (the daemon's: her account's). URL names a repository's remote (nil: GitHubURL); Env is git's whole environment (nil: the daemon's own, with GIT_TERMINAL_PROMPT=0, so git never waits on a prompt no one answers).
func (*Stager) Prune ¶
Prune removes the worktrees of finished jobs past kept, the oldest staged first (by its JOB.md), at most PrunePerPass of them, and answers the jobs it removed; a job whose mirror a stage holds is left for the next pass, never waited on. A job is finished when it is not live (held on her row, run by a lane, being staged: the caller's live) and its brief is not in her inbox (the inbox cleanup retired it); only a job whose checkout is a worktree of one of her mirrors is ever pruned, never a clone or anything another hand staged. A pruned job is gone whole (jobs/<job>), its worktree removed from the mirror; its branch stays in the mirror, so any commit on it is kept, and a stage of the job again takes the branch as it stands.
func (*Stager) Stage ¶
Stage stages p's job: the mirror of its repository fetched (cloned the first time), a git worktree of it at the base on the card's branch at jobs/<job>/repo, whose origin is the repository itself (the mirror's origin), and jobs/<job>/JOB.md. It answers the commit the checkout is at. A job already staged is left as it is; a checkout is never half there (the worktree is added beside, under jobs/<job>/.staging, and moved in whole), and JOB.md is written last, so a lane never meets a checkout not ready. A branch the mirror already holds (a pruned job's, staged again) is checked out as it stands, never reset to the base.
type Started ¶
Started is a card a lane began, kept in the lane state until the lane is done with it: a daemon that starts up and finds one finishes it, for the run that held it is gone.
type Status ¶
type Status struct {
Friend string `json:"friend"`
Harness string `json:"harness"`
Started time.Time `json:"started"`
At time.Time `json:"at"` // when this was written
// Seat is the coordinator seat holder as the sprint server last said it: who
// the daemon tells. Whether the friend is there is the nova-hook record's
// (nova-friend status and check read it), never this file's.
Seat string `json:"seat"`
Beats int `json:"beats"`
LastBeat time.Time `json:"last_beat"`
BeatError string `json:"beat_error,omitempty"`
StoreError string `json:"store_error,omitempty"`
Width int `json:"width"`
// Session is SessionOK, or SessionBroken once the provider refused BrokenAfter
// turns in a row the same way; empty for a passive harness.
Session string `json:"session,omitempty"`
SessionID string `json:"session_id,omitempty"`
SessionReason string `json:"session_reason,omitempty"`
BrokenAt time.Time `json:"broken_at,omitempty"`
// While the harness is at its usage limit or out of credits Session is
// SessionLimited, LimitKind says which (KindLimit or KindCredits) and
// LimitUntil is the reset (docs/SPEC-FRIEND.md, limits-mean-down-w-r.w1~15).
LimitKind string `json:"limit_kind,omitempty"`
LimitUntil time.Time `json:"limit_until,omitzero"`
// Mode is how the daemon delivers now (batch or one-shot), and Lanes the
// one-shot lanes as n:session:card/turn, empty in batch.
Mode string `json:"mode,omitempty"`
Lanes string `json:"lanes,omitempty"`
// Paced is the lanes' effective width under the subscription windows' pacing
// (pacing.go), nil before the lanes have stepped; Window is the windows' use
// as the harness last reported it ("5h 62% 7d 31%", empty when none is live),
// and Pacing the row's pacing as a percent.
Paced *int `json:"paced,omitempty"`
Window string `json:"window,omitempty"`
Pacing string `json:"pacing,omitempty"`
// Held, InboxJobs and Missing are the last inbox reconcile's counts (SyncInbox): the
// cards on her row, the sprint jobs in her inbox, and the held cards with no BRIEF.md
// after it; HeldKnown is false until the server has answered once, and InboxError is
// why the last reconcile did not finish, empty when it did.
HeldKnown bool `json:"held_known,omitempty"`
Held int `json:"held"`
InboxJobs int `json:"inbox"`
Missing int `json:"missing"`
InboxError string `json:"inbox_error,omitempty"`
// HeldFrom is where the last answer came from: friend cards, or the worker view while the
// server does not serve it (no brief is written from the view).
HeldFrom string `json:"held_from,omitempty"`
// Refused is the server's refusals counted per verb: each verb's consecutive
// refusals, cleared when it answers again (docs/SPEC-FRIEND.md, "A refused verb").
Refused map[string]int `json:"refused,omitempty"`
// LastRefusal is the last refusal as "verb: why", and when, on the daemon's clock.
LastRefusal string `json:"last_refusal,omitempty"`
LastRefusalAt time.Time `json:"last_refusal_at,omitzero"`
// Proof is the harness proof's last result ("ok", or the terminal reason it
// cannot answer), and ProofAt when it ran.
Proof string `json:"proof,omitempty"`
ProofAt time.Time `json:"proof_at,omitzero"`
}
Status is what the daemon knows, as status reads it: one file, rewritten whole, so a reader never sees half a state.
type StopReturn ¶
type StopReturn struct {
Lane int `json:"lane"`
// ServerLane is the lane the server says holds the card (take --lane), named on the
// stop-return so another lane's card is refused; 0 when no lane holds it
ServerLane int `json:"server_lane,omitempty"`
Job string `json:"job"`
Row string `json:"row"` // the owner row the return is sent as: friend.<name>, or the reader row
Card string `json:"card"` // the card id
Gen int `json:"gen"`
Epoch string `json:"epoch"`
Pid int `json:"pid,omitempty"` // the process signalled, when the harness said it (0: its group, by the lane's context)
Exit int `json:"exit"` // how the run ended; -1 while it has not
Ended bool `json:"ended"` // the run has ended: the return may be sent
At time.Time `json:"at"` // when the stop cancelled it
Tries int `json:"tries,omitempty"` // stop-returns sent and refused
Result string `json:"result,omitempty"`
// NextTry is when a refused stop-return is sent again (StopReturnRetry), and Refusal
// the refusal last said for it, said once while its text stands.
NextTry time.Time `json:"next_try,omitzero"`
Refusal string `json:"refusal,omitempty"`
}
StopReturn is one card the machine's stop took out of a lane: the evidence (the lane, the job, the card at its generation, the epoch, the process's end) and the stop-return owed for it, Result "" while it is owed and the server's answer once it took it.
func (StopReturn) Owed ¶
func (s StopReturn) Owed() bool
Owed says the stop-return has not been taken by the server.
type Stub ¶
type Stub struct{ Harness, Reason string }
Stub is a harness with no deliver command yet: it refuses every delivery with the way a session of that harness still reads the bus, so the tool is honest. It is Passive: the daemon takes nothing off the stream for it (the session's own blocking read does), only peeks, so a ping is still answered by the daemon at once and the beat is real.
type Task ¶
type Task struct {
Gen int `json:"gen,omitempty"` // assignment generation; absent means 1 (docs/FRIENDS.md)
Job string `json:"job,omitempty"` // delivered inbox directory, when recorded
ID string `json:"id"`
State string `json:"state"` // queued, working, done
Deliverable string `json:"deliverable,omitempty"`
}
Task is one record of the queue file.
type Tmux ¶
type Tmux struct {
Dir string // the friend's directory, the working directory of each tmux call
Session string // the tmux session, friend-<name>
Prompt *regexp.Regexp // the idle prompt, matched against the last non-empty line
Run Exec
Out io.Writer
Now func() time.Time // time.Now when nil
Sleep func(ctx context.Context, d time.Duration) // a real wait when nil
}
Tmux delivers into a TUI hosted in a tmux pane. Deliver captures the pane (`tmux capture-pane -p -t <session>`); when its last non-empty line matches the idle prompt it types the text literally (`send-keys -l`), then Enter as a second call, and is accepted once the prompt line has gone, the turn having started. While the prompt is absent a turn runs: Deferred, so no second turn lands beside one. A missing session is Deferred with the host line, never a failure.
type TokenCapped ¶
type TokenCapped struct {
Cap int64
At Tokens // the card's usage when the lane stopped it
Card string
Wrote bool // the lane wrote the card's REPORT.md (false: hers stood, or none could be written)
}
TokenCapped is a card's turn the lane stopped at its token cap.
func (TokenCapped) Error ¶
func (e TokenCapped) Error() string
type Tokens ¶
type Tokens struct {
Input, CacheRead, CacheWrite, Output, Reasoning int64
}
Tokens is a card's tokens as the harness's own usage record counts them.
func SessionTokens ¶
SessionTokens is a session's tokens from its export: its assistant messages' tokens summed. An export with no message carrying them answers errNoTokenShape, and the cap is not applied; its price (SessionCost) stands as it is.
type Unparseable ¶ added in v1.3.16
type Unparseable struct {
Field string // the field the line is missing: gen, kind or job
Why string
}
Unparseable is a LANE line that names the lane that asked but that the lane cannot read: a field it needs (gen, kind, job) missing or malformed. It is a Refused too. Asking again gets the same line from the same server, so the lane says it once and asks no more until the daemon restarts (laneAsk), rather than once a TakeRetry forever.
func (*Unparseable) Error ¶ added in v1.3.16
func (u *Unparseable) Error() string
func (*Unparseable) Unwrap ¶ added in v1.3.16
func (u *Unparseable) Unwrap() error
Unwrap makes an unparseable line a refusal for errors.As.
type Usage ¶
type Usage struct {
FiveHour, SevenDay float64
FiveHourResets, SevenDayResets time.Time
At time.Time
}
Usage is a harness's measured utilization of its five-hour and weekly windows, each a fraction (1 is the window spent), with when each resets and when it was measured (zero: never).
type UsageLimited ¶
UsageLimited is a lane's answer when the harness account itself is at its usage limit (a Claude Code rate_limit_event rejected, adapter_claude.go): unlike a rate limit it names its reset, so the lanes stop taking until Until (LaneGovernor.PauseUntil) and no cap is lowered; the card stays in the lane's hand, counted toward nothing.
func (UsageLimited) Error ¶
func (u UsageLimited) Error() string
type Verdict ¶
type Verdict struct {
Status string `json:"status"` // up or down
Reason string `json:"reason"`
Evidence []string `json:"evidence"`
}
Verdict is a friend's status, the one reason that decided it, and every piece of evidence as a person reads it.
func FriendStatus ¶
FriendStatus decides a friend's status from evidence, in order: at a limit is down until the reset; a hook record that does not prove her there is down; a bus that cannot deliver to her is down; otherwise up. Times are shown in loc.
type VerdictFacts ¶
type VerdictFacts struct {
Friend string `json:"friend"`
Verdict string `json:"verdict"` // ok, broken, down, untrue
Shown string `json:"shown"` // state/working (e.g. "up/8") or "-"
Why string `json:"why"`
}
VerdictFacts carries the health check verdict and explanation.
func DecideVerdict ¶
func DecideVerdict(df DaemonFacts, hf HarnessFacts, bf BusFacts, wf WorkFacts, shown *ShownEntry, window time.Duration) VerdictFacts
DecideVerdict is the pure function deciding a friend verdict from facts; every count and age is of the window (docs/SPEC-FRIEND.md "Check": the verdicts). The facts decide first, in this order:
- broken when the session is marked broken, or deliveries in the window are all failures (delivered > 0 and failed == delivered)
- down when her nova-hook record does not prove her there
- else ok
Then --shown: when it says up or working and the facts verdict is not ok, the verdict stays the facts' and the why leads with "untrue:", the claim and the facts' reason.
func (VerdictFacts) Line ¶
func (vf VerdictFacts) Line() string
Line renders the CHECK VERDICT line.
type Wall ¶
type Wall struct {
Profile string // the row's profile; "" is sandbox.ProfileFriend
Self []string // the program that runs the wall verb, and its arguments before the verb: this nova-friend
Dir string // the friend's working directory
ConfigDir string // her CLAUDE_CONFIG_DIR; "" none
Jobs []string // her job directories outside Dir
Reads []string // what her harness reads beyond the system roots and its own directory
Deny []string // the coordinator's self, never written inside the wall (sandbox.LaneProfile.Deny)
// Tmp is the lane's private temp directory, <lane dir>/tmp: Exec makes it for the
// run and removes it after, and the wall carries it as --tmp (lane_tmpdir.go).
Tmp string
}
Wall is the wall every child of a lane runs inside: the wall profile its friend row names (sandbox.LaneProfile), over the friend's directories.
func (Wall) Args ¶
Args is the wall verb and its flags, up to and with the "--" the command follows.
func (Wall) Exec ¶
Exec is run with every lane's child inside the wall: a command whose context is a lane's (LaneContext) runs as `<Self> wall <flags> -- <name> <args>`, in the same directory and with the same stdin; any other runs as it was. With no Self the lane's command is refused, never run unwalled.
type Watch ¶
Watch is the cursor of the coordinator's watch (docs/SPEC-FRIEND.md, Watch): the last stream entry id it has seen and the wake file's offset it has read to, so the next run misses nothing and takes no flag.
type WindowRefused ¶
type WindowRefused struct{ Remedy string }
WindowRefused is the window step's answer when the accessibility permission is absent (docs/SPEC-FRIEND.md, Reach). Remedy is what a person grants.
func (WindowRefused) Error ¶
func (w WindowRefused) Error() string
type WindowUse ¶
type WindowUse struct {
Window string `json:"window"`
Used float64 `json:"used"`
Status string `json:"status,omitempty"`
Resets time.Time `json:"resets,omitzero"`
At time.Time `json:"at,omitzero"`
}
WindowUse is one subscription window as the harness last reported it: its name, the fraction used (0 when the report named none: under the harness's warning threshold), the harness's status (allowed, allowed_warning, rejected), when it resets (zero: not said) and when it was read.
func ReadRateLimitEvents ¶
ReadRateLimitEvents is the windows a headless run's stream-json output reported in its rate_limit_event lines (rateLimitEvent, limit.go: the unifiedWindows of each window, or the older shape's one window), the last word of each window, in the order the windows were first named, each read at at. A rejected event marks rejected the windows it spent (at 1), or every window it names when none is at 1. A line that is not such an event is skipped.
Source Files
¶
- activity.go
- adapter.go
- adapter_antigravity.go
- adapter_claude.go
- adapter_claude_lanes.go
- adapter_dsh.go
- adapter_folder.go
- adapter_gemini.go
- adapter_grok.go
- adapter_opencode_lanes.go
- adapter_refused.go
- adapter_tmux.go
- antigravity_ledger.go
- check.go
- claude_async_hook.go
- conformance.go
- daemon.go
- deliver.go
- epoch.go
- group_unix.go
- harness_proof.go
- inbox.go
- lane_cap.go
- lane_end.go
- lane_parity.go
- lane_take.go
- lane_tmpdir.go
- lanes.go
- launchd.go
- limit.go
- limits.go
- machine.go
- notices.go
- one_lane.go
- outbox.go
- pacing.go
- presence.go
- pronouns.go
- pushproof_start.go
- ratelimit.go
- read_lanes.go
- renew.go
- rework.go
- settings.go
- settings_claude.go
- settings_codex.go
- settings_dsh.go
- settings_grok.go
- settings_opencode.go
- spendcap.go
- stage.go
- state.go
- status.go
- stop.go
- tokencap.go
- window.go
- window_other.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package friendtest holds the test doubles of pkg/friend that tests in other packages share.
|
Package friendtest holds the test doubles of pkg/friend that tests in other packages share. |