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.

internal/sshserver/runner.go +10

@@ -305,6 +305,16 @@ func (s *Server) serveRunner(ch ssh.Channel, user, accountID string) {
305 305 continue
306 306 }
307 307 }
308 // The machine is a claim from the record, mirrored under the same rule as the
309 // log and the artifacts: written only while this runner still holds the lease,
310 // so a runner that was overtaken leaves no claim behind.
311 if mirrored, err := cfg.Runs.RecordMachine(run.ID, owner, rec.OS, rec.Arch); err != nil {
312 _ = enc.Encode(runnerReply{Op: "finish", Error: err.Error()})
313 continue
314 } else if !mirrored {
315 _ = enc.Encode(runnerReply{Op: "finish", OK: false})
316 continue
317 }
308 318 attested, err := cfg.Runs.RecordAttestation(run.ID, owner, runs.Attestation{
309 319 Signer: rec.Signer,
310 320 Fingerprint: rec.Key,