Documentation
¶
Overview ¶
Package ouroboros is the mining loop: the service that runs every accepted miner over the harness corpus all the time, decides for free whether a mining ticket can be fixed, launches one fixer session per ticket through the harness under a daily budget, merges ready pull requests through the merge path, and measures the compounding number the loop exists for. It replaces the ad hoc scripts that launched fixers outside the session gates.
It is a service in the harness host app: it owns no listener and no process. The binary grants it the ledger over csfpg, the harness's session capability, the process capability, the ticket capability over gh, the clock, the file and watch capabilities over the corpus and the repository, and mounts its four triggers into the cron service. Its own goroutine is the corpus watch, started on the scope the runtime hands it.
Index ¶
- Constants
- Variables
- func CorpusKinds(declared string) []string
- func MinerName(proposed string) string
- func PoissonRate(events int64, exposure int64) (rate *float64, low *float64, high *float64)
- func PullRequestOf(url string) (string, int64, error)
- func Refusal(report string) string
- func RepositorySlug(origin string) (string, error)
- func SessionTrailers(text string) []string
- func WeekOf(day string) string
- type Baseline
- type Comment
- type DailyBudget
- type Exponent
- type Finding
- type Fixer
- type FixerSummary
- type GitHubTickets
- func (tickets *GitHubTickets) Comment(ctx context.Context, number int64, body string) error
- func (tickets *GitHubTickets) ListMiningTickets(ctx context.Context) ([]Ticket, error)
- func (tickets *GitHubTickets) ListReadyPullRequests(ctx context.Context) ([]PullRequest, error)
- func (tickets *GitHubTickets) PullRequest(ctx context.Context, number int64) (PullRequest, error)
- func (tickets *GitHubTickets) PullRequestSessions(ctx context.Context, number int64) ([]string, error)
- func (tickets *GitHubTickets) Reference(ctx context.Context, number int64) (ReferenceKind, error)
- func (tickets *GitHubTickets) Repository() string
- func (tickets *GitHubTickets) TicketComments(ctx context.Context, number int64) ([]Comment, error)
- type HiddenRuns
- type IStore
- type ITickets
- type Item
- type Ledger
- func (ledger *Ledger) FindingsSince(ctx context.Context, since time.Time) ([]Finding, error)
- func (ledger *Ledger) FixersForTicket(ctx context.Context, ticket int64) ([]Fixer, error)
- func (ledger *Ledger) FixersStartedSince(ctx context.Context, since time.Time) ([]Fixer, error)
- func (ledger *Ledger) Item(ctx context.Context, miner string, item string) (Item, bool, error)
- func (ledger *Ledger) ItemsMinedSince(ctx context.Context, since time.Time) ([]Item, error)
- func (ledger *Ledger) Merge(ctx context.Context, pullRequest int64, headSHA string) (Merge, bool, error)
- func (ledger *Ledger) Proposal(ctx context.Context, ticket int64, proposal string) (ProposalRecord, bool, error)
- func (ledger *Ledger) ProposalsNeedingLabels(ctx context.Context) ([]ProposalRecord, error)
- func (ledger *Ledger) RecentFindings(ctx context.Context, limit int) ([]Finding, error)
- func (ledger *Ledger) RecentFixers(ctx context.Context, limit int) ([]Fixer, error)
- func (ledger *Ledger) RecentMerges(ctx context.Context, limit int) ([]Merge, error)
- func (ledger *Ledger) RecordFindings(ctx context.Context, findings []Finding) (int64, error)
- func (ledger *Ledger) RecordFixer(ctx context.Context, fixer Fixer) error
- func (ledger *Ledger) RecordItem(ctx context.Context, item Item) error
- func (ledger *Ledger) RecordMerge(ctx context.Context, merge Merge) error
- func (ledger *Ledger) RecordProposal(ctx context.Context, record ProposalRecord) error
- func (ledger *Ledger) RecordSeries(ctx context.Context, point Point) error
- func (ledger *Ledger) RunningFixers(ctx context.Context) ([]Fixer, error)
- func (ledger *Ledger) Series(ctx context.Context, series string) ([]Point, error)
- func (ledger *Ledger) UpdateFixer(ctx context.Context, fixer Fixer) error
- type Loop
- func (loop *Loop) DailyBudget(ctx context.Context) (DailyBudget, error)
- func (loop *Loop) Detect(ctx context.Context, only []string) error
- func (loop *Loop) Fixers(ctx context.Context) error
- func (loop *Loop) Measure(ctx context.Context) (*Snapshot, error)
- func (loop *Loop) MergeTrain(ctx context.Context) error
- func (loop *Loop) Miners(ctx context.Context) ([]Miner, error)
- func (loop *Loop) Register(router gin.IRouter)
- func (loop *Loop) Start(scope *runtime.Scope) error
- func (loop *Loop) Triggers() []cronservice.Option
- type LoopOption
- func WithClock(source clock.IClock) LoopOption
- func WithCorpus(directory string, files iofs.IFiles, watcher iofs.IWatcher) LoopOption
- func WithDailyBudget(usdMicros int64) LoopOption
- func WithFixerLaunch(enabled bool) LoopOption
- func WithFixerModel(model string) LoopOption
- func WithHidden(hidden HiddenRuns) LoopOption
- func WithLauncher(launcher proc.ILauncher) LoopOption
- func WithLedger(store IStore) LoopOption
- func WithLogger(logger *slog.Logger) LoopOption
- func WithMergeObserver(observer MergeObserver) LoopOption
- func WithMergerIdentity(identity string) LoopOption
- func WithRepository(directory string, files iofs.IFiles) LoopOption
- func WithSessions(sessions csf.IAgentSessions) LoopOption
- func WithState(directory string, files iofs.IFiles) LoopOption
- func WithTickets(tickets ITickets) LoopOption
- type Merge
- type MergeObserver
- type MergeSummary
- type Miner
- type MinerStatus
- type Outcome
- type Period
- type Point
- type Precheck
- type Prechecker
- type Proposal
- type ProposalRecord
- type PullRequest
- type Rate
- type Reading
- type Reference
- type ReferenceKind
- type Snapshot
- type StructureCounts
- type StructureWeek
- type Ticket
- type Trend
- type Usage
- type Verdict
Constants ¶
const ( // TriggerDetector sweeps every miner over the corpus items that grew // since they were last mined; the watch runs the same sweep the moment a // log changes, so this is the catch-up after a restart or a missed // notification. TriggerDetector = "ouroboros.detector" // TriggerFixers reconciles the running fixer sessions, pre-checks every // open mining ticket and launches fixers under the daily budget. TriggerFixers = "ouroboros.fixers" // TriggerMergeTrain runs the merge path over every ready pull request, // oldest first; one run of the path builds the checkers and takes about // ten minutes, so the train runs every thirty. TriggerMergeTrain = "ouroboros.merge_train" // TriggerMeasure computes the struggle rate, its compounding rate and the // loop's own yields, records them as series and projects them for the // ops view. TriggerMeasure = "ouroboros.measure" // ScheduleLocation is the time zone the triggers, the budget day and the // measured days are declared in: the one #330's measurement uses. ScheduleLocation = "America/Los_Angeles" // SnapshotFile is where the loop projects its numbers, under the state // directory, for the ops view that follows that directory. SnapshotFile = "ouroboros.json" // DefaultDailyBudgetUSDMicros is the operator's hard cap on fixer spend: // $100 per day, in integer microdollars like every amount in csfpg. DefaultDailyBudgetUSDMicros = 100_000_000 // DefaultFixerModel is the model fixers run on: every real session runs // claude-opus-5-5 (operator, 2026-10-05), which the harness's model // policy enforces at submit. DefaultFixerModel = "claude-opus-5-5" // MinersDirectory holds one directory per miner under the repository. MinersDirectory = "services/ouroboros/miners" // MinerExecutables holds each miner's built executable, as Bazel publishes // it under the repository. MinerExecutables = "bazel-bin/services/ouroboros/miners" // APIPath serves the latest snapshot as JSON on the host's router. APIPath = "/api/ouroboros" )
The triggers the loop declares, as csfcron names them, and their cadence. Each interval is derived from a measurement recorded in the README: the detector sweep is the catch-up behind the watch, the fixer and merge cadences follow the mean fixer session (21.8 min), and the measure follows the day the compounding number is computed over.
const ( // ScopeGeneric and ScopeTenant are the proto names of a miner's scope // (#120 amendment C): generic holds for any harness user and may be // shared from an opted-in tenant; tenant never leaves the tenant. ScopeGeneric = "SCOPE_GENERIC" ScopeTenant = "SCOPE_TENANT" )
A miner's files under its directory and the verbs of its executable, as the contract's main defines them.
const ( SeriesStruggleRate = "ouroboros.struggle_rate_per_1k_tool_calls" SeriesStruggleRateWeekly = "ouroboros.struggle_rate_per_1k_tool_calls_weekly" SeriesCompounding = "ouroboros.compounding_per_week" SeriesCompoundingDaily = "ouroboros.compounding_per_day" SeriesFindings = "ouroboros.findings" SeriesFixerSpend = "ouroboros.fixer_spend_usd" SeriesCostPerReadyPull = "ouroboros.cost_per_ready_pull_request_usd" SeriesFixerYield = "ouroboros.fixer_yield" // The baseline to beat (#330, 2026-10-02 comment): the weekly growth // factor of the struggle rate with its interval, and the rate in the // week of 2026-09-28. Exponential improvement is this factor below 1, // and staying there. BaselineWeeklyFactor = 1.156 BaselineWeeklyLow = 1.135 BaselineWeeklyHigh = 1.177 BaselineRatePerK = 49.9 BaselineWeek = "2026-09-28" // SignalToolError, SignalPermissionDenial and SignalRetry name the three // struggle signals read from a harness event log, as rrsi-mine names them. SignalToolError = "tool_error" SignalPermissionDenial = "permission_denial" SignalRetry = "retry" )
The series the measure records, and the constants of the measurement. The primary series is candace-server #330's: struggle episodes per 1,000 agent tool calls, reported weekly with the 95% Garwood Poisson interval, and the weekly growth factor from a weighted log-linear fit over the active weeks. The struggle definition is the deterministic part of #330's (rrsi-mine traces, the nine signals merged into episodes): the three signals a harness event log carries without a model are kept, with the same episode gap, and every episode counts, since no labeler marks noise or harness-fixability here. Days are calendar days in ScheduleLocation; weeks start on Monday. The per-day fit is kept as the early read while the corpus holds fewer than three active weeks.
const ( SeriesStructure = "ouroboros.structure_per_intervention" SeriesStructureExponent = "ouroboros.structure_exponent" // StructureProxy marks the denominator as the proxy it is until the // AFFECT miner labels corrections. StructureProxy = "proxy: operator-authored messages stand in for interventions until the AFFECT miner labels corrections" )
The internal check (#120 amendment B): structure gained per operator intervention, per week. The numerator is merged enforced structure, counted from git on main at each week's end: session gates (the Gate constants of the session gate), accepted miners (directories with a rules file) and ontology terms (term declarations). Recorded intents live in csfpg, not in git, so they are not counted here. The denominator is operator interventions: until the AFFECT miner labels corrections, the operator-authored messages into sessions (every prompt after a run's first turn), so the series is marked proxy. The slope of log(y) on the week index is the compounding exponent.
const ( CorpusEvents = "jsonl" CorpusIssue = "issue" CorpusPullRequest = "pull_request" CorpusFile = "file_at" InstanceRun = "run" InstanceIssue = "issue" InstancePullRequest = "pull_request" InstanceCommit = "commit" )
The corpus kinds a proposal declares, as the miner contract's Corpus readers name them, and the instance kind each one reads.
const (
// FixerAgentID names the fixer agent in every recipe and run record.
FixerAgentID = "ouroboros-fixer"
)
The fixer recipe: one agent definition, one brief per ticket, one branch per miner, and the tools the brief needs. The brief is the one the ad hoc loop handed its sessions, made a harness recipe.
const ( // SessionTrailer is the commit trailer every harness session leaves on // its commits; the merge train reads the author from it. SessionTrailer = "CSF-Session:" )
The gh invocations and the labels the mining subset is read by.
Variables ¶
var ( // ErrInvalidOption reports a nil option or a value the service cannot use. ErrInvalidOption = errors.New("ouroboros: invalid option") // ErrMissingCapability reports a loop built without a required capability. ErrMissingCapability = errors.New("ouroboros: a required capability is missing") // ErrAlreadyStarted reports a second Start of one loop. ErrAlreadyStarted = errors.New("ouroboros: the loop is already started") // ErrBudgetSpent reports a launch refused because the day's budget is // spent or reserved by the fixers already running. ErrBudgetSpent = errors.New("ouroboros: the daily fixer budget is spent") // ErrFixersDisabled reports a launch refused because the loop was built // without the fixer switch. ErrFixersDisabled = errors.New("ouroboros: fixers are not enabled") // ErrSelfMerge reports a pull request the train refused to merge because // its commits carry the merger's own session: NO-SELF-MERGE (#249). ErrSelfMerge = errors.New("ouroboros: the merger is the author session") )
var ErrDatabaseRequired = errors.New("ouroboros: a database is required")
ErrDatabaseRequired reports a ledger built without the database capability.
var ErrNoRepositorySlug = errors.New("ouroboros: the origin URL names no GitHub repository")
ErrNoRepositorySlug reports an origin URL no GitHub owner/name can be read from.
var ErrNotPullRequestURL = errors.New("ouroboros: not a GitHub pull request URL")
ErrNotPullRequestURL reports a URL that names no GitHub pull request.
Functions ¶
func CorpusKinds ¶
CorpusKinds reads the corpus kinds a proposal declares, such as "pull_request, jsonl".
func PoissonRate ¶
PoissonRate is events per 1,000 units of exposure with its 95% Garwood interval; no rate when there is no exposure.
func PullRequestOf ¶
PullRequestOf reads the repository slug and the number of the pull request a GitHub URL names.
func Refusal ¶
Refusal is the refusal reason a merge report carries: its first lines naming a refusal, regression, drift or failure, bounded.
func RepositorySlug ¶
RepositorySlug reads owner/name from a GitHub remote URL in either the https or the ssh spelling.
func SessionTrailers ¶
SessionTrailers reads every distinct CSF-Session trailer value in text, in first-seen order.
Types ¶
type Baseline ¶
type Baseline struct {
Factor float64 `json:"factor"`
Low float64 `json:"low"`
High float64 `json:"high"`
RatePerK float64 `json:"rate_per_1k"`
Week string `json:"week"`
}
Baseline is #330's baseline, carried in every snapshot so the view shows what the factor is measured against.
type DailyBudget ¶
type DailyBudget struct {
Day string
CapUSDMicros int64
SpentUSDMicros int64
ReservedUSDMicros int64
ExpectedSessionUSDMicros int64
MeasuredSessions int64
}
DailyBudget is the day's fixer budget as the ledger reads it now: the cap, what the day's fixers spent, what the running ones are expected to add, and that expectation per session with the number of finished sessions it was measured from (zero when it is the measured baseline).
func (DailyBudget) LeftUSDMicros ¶
func (budget DailyBudget) LeftUSDMicros() int64
LeftUSDMicros is the cap less the spend and the reservation, never below zero.
type Exponent ¶
type Exponent struct {
Slope *float64 `json:"slope"`
Low *float64 `json:"low"`
High *float64 `json:"high"`
Weeks int `json:"weeks"`
Proxy string `json:"proxy"`
}
Exponent is the compounding exponent of the internal check: the slope of log(structure per intervention) on the week index, with its 95% interval.
func StructureExponent ¶
func StructureExponent(weeks []StructureWeek) Exponent
StructureExponent fits log(y) on the week index by ordinary least squares over the weeks with a positive y, and returns the slope with its 95% interval; it needs structureMinWeeks such weeks.
type Finding ¶
type Finding struct {
Miner string
Rule string
Subject string
Item string
Severity string
Scope string
Record json.RawMessage
FoundAt time.Time
}
Finding is one verdict row a miner derived over one item: the subject's instance, the rule, the severity and the miner's own record whole.
func ParseFindings ¶
ParseFindings reads the JSON lines a miner printed. A finding's subject is its first argument; it is attributed to the item whose run directory the subject names, or to the first item when the subject names none.
type Fixer ¶
type Fixer struct {
AssignmentID string
Ticket int64
ProposalID string
Miner string
Model string
StartedAt time.Time
FinishedAt time.Time
Outcome Outcome
PullRequestURL string
CostUSDMicros int64
InputTokens int64
OutputTokens int64
Seconds int64
}
Fixer is one fixer session the loop launched, with what it cost.
type FixerSummary ¶
type FixerSummary struct {
Sessions int `json:"sessions"`
Running int `json:"running"`
Finished int `json:"finished"`
Ready int `json:"ready"`
SpendUSD float64 `json:"spend_usd"`
SpendTodayUSD float64 `json:"spend_today_usd"`
BudgetUSD float64 `json:"budget_usd"`
CostPerReady *float64 `json:"cost_per_ready_pull_request_usd"`
Yield *float64 `json:"yield"`
Launch bool `json:"launch_enabled"`
}
FixerSummary is the loop's own yield, from the ledger.
type GitHubTickets ¶
type GitHubTickets struct {
// contains filtered or unexported fields
}
GitHubTickets is the ticket capability over gh, run through the process capability against one repository.
func NewGitHubTickets ¶
func NewGitHubTickets(launcher proc.ILauncher, repository string) (*GitHubTickets, error)
NewGitHubTickets grants the repository's tickets through gh. repository is the owner/name slug.
func (*GitHubTickets) Comment ¶
Comment posts one comment on a pull request, read from standard input so its body never crosses an argument vector.
func (*GitHubTickets) ListMiningTickets ¶
func (tickets *GitHubTickets) ListMiningTickets(ctx context.Context) ([]Ticket, error)
ListMiningTickets lists the open severity-labeled, non-lang issues.
func (*GitHubTickets) ListReadyPullRequests ¶
func (tickets *GitHubTickets) ListReadyPullRequests(ctx context.Context) ([]PullRequest, error)
ListReadyPullRequests lists the open pull requests that are not drafts, oldest first.
func (*GitHubTickets) PullRequest ¶
func (tickets *GitHubTickets) PullRequest(ctx context.Context, number int64) (PullRequest, error)
PullRequest reads one pull request.
func (*GitHubTickets) PullRequestSessions ¶
func (tickets *GitHubTickets) PullRequestSessions(ctx context.Context, number int64) ([]string, error)
PullRequestSessions reads the CSF-Session trailers of a pull request's commit messages.
func (*GitHubTickets) Reference ¶
func (tickets *GitHubTickets) Reference(ctx context.Context, number int64) (ReferenceKind, error)
Reference asks the issues API what a number is; a number gh cannot find is nothing.
func (*GitHubTickets) Repository ¶
func (tickets *GitHubTickets) Repository() string
Repository is the owner/name slug.
func (*GitHubTickets) TicketComments ¶
TicketComments lists a ticket's comments, oldest first.
type HiddenRuns ¶
HiddenRuns lists the run directories of the corpus no miner and no measure may read: the evaluation suite's tickets, held out (#416).
type IStore ¶
type IStore interface {
Item(ctx context.Context, miner string, item string) (Item, bool, error)
RecordItem(ctx context.Context, item Item) error
ItemsMinedSince(ctx context.Context, since time.Time) ([]Item, error)
RecordFindings(ctx context.Context, findings []Finding) (int64, error)
FindingsSince(ctx context.Context, since time.Time) ([]Finding, error)
RecentFindings(ctx context.Context, limit int) ([]Finding, error)
Proposal(ctx context.Context, ticket int64, proposal string) (ProposalRecord, bool, error)
RecordProposal(ctx context.Context, record ProposalRecord) error
ProposalsNeedingLabels(ctx context.Context) ([]ProposalRecord, error)
RecordFixer(ctx context.Context, fixer Fixer) error
UpdateFixer(ctx context.Context, fixer Fixer) error
RunningFixers(ctx context.Context) ([]Fixer, error)
FixersStartedSince(ctx context.Context, since time.Time) ([]Fixer, error)
FixersForTicket(ctx context.Context, ticket int64) ([]Fixer, error)
RecentFixers(ctx context.Context, limit int) ([]Fixer, error)
Merge(ctx context.Context, pullRequest int64, headSHA string) (Merge, bool, error)
RecordMerge(ctx context.Context, merge Merge) error
RecentMerges(ctx context.Context, limit int) ([]Merge, error)
RecordSeries(ctx context.Context, point Point) error
Series(ctx context.Context, series string) ([]Point, error)
}
IStore is the ledger: every proposal, pre-check verdict, fixer session, merge result and series point the loop records, in the out-of-process store the binary grants.
type ITickets ¶
type ITickets interface {
// Repository is the owner/name slug the tickets live in.
Repository() string
// ListMiningTickets lists the open tickets carrying a severity label
// and no lang label, the mining subset, lowest number first.
ListMiningTickets(ctx context.Context) ([]Ticket, error)
// TicketComments lists a ticket's comments, oldest first.
TicketComments(ctx context.Context, number int64) ([]Comment, error)
// Reference reports whether a number is an issue, a pull request or
// nothing in the repository.
Reference(ctx context.Context, number int64) (ReferenceKind, error)
// ListReadyPullRequests lists the open pull requests that are not drafts,
// oldest first.
ListReadyPullRequests(ctx context.Context) ([]PullRequest, error)
// PullRequest reads one pull request.
PullRequest(ctx context.Context, number int64) (PullRequest, error)
// PullRequestSessions lists the CSF-Session trailers of a pull request's
// commits: the sessions that authored it.
PullRequestSessions(ctx context.Context, number int64) ([]string, error)
// Comment posts one comment on a pull request.
Comment(ctx context.Context, number int64, body string) error
}
ITickets is the ticket capability: the repository's issues and pull requests, reached through gh in the binary and a double in specs.
type Ledger ¶
type Ledger struct {
// contains filtered or unexported fields
}
Ledger is the IStore over CSF's PostgreSQL schema, reached through the csfpg capability: the csf_ouroboros_* tables and the queries csfpg generates for them. It borrows the capability and never closes it.
func NewLedger ¶
NewLedger returns the ledger over a pool the binary opened through ipc/db/csfpg, or over pgmem's IDB in a spec.
func (*Ledger) FindingsSince ¶
FindingsSince lists the findings recorded at or after since, oldest first; a zero since lists every finding.
func (*Ledger) FixersForTicket ¶
FixersForTicket lists every fixer launched for one ticket, oldest first.
func (*Ledger) FixersStartedSince ¶
FixersStartedSince lists the fixers started at or after since, oldest first; a zero since lists every fixer.
func (*Ledger) ItemsMinedSince ¶
ItemsMinedSince lists every item a miner last read at or after since, oldest first.
func (*Ledger) Merge ¶
func (ledger *Ledger) Merge(ctx context.Context, pullRequest int64, headSHA string) (Merge, bool, error)
Merge reads the merge path's result on one pull request head.
func (*Ledger) Proposal ¶
func (ledger *Ledger) Proposal(ctx context.Context, ticket int64, proposal string) (ProposalRecord, bool, error)
Proposal reads the verdict recorded on one proposal of one ticket.
func (*Ledger) ProposalsNeedingLabels ¶
func (ledger *Ledger) ProposalsNeedingLabels(ctx context.Context) ([]ProposalRecord, error)
ProposalsNeedingLabels is the labeler's queue, oldest first.
func (*Ledger) RecentFindings ¶
RecentFindings lists the newest findings, newest first.
func (*Ledger) RecentFixers ¶
RecentFixers lists the newest fixers, newest first.
func (*Ledger) RecentMerges ¶
RecentMerges lists the newest merge results, newest first.
func (*Ledger) RecordFindings ¶
RecordFindings records the findings not yet recorded and reports how many were new.
func (*Ledger) RecordFixer ¶
RecordFixer records a fixer session the loop launched, as running.
func (*Ledger) RecordItem ¶
RecordItem records that a miner read an item at a size.
func (*Ledger) RecordMerge ¶
RecordMerge records one run of the merge path.
func (*Ledger) RecordProposal ¶
func (ledger *Ledger) RecordProposal(ctx context.Context, record ProposalRecord) error
RecordProposal records or replaces the verdict on one proposal.
func (*Ledger) RecordSeries ¶
RecordSeries records or replaces one day of one series.
func (*Ledger) RunningFixers ¶
RunningFixers lists the fixers not yet finished, oldest first.
type Loop ¶
type Loop struct {
// contains filtered or unexported fields
}
Loop is the mining loop. Its state between occurrences is the ledger; the only in-process datum is the latest snapshot, published whole.
func NewLoop ¶
func NewLoop(options ...LoopOption) (*Loop, error)
NewLoop validates the whole option set and returns a stopped loop: it reads nothing and starts no goroutine until mounted.
func (*Loop) DailyBudget ¶
func (loop *Loop) DailyBudget(ctx context.Context) (DailyBudget, error)
DailyBudget reads the day's budget from the ledger. The expectation per running fixer is the ledger's own mean once it has ledgerMeanMinimum finished fixers, the measured baseline before.
func (*Loop) Detect ¶
Detect runs every built miner over the corpus items that grew since the miner last read them: every item when only is nil, the named run directories otherwise. It is deterministic and calls no model; the new findings go to the ledger and each item's size is recorded as read.
func (*Loop) Fixers ¶
Fixers is one occurrence of the fixer trigger: reconcile the running fixers with the harness, then pre-check every open mining ticket whose latest proposal has no verdict yet and launch a fixer for each one that passes, one per ticket, while the day's budget and the harness's admission allow. A ticket whose proposal names no real instance is queued for the labeler at no model cost.
func (*Loop) Measure ¶
Measure computes the loop's numbers over the corpus and the ledger, records them as series and publishes the snapshot.
func (*Loop) MergeTrain ¶
MergeTrain runs the merge path over every ready pull request, oldest first, exactly once per head: a refused head is commented on and retried only after its author pushes a new one. The merger is never an author session: a pull request whose commits carry the merger's identity is refused without running the path.
func (*Loop) Miners ¶
Miners lists the miners under the repository: every directory with a rules file, built or not, with the scope a built one reports.
func (*Loop) Start ¶
Start starts the corpus watch on scope, so every change to a run's event log mines that log once the change has settled, and runs the detector and the measure once, so the numbers are there as soon as the host is.
func (*Loop) Triggers ¶
func (loop *Loop) Triggers() []cronservice.Option
Triggers declares the loop's four triggers for the cron service, in ScheduleLocation. Every one skips an occurrence while the previous one still runs, so a long merge never overlaps the next.
type LoopOption ¶
LoopOption configures a Loop.
func WithClock ¶
func WithClock(source clock.IClock) LoopOption
WithClock replaces the host's clock, which stamps every ledger row and decides the budget day.
func WithCorpus ¶
WithCorpus grants the harness state directory the miners read: its absolute path, read access and change notification. Required.
func WithDailyBudget ¶
func WithDailyBudget(usdMicros int64) LoopOption
WithDailyBudget sets the hard cap on fixer spend per day, in USD microdollars. The default is DefaultDailyBudgetUSDMicros.
func WithFixerLaunch ¶
func WithFixerLaunch(enabled bool) LoopOption
WithFixerLaunch is the always-on switch: fixers are launched only when it is on. Until the harness reports that sandboxed launch is available, the binary turns it on only from an explicit flag.
func WithFixerModel ¶
func WithFixerModel(model string) LoopOption
WithFixerModel sets the model fixers run on.
func WithHidden ¶
func WithHidden(hidden HiddenRuns) LoopOption
WithHidden grants the list of held-out run directories; every corpus reader of the loop skips them. Without it nothing is hidden.
func WithLauncher ¶
func WithLauncher(launcher proc.ILauncher) LoopOption
WithLauncher grants the process capability: miners, git and the merge path run through it. Required.
func WithLogger ¶
func WithLogger(logger *slog.Logger) LoopOption
WithLogger receives the loop's own records.
func WithMergeObserver ¶
func WithMergeObserver(observer MergeObserver) LoopOption
WithMergeObserver tells observer about every pull request the merge train merges: the slice dispatcher releases what depended on it.
func WithMergerIdentity ¶
func WithMergerIdentity(identity string) LoopOption
WithMergerIdentity names the principal the merge train merges as, which NO-SELF-MERGE compares with the sessions a pull request's commits carry. Required.
func WithRepository ¶
func WithRepository(directory string, files iofs.IFiles) LoopOption
WithRepository grants the checkout the miners are read from, fixer worktrees are created from and the merge path runs in. Required.
func WithSessions ¶
func WithSessions(sessions csf.IAgentSessions) LoopOption
WithSessions grants the harness's session capability, through which every fixer is launched and observed. Required.
func WithState ¶
func WithState(directory string, files iofs.IFiles) LoopOption
WithState grants the state directory of the harness host the loop runs in: where fixer sessions run and where the snapshot is written. Required.
func WithTickets ¶
func WithTickets(tickets ITickets) LoopOption
WithTickets grants the ticket capability over the repository's issues and pull requests. Required.
type Merge ¶
type Merge struct {
PullRequest int64
HeadSHA string
AuthorSessions []string
Merger string
Merged bool
ExitCode int
Reason string
RecordedAt time.Time
}
Merge is one run of the merge path over one pull request head.
type MergeObserver ¶
type MergeObserver func(ctx context.Context, pull PullRequest)
MergeObserver is told about every pull request the merge train merged, once the merge is recorded.
type MergeSummary ¶
MergeSummary is the merge train's record.
type Miner ¶
type Miner struct {
Name string
Directory string
Executable string
Built bool
// Scope is what the miner's findings encode, as its executable reports
// it; empty for a miner that is not built.
Scope string
}
Miner is one accepted miner: a directory under the repository's miners directory with its rules, and its built executable.
type MinerStatus ¶
type MinerStatus struct {
Name string `json:"name"`
Built bool `json:"built"`
Scope string `json:"scope"`
Knee int64 `json:"knee"`
HasKnee bool `json:"has_knee"`
Findings int `json:"findings"`
}
MinerStatus is what the snapshot shows about one miner.
type Outcome ¶
type Outcome string
Outcome is where a fixer session stands.
type Point ¶
type Point struct {
Series string
Day string
Value *float64
Low *float64
High *float64
Numerator int64
Denominator int64
ComputedAt time.Time
}
Point is one day of one series: a value with its interval, or no value when the day had no exposure, and the counts it was computed from.
type Prechecker ¶
type Prechecker struct {
// contains filtered or unexported fields
}
Prechecker is the free pre-check: it decides, without a model, whether a proposal's miner has anything to backtest on. It reads the corpus, asks the ticket capability what a number is and git whether a commit exists.
func NewPrechecker ¶
func NewPrechecker(corpus iofs.IFiles, tickets ITickets, launcher proc.ILauncher, repository string) (*Prechecker, error)
NewPrechecker grants the pre-check the corpus, the tickets, the process capability and the repository checkout commits are resolved in.
func (*Prechecker) Check ¶
func (checker *Prechecker) Check(ctx context.Context, ticket int64, proposal Proposal) (Precheck, error)
Check decides whether the proposal's miner has anything to backtest on: at least one labeled instance must exist in the corpus and be of a kind the miner's extractor reads. A run must have a run directory, an issue or pull request must exist in the repository and not be the ticket itself, and a commit must be in the repository.
type Proposal ¶
Proposal is one mining proposal as a ticket carries it: the miner it names, the corpus kinds its extractor reads and the instances it labels.
func LatestProposal ¶
LatestProposal is the newest proposal among a ticket's comments.
func ParseProposal ¶
ParseProposal reads a proposal from a comment body: the miner and corpus rows of its field table and every row of its labeled-instance table. A comment without the labeled-instance table is not a proposal.
type ProposalRecord ¶
type ProposalRecord struct {
Ticket int64
ID string
Miner string
Corpus string
Instances []string
Verdict Verdict
Reason string
CheckedAt time.Time
}
ProposalRecord is the pre-check's verdict on one mining proposal of one ticket. A verdict of needs_labels is the labeler's queue entry.
type PullRequest ¶
type PullRequest struct {
Number int64
Title string
URL string
HeadSHA string
Draft bool
State string
CreatedAt time.Time
}
PullRequest is one pull request as the merge train and the fixer ledger read it.
func (PullRequest) Merged ¶
func (pull PullRequest) Merged() bool
Merged reports whether the pull request has merged.
type Rate ¶
type Rate struct {
Day string `json:"day"`
ToolCalls int64 `json:"tool_calls"`
Struggles int64 `json:"struggles"`
PerK *float64 `json:"per_1k"`
Low *float64 `json:"low"`
High *float64 `json:"high"`
}
Rate is one period's struggle rate: episodes per 1,000 tool calls with its interval, or no rate when the period had no tool call. Day is the calendar day, or the Monday of the week.
func DailyRates ¶
DailyRates folds the readings of several event logs into one rate per day, oldest first, and the operator interventions per week.
type Reading ¶
type Reading struct {
Calls map[string]int64
Episodes map[string]int64
Interventions map[string]int64
}
Reading is what one event log contributes to the measure, each count by the calendar day it fell on.
func Struggles ¶
Struggles reads one event log into its tool calls, struggle episodes and operator interventions, each dated in location.
func StrugglesWithin ¶
StrugglesWithin is Struggles over the log's first budget tool calls, and everything up to the next one: a fixed budget, the unit the evaluation suite reads a replay at. A budget of 0 reads the whole log.
type Reference ¶
Reference is one thing a labeled instance may name in the corpus.
func References ¶
References reads what a labeled instance may name: harness runs by their assignment identifier, issues and pull requests by a #number, and commits by a hex revision. It is pure; existence is the pre-check's question.
type ReferenceKind ¶
type ReferenceKind string
ReferenceKind is what a number names in the repository's issue space.
const ( ReferenceIssue ReferenceKind = "issue" ReferencePullRequest ReferenceKind = "pull_request" ReferenceNone ReferenceKind = "none" )
The kinds a number resolves to.
type Snapshot ¶
type Snapshot struct {
ComputedAt time.Time `json:"computed_at"`
Day string `json:"day"`
Week Rate `json:"week"`
Weeks []Rate `json:"weeks"`
Compounding Trend `json:"compounding"`
Baseline Baseline `json:"baseline"`
Struggle Rate `json:"struggle_rate"`
Days []Rate `json:"days"`
CompoundingDaily Trend `json:"compounding_daily"`
Structure []StructureWeek `json:"structure"`
StructureExponent Exponent `json:"structure_exponent"`
Findings int `json:"findings"`
FindingsToday int `json:"findings_today"`
FindingsPerDay *float64 `json:"findings_per_day"`
Fixers FixerSummary `json:"fixers"`
Merges MergeSummary `json:"merges"`
Queue int `json:"needs_labels"`
Miners []MinerStatus `json:"miners"`
GenericMiners int `json:"generic_miners"`
TenantMiners int `json:"tenant_miners"`
}
Snapshot is the loop's numbers at one instant: what the ops view shows and the API serves.
type StructureCounts ¶
type StructureCounts struct {
Gates int `json:"gates"`
Miners int `json:"miners"`
Terms int `json:"terms"`
}
StructureCounts is the enforced structure on main at one commit.
func (StructureCounts) Total ¶
func (counts StructureCounts) Total() int
Total is the structure as one number.
type StructureWeek ¶
type StructureWeek struct {
Week string `json:"week"`
Commit string `json:"commit"`
Counts StructureCounts `json:"counts"`
Gained int `json:"gained"`
Interventions int64 `json:"interventions"`
PerIntervention *float64 `json:"per_intervention"`
}
StructureWeek is one week of the internal check.
type Trend ¶
type Trend struct {
Factor *float64 `json:"factor"`
Low *float64 `json:"low"`
High *float64 `json:"high"`
Weeks int `json:"periods"`
}
Trend is a compounding rate: the multiplicative change of the struggle rate per period with its 95% interval, over the periods that entered the fit.
func Compounding ¶
Compounding fits ln(struggles/calls) on the period index over the periods with at least one struggle and activeCalls tool calls, weighting each by its struggles, and returns the per-period factor with its 95% interval: measure.py's trend, over days or weeks.
type Usage ¶
type Usage struct {
CostUSDMicros int64
InputTokens int64
OutputTokens int64
Seconds int64
Results int
}
Usage is what a fixer session cost, folded from its event log.
func FoldUsage ¶
FoldUsage reads a session's cost from its event log. The executor reports total_cost_usd cumulatively within one process and from zero when the process is reopened, so the cost is the sum of the maximum of each non-decreasing run; tokens are summed over every result; seconds span the first record to the last.
type Verdict ¶
type Verdict string
Verdict is the pre-check's answer on one proposal.
const ( // VerdictLaunch: the ticket names an instance that exists in the corpus, // so a fixer may be launched. VerdictLaunch Verdict = "launch" // VerdictNeedsLabels: no named instance exists, so no model is paid and // the proposal waits in the labeler's queue. VerdictNeedsLabels Verdict = "needs_labels" )
The verdicts, as the ledger stores them.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package codes holds CSF's failure codes and codes complaints with them.
|
Package codes holds CSF's failure codes and codes complaints with them. |
|
Package evaluate scores csf builds on a held-out, rotated suite of past tickets before they go live (EVAL-SUITE, #416).
|
Package evaluate scores csf builds on a held-out, rotated suite of past tickets before they go live (EVAL-SUITE, #416). |
|
Package labeler is the ouroboros labeler (csf_staging#318): for a mining ticket that names no real instance, it finds candidate spans in the corpus the ticket's miner would read, asks a local model to label them, and keeps only the labels that reproduce.
|
Package labeler is the ouroboros labeler (csf_staging#318): for a mining ticket that names no real instance, it finds candidate spans in the corpus the ticket's miner would read, asks a local model to label them, and keeps only the labels that reproduce. |
|
Package mocks is a generated GoMock package.
|
Package mocks is a generated GoMock package. |