Documentation
¶
Overview ¶
Package harbor holds what BuildMax needs to be measured by Harbor against Terminal-Bench 2.1: the versions a result depends on, and the Python agent Harbor loads to run the built CLI inside a task container.
Harbor owns task materialization and official verification. BuildMax does not run a second copy of the benchmark and does not re-grade its outcomes; see docs/design/evaluation-system.md section 14.2.
Index ¶
- Constants
- func DefaultJobName(at time.Time) string
- func ResolveJob(jobsDir, jobName string) (string, error)
- func Run(pins Pins, spec RunSpec, stdout, stderr io.Writer) (string, error)
- func RunCommand(pins Pins, spec RunSpec) []string
- type Adapter
- type AgentContext
- type AgentInfo
- type Canary
- type Conversion
- type Dataset
- type ExceptionInfo
- type Harbor
- type ModelInfo
- type Options
- type Pins
- type Protocol
- type RunSpec
- type SubjectInput
- type Trial
- type TrialConfig
- type TrialResult
- type VerifierResult
Constants ¶
const ( // TrialResultFile is Harbor's record of one attempt. // // Singular, despite Harbor's own TrialPaths docstring calling it // results.json in two places: its `result_path` property returns // result.json, and that is what a real job directory holds. The code is the // fact. TrialResultFile = "result.json" // TrialConfigFile is the configuration that attempt ran under. Harbor // writes it with defaults excluded, so an absent field means the default. TrialConfigFile = "config.json" // TrialAgentDir is where the agent's own logs land, mounted from the // container's /logs/agent. It is where this repository's adapter leaves // BuildMax's result envelope and the run's traces. TrialAgentDir = "agent" // AgentResultFile is the print-mode envelope the BuildMax adapter writes. AgentResultFile = "buildmax-result.json" // AgentSessionsDir holds the durable traces the adapter copied out. AgentSessionsDir = "sessions" )
Harbor's own on-disk layout. A job directory holds one directory per trial, and each of those holds the files below.
const OracleAgent = "oracle"
OracleAgent runs each task's own reference solution instead of a subject. It measures the environment — Docker, the dataset download, the task images — which is what makes it the thing to run before spending anything on a model.
const PassingReward = 1.0
PassingReward is the value a Terminal-Bench task writes for success. Its tasks write 0 or 1 to reward.txt, so anything short of full credit is a failure rather than a partial pass — the recorded score keeps the number for a task that ever reports one in between.
const PinsFile = "pins.json"
PinsFile is the committed pin set, relative to this package.
const SchemaVersion = 1
SchemaVersion is the pin format this build understands.
const VerifierGrader = "harbor-verifier"
VerifierGrader is the single grader a Harbor trial carries. There is exactly one because section 14.2 leaves the benchmark's own verifier authoritative: BuildMax records what it decided and does not re-grade the workspace, which it never saw.
Variables ¶
This section is empty.
Functions ¶
func DefaultJobName ¶
DefaultJobName names a job after the moment it started. The name is chosen here rather than left to Harbor's own default so that the caller knows where the job landed without guessing at a directory listing afterwards.
func ResolveJob ¶
ResolveJob finds the job a run wrote. It prefers the directory the run asked for and falls back to the newest one in the jobs directory, because the layout belongs to Harbor: a release that renames or nests what it writes should cost an import that finds the job anyway, not a failed one that leaves a paid-for run unfiled.
func Run ¶
Run starts the benchmark and returns the directory Harbor wrote the job into.
This is the only place in the repository that starts a Harbor run rather than reading one, and it stays a thin wrapper on purpose: Harbor owns task materialization, execution, and verification, and none of that is reproduced here. What this owns is the argument list, because every argument that has to be right is already pinned.
The job directory comes back even when the run fails. A job that died partway still holds the trials that finished, and importing them is how a failure gets diagnosed.
func RunCommand ¶
RunCommand is the command a run takes, and the command a bundle records as its reproduction. Both read this, so the command in the evidence is the command that produced the evidence.
The dataset always carries its immutable ref. Harbor resolves a bare name to `latest`, and a job that measured latest cannot honestly be filed under a pinned digest — which is exactly what the importer stamps on every bundle it writes. The pin was enforced by a human copying a checksum out of a README until this existed.
Types ¶
type Adapter ¶
Adapter is this repository's own contribution to a result. It versions separately from the product because a change to how the CLI is invoked moves scores without the CLI moving.
type AgentContext ¶
type AgentContext struct {
InputTokens *int `json:"n_input_tokens"`
CacheTokens *int `json:"n_cache_tokens"`
OutputTokens *int `json:"n_output_tokens"`
CostUSD *float64 `json:"cost_usd"`
Metadata map[string]any `json:"metadata"`
}
AgentContext is what the agent reported about its own run. For the BuildMax adapter, Metadata carries the subject facts the adapter resolved and the print-mode envelope's exit classification.
type AgentInfo ¶
type AgentInfo struct {
Name string `json:"name"`
Version string `json:"version"`
ModelInfo *ModelInfo `json:"model_info"`
}
AgentInfo identifies the agent that ran, as Harbor recorded it.
type Canary ¶
type Canary struct {
Tasks []string `json:"tasks"`
}
Canary is the named subset a change is validated on before the full benchmark is paid for.
It is pinned rather than chosen per run because its job is comparison against itself: a subset picked fresh each time measures a different thing every time, and the first question after a canary is always whether something got worse. The tasks are chosen to exercise different paths through the adapter — a build toolchain, git, a served process, plain data work, and something compute-bound enough to fail — rather than to sample capability. Six tasks cannot estimate a score and are not meant to.
type Conversion ¶
type Conversion struct {
Subject contract.SubjectManifest
Bundles []contract.TrialBundle
}
Conversion is one Harbor job expressed in the BuildMax contract.
func Convert ¶
func Convert(trials []Trial, pins Pins, opt Options) (Conversion, error)
Convert turns a loaded Harbor job into one bundle per attempt.
It reads two sources per trial and prefers the closer one. Harbor's results.json is a re-encoding of what the agent reported — its cost is a float in dollars, which cannot round-trip the runtime's integer nano-units — while the print-mode envelope the adapter left in the trial's agent directory is BuildMax's own first-hand report. The envelope wins where both speak; the verifier's verdict is only ever Harbor's.
func Import ¶
func Import(jobDir, bundleRoot string, pins Pins, opt Options) (Conversion, error)
Import reads a finished Harbor job and writes it into a BuildMax bundle tree.
It is one direction only. Harbor ran the benchmark, its verifier decided each outcome, and its job directory keeps the trajectories and artifacts; this copies none of that and rewrites none of it. What it produces is the record that makes an external result comparable with a BuildMax one: the subject tuple a qualification has to name, and one bundle per attempt carrying the verdict, the failure class, the usage, and the path back to the evidence.
func (Conversion) Attempts ¶
func (c Conversion) Attempts() int
Attempts returns the highest attempt count any task reached.
The maximum rather than the mean: Harbor retries a trial that failed for a harness reason, so a job can hold more attempts for one task than another, and reporting an average would describe a repetition count no task actually ran.
func (Conversion) Tasks ¶
func (c Conversion) Tasks() []string
Tasks returns the task ids the job covered, in order and without repeats.
type Dataset ¶
type Dataset struct {
Name string `json:"name"`
Ref string `json:"ref"`
// Tasks is how many the release holds. A run that measured a different
// number measured a different dataset, whatever it was called.
Tasks int `json:"tasks"`
// Source is where Ref was read from, so the next reader can check it
// against the benchmark rather than against this file.
Source string `json:"source"`
}
Dataset is the task collection, pinned by the immutable ref the benchmark's own leaderboard configuration names rather than by a floating "latest".
type ExceptionInfo ¶
type ExceptionInfo struct {
Type string `json:"exception_type"`
Message string `json:"exception_message"`
}
ExceptionInfo is how a trial failed outside the verifier's judgement.
type Harbor ¶
type Harbor struct {
Version string `json:"version"`
// Install is the exact command that produces this version, so a reader
// reproducing a run does not have to know which package index it came from.
Install string `json:"install"`
}
Harbor is the harness release. Its version pins the custom-Agent interface this repository's Python agent is written against, which changes between releases: 0.22.0 deprecated `--agent-import-path` in favour of `--agent`.
type ModelInfo ¶
ModelInfo is Harbor's model identity. Provider is absent when the run named a model without a `provider/` prefix, which Harbor records rather than filling in — the same choice the BuildMax subject manifest makes about a revision.
type Options ¶
type Options struct {
// Subject is what the job cannot say about what it measured.
Subject SubjectInput
// ExperimentID names the measurement these bundles belong to.
ExperimentID string
// CreatedAt dates the experiment. It is passed rather than read from the
// clock so an import is reproducible, and so a caller can date the record
// from the job it read rather than from when it got round to reading it.
CreatedAt time.Time
// Retention is how much of the subject's free text the bundles keep. Empty
// means bounded, which is what a local diagnosis wants; an export lowers it.
Retention contract.RetentionLevel
}
Options is everything an import needs beyond the job directory and the pins.
type Pins ¶
type Pins struct {
SchemaVersion int `json:"schema_version"`
Harbor Harbor `json:"harbor"`
Dataset Dataset `json:"dataset"`
Adapter Adapter `json:"adapter"`
Protocol Protocol `json:"protocol"`
Canary Canary `json:"canary"`
}
Pins names every version a Terminal-Bench result depends on besides the subject itself.
It exists because a benchmark score is only a measurement if the thing that produced it can be named. Harbor, the dataset, and this adapter all move independently of BuildMax, and a run that recorded only "Terminal-Bench 2.1" could not tell a product regression from a dataset correction or a harness upgrade.
type Protocol ¶
type Protocol struct {
Attempts int `json:"attempts"`
MaxRetries int `json:"max_retries"`
Source string `json:"source"`
}
Protocol is the benchmark's own comparison policy, copied so a run can be checked against it without network access. Deviating from it is allowed and reported; deviating from it silently is what makes a number incomparable.
type RunSpec ¶
type RunSpec struct {
// Agent is the Harbor agent to run. Empty means this repository's adapter.
Agent string
// Model is Harbor's `provider/model`. Harbor resolves the credential for it
// from the environment; the adapter writes that into the trial home. A
// contributor's own settings.yaml is never consulted, so a run measures the
// subject rather than the machine it was started from.
Model string
// Tasks are qualified names, `<org>/<name>`: Harbor lists a packaged task
// that way and refuses a bare one. Empty runs the whole dataset.
Tasks []string
Attempts int
// Limit caps how many tasks run, applied after the filters.
Limit int
JobsDir string
JobName string
Kwargs map[string]any
// AdapterSrc is put on PYTHONPATH so Harbor can import the adapter class.
// Passing it is what makes the run independent of the working directory it
// was started from.
AdapterSrc string
// Extra is passed to Harbor verbatim, for the flags this type does not
// model. It is an escape hatch, not the way to set anything above.
Extra []string
}
RunSpec is one Harbor invocation: what to measure, over which tasks, how many times. Everything else a result depends on comes from the pins, which is the point: the caller cannot forget the dataset ref or the adapter's import path because it never gets to name them.
type SubjectInput ¶
type SubjectInput struct {
Name string
Host contract.HostProfile
}
SubjectInput is what a Harbor job cannot say about the subject it measured.
Only the host, and only because trials execute in containers Harbor placed somewhere: the machine that started them is what a latency comparison has to hold constant, and nothing in a job directory records it.
The artifact is deliberately not here. Harbor records the agent kwarg naming a binary path, which is not the digest of the file that ran, and a caller asserting the digest afterwards can assert the wrong one with nothing able to check it. The adapter digests the binary it uploads and records that instead.
type Trial ¶
type Trial struct {
// Dir is the trial directory, kept so evidence beside the manifests can be
// found without recomputing where it was.
Dir string
Result TrialResult
Config TrialConfig
}
Trial is one attempt as Harbor left it on disk.
func LoadJob ¶
LoadJob reads every trial in a Harbor job directory, ordered by task and then by start time.
A directory without a result file is skipped: Harbor creates a trial directory before the trial runs, so an interrupted job leaves empties behind and refusing them would make a partial job unreadable. A result file that does not parse is an error, because that is evidence this build cannot interpret rather than evidence that was never written.
type TrialConfig ¶
type TrialConfig struct {
Agent struct {
Name string `json:"name"`
ImportPath string `json:"import_path"`
ModelName string `json:"model_name"`
Kwargs map[string]any `json:"kwargs"`
} `json:"agent"`
}
TrialConfig is the part of Harbor's config.json this package reads: what the attempt was configured to run, as opposed to what it reported afterwards.
type TrialResult ¶
type TrialResult struct {
TaskName string `json:"task_name"`
TrialName string `json:"trial_name"`
TrialURI string `json:"trial_uri"`
// Source is the dataset the task came from, absent for an ad-hoc run.
Source *string `json:"source"`
// TaskChecksum pins the task content the attempt started from. It is the
// initial-state identity for an external benchmark: BuildMax never
// materialized the workspace, so the task's own digest is what says where
// the trial began.
TaskChecksum string `json:"task_checksum"`
AgentInfo AgentInfo `json:"agent_info"`
AgentResult *AgentContext `json:"agent_result"`
VerifierResult *VerifierResult `json:"verifier_result"`
ExceptionInfo *ExceptionInfo `json:"exception_info"`
StartedAt *time.Time `json:"started_at"`
FinishedAt *time.Time `json:"finished_at"`
}
TrialResult is the part of Harbor's results.json this package reads.
type VerifierResult ¶
VerifierResult is the benchmark's own verdict. Rewards is an open map because a task decides its own keys: a Terminal-Bench task writes reward.txt, which Harbor reads as a single "reward" of 0 or 1.