Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Phase 4: a run record names the machine, not the toolchain

379dad1e7417b9153a4913402cfc97bb51ce1bb4 · Keenan Nemetz · 16d ago · parent 72797dcd

Phase 4: a run record names the machine, not the toolchain

A finished attempt now says which operating system and architecture ran it,
in record.md beside the exit code and the signer, so the two fields ride the
signature that is the attestation. A result a clone carries says what kind
of machine produced it, not only which job it was — which is what turns
"one macOS runner in a Linux pool" into a question somebody can answer
after the fact, and the first half of the targeting work that remains.

The roadmap also asked for the runner's Go version and that was dropped
deliberately: runtime.Version() names the toolchain the *runner binary* was
compiled with, which is not the Go that builds anything in a job. A step
running `go build` uses whatever is on PATH in the checkout, usually a
different install, so in a signed record the field would be a confident
answer to a question nobody asked. OS and architecture survive the same
objection because they describe the machine, which is the fact this was for.

The keys are optional and an absent machine writes nothing at all rather
than an empty line, because a record is never rewritten and history that
predates a field has to stay readable. runs.db mirrors the pair the way it
mirrors the log and the artifacts — only while the runner still holds the
lease, so an overtaken runner leaves no claim behind — and `vole index
rebuild` restores it from the branch.

Measured: TestRunRecordIsPortable carries the machine through the record,
the row, the rebuild and the page; TestRecordWithoutMachineStillReads and
TestMachineIsRecordedOnlyWhileTheLeaseIsHeld pin the two edges.

cmd/vole/runner.go +5

@@ -12,6 +12,7 @@ import (
12 12 "os/exec"
13 13 "path"
14 14 "path/filepath"
15 "runtime"
15 16 "slices"
16 17 "sort"
17 18 "strings"
@@ -508,6 +509,10 @@ func (s *runnerSession) finish(remote, work string, job *runnerJob, log *strings
508 509 Workflow: job.Workflow, WorkflowSHA: job.WorkflowSHA, Job: job.Job,
509 510 StepsSHA: job.StepsSHA, Exit: exit, Finished: time.Now().UTC(),
510 511 Signer: s.account, Key: s.fingerprint, Artifacts: artifacts,
512 // The machine this attempt ran on. The runner binary's own build target,
513 // which is the honest thing it can say: a live probe would add a subprocess
514 // and a platform quirk for a fact the binary already knows.
515 OS: runtime.GOOS, Arch: runtime.GOARCH,
511 516 }
512 517 if oid != "" {
513 518 rec.Log = &lfs.Pointer{OID: oid, Size: size}