Between 0.3.23 and 0.3.32, Mechanics ran the same refactor seven times: take one
external system's transport (HTTP calls, DTOs, auth flows, error mapping), move
it into an operation-based provider in mechanics-sdk, and delete the
internal client with no compatibility wrapper. Forgejo, OpenBao, GitHub, S3,
VictoriaMetrics, OCI registries, and finally Kubernetes itself.
Providers own transport, Mechanics owns meaning
The split is strict. A provider knows how to talk to a system: Device Flow
against GitHub, signed ListObjectsV2 against S3, manifest reads with the right
Accept headers against an OCI registry. Mechanics keeps what the
calls mean: signup state, workspace attribution, PromQL construction, pull
credential policy, command output. Each provider is consumed through a narrow
ports layer such as internal/forgejoops, internal/openbaoops,
and internal/kubernetesops, and architecture tests fail the build if a
deleted client package ever comes back.
The kubectl binary is gone
The largest step was ADR-037/ADR-040: the Kubernetes provider first replaced the internal kubectl transport package, then replaced kubectl process execution with client-go: discovery-based resolution, server-side apply, SPDY exec and port-forward streams, TokenRequest tokens. The kubectl binary is no longer a runtime dependency of the service, and exec arguments travel in API request bodies instead of child argv.
Safety came along for free
Centralizing transport centralized redaction: provider errors scrub
credential-bearing response bodies and key=value fragments such as
PGPASSWORD=... before they can reach diagnostics. Operations return
stable names, run IDs, and timing metadata, and the providers share one verb
contract: converging operations report Created/Changed,
and deletes tolerate absent targets, so Mechanics stopped sniffing
"AlreadyExists" strings to decide what happened.
gitea.andreygubarev.com/mechanics.run/mechanics-sdk/provider/forgejo
gitea.andreygubarev.com/mechanics.run/mechanics-sdk/provider/openbao
gitea.andreygubarev.com/mechanics.run/mechanics-sdk/provider/github
gitea.andreygubarev.com/mechanics.run/mechanics-sdk/provider/s3
gitea.andreygubarev.com/mechanics.run/mechanics-sdk/provider/victoriametrics
gitea.andreygubarev.com/mechanics.run/mechanics-sdk/provider/oci
gitea.andreygubarev.com/mechanics.run/mechanics-sdk/provider/kubernetes Ten releases, seven providers, zero compatibility wrappers, and a control plane that finally contains no HTTP client it has to apologize for.