Release Notes
Every runner cycle is now traced & emits metrics. 1.1's headline is OpenTelemetry: each cycle emits a span tree covering image resolution, pull, SSH provisioning, runner launch, and teardown, plus spans for the underlying HTTP egress (GitHub API, registry, tarball CDN). Opt in via observability.otlp in config.
The second theme is operator access and audit: grant/revoke/list operator accounts at runtime, revocation enforced as soon as possible, and every debug session stamped with the authenticated UID and recorded as a cycle artifact.
Also in this release:
ssh_hardening: scramblefor randomized guest passwords- per-pool
guest_env/guest_setupprovisioning (thanks to @paul-calnan-simplisafe for his contribution!) - runnyctl prune for on-demand disk reclaim
- a fix for tart-guest-agent behaving oddly and killing system processes when a console device wasn't attached (thanks to @withzombies for his contribution!)
Changelog
1.1.0 (2026-07-10)
Features
- app: render benign cycle endings distinctly in the timeline (#239) (798243f)
- ci: report combined Go+Swift coverage to Codecov (#281) (427abbf), closes #277
- config: add per-pool guest_env and guest_setup for guest provisioning (#294) (15a5b2e)
- cycle: persist the ending classification on the record (#237) (68f8adf)
- guest: add ssh_hardening: scramble to randomize guest passwords (#215) (1bc753d), closes #210
- guest: record operator debug sessions as cycle artifacts (#211) (c1c8bea)
- home: add opt-in observability.otlp config block (#236) (f77d859)
- images: action events and ensurer-scope pull metrics (#246) (1d1f998)
- obs,images: pull-scoped events from the shared image puller (#265) (53d7f99), closes #257
- obs: add the cycle observability event stream and Action wrapper (#238) (c7c6c7b)
- obs: emit spans for HTTP egress (#248) (9d18860)
- otlp: send custom headers on OTLP exports, with ${env:VAR} expansion (#273) (283bee4)
- release: add a beta channel formula/cask pair to the tap (#268) (6cdb3c2)
- runnyctl: on-demand disk reclaim via runnyctl prune (#206) (5596ab9)
- runnyctl: stage config on install, add edit-config (#274) (6d467ca)
- runnyd: add the OTLP telemetry runtime — providers, resource, bounded shutdown (#242) (cd78eca)
- socket: enforce operator revocation at RPC-start, not just connect() (#270) (e68ca57)
- socket: grant/revoke/list operator accounts at runtime (#220) (8979276), closes #209
- socket: log the authenticated operator on lifecycle commands (#272) (74e3080)
- socket: stamp the authenticated operator uid on injected_keys (#219) (c7a2786)
- statemachine: action events for teardown, rotation, and provision sub-steps (#244) (127239a), closes #231
- statemachine: emit observability events from the record helpers (#241) (a3a5f37), closes #224
- telemetry: add the trace emitter (#243) (fe9b82f), closes #227
- telemetry: fold pull events into traces and metrics; delete images.Metrics (#266) (1a89323), closes #258
- telemetry: metrics emitter — cycle instruments and slot gauges (#245) (d947877)
Bug Fixes
- address post-1.0 security audit findings (#201) (ba32aae)
- collapse the runner-tarball cache to per-cycle owned clones (#205) (973b031)
- deps: update module golang.org/x/sync to v0.22.0 (#293) (698859c)
- deps: update module golang.org/x/sys to v0.47.0 (#292) (0a70309)
- deps: update module google.golang.org/grpc to v1.82.0 (#289) (e8d95bb)
- harden daemon failure paths — force-stop, gRPC, stall, runner cache (#203) (a672c37)
- home: validate retention.cycles_per_slot, share the positive-duration check (#286) (f118682)
- release: pin version.sh's svu baseline to the last stable tag (da62db0)
- sshx: stop WaitFor's rejection test racing real SSH timing (#216) (e391020)
- statemachine: stop daemon shutdown from relabeling a decided cycle's ending (#240) (f46bd09)
- sysdaemon: parse the -test-config verdict at install time (#282) (0a35a2b)
- vm: reuse the persisted ECID and attach the tart-guest-agent's console port (#222) (efcc368)
Refactoring
- apply the over-engineering audit across daemon, CLI, and app (#276) (80ad279)
- guest: extract a shared per-OS dispatch helper (#217) (3106113), closes #214
- home: fold limits.*/retention.max_age into a config field table (#283) (4af92ec)
- images: collapse parameter lists into Ensurer methods (#262) (c38d48d), closes #253
- obs,telemetry: durations on step/job events; stateless metrics consumer (#264) (1254317), closes #256
- obs: drop the unused Event.Seq / per-scope counter (#267) (28e3fa7)
- runnyctl: parse the CLI with kong instead of stdlib flag (#275) (4e6523b)
- statemachine: extract the slot's mutex-guarded state into a statusCell (#259) (ceff3b2), closes #250
- statemachine: hoist runCycle's working state into a per-cycle run struct (#260) (6c3a599), closes #251
- statemachine: unify the step bracket and the record/status/event writes (#261) (d957fca), closes #252
- telemetry: delete the deterministic trace-ID machinery (#263) (bfbf67e), closes #255