GitHub
10/23/2026, 7:53 PMrollout_pending or rollout_paused on the osctrld-osquery route. osctrld does not know these reasons yet. It logs them once at debug and records nothing. Nothing breaks, but the node page and status report show no reason for the skipped upgrade.
A second gap shows up once hosts are gated. While a rollout is paused, a host that already rolled back would have its remembered rollback replaced by skipped/rollout_paused. osctrl then loses the rollback, so the host drops out of its rolled-back counts and table.
Change
• Add rollout_pending and rollout_paused to the server reasons osctrld records and reports, handled like the existing server skip reasons:
• recorded as skipped with the reason and the request id
• debug-level logging only
• no package download and no call to the package server
• no state-file rewrite when the same skip repeats
• While gated, if the remembered rejection has the same request id as the answer, keep that rejection as the last result instead of overwriting it with the skip. The event id is untouched, so nothing is reported twice. A different request id records the skip as before.
• Unknown reasons are still logged once at debug and ignored, so older and newer servers stay compatible in both directions.
• Update the README sentence that lists the reasons.
Behavior notes
• A host that rolled back is not retried under the same request id after the operator resumes the rollout. This is the existing rejected-memory rule and is unchanged.
• An older osctrld release ignores the two new reasons, so it does not upgrade while gated. It also does not report them.
Security and operational impact
• No new network calls, files or privileges. The new reasons only suppress an upgrade attempt.
• osctrl validates the reason against its own allowlist, and osctrld reports only reasons in its reported set.
Validation
• go test ./... -count=1
• GOOS=windows go vet ./... and GOOS=darwin go vet ./...
• gofmt -l cmd
• `golangci-lint run ./...`: 0 issues
New tests:
• TestUpgradeStepRecordsRolloutPending and TestUpgradeStepRecordsRolloutPaused
• TestStatusReportCarriesRolloutReasons
• TestUpgradeStepRolloutReasonNeverReplacesUnreportedRejection
• TestUpgradeStepRolloutKeepsMatchingRollback
• TestUpgradeStepUnknownReasonStillIgnored
Tests were run on macOS only. They make no real network calls.
Compatibility
Pairs with the osctrl gradual-rollout change, which sends the two new reasons. Merge order does not matter: without this change osctrld ignores the reasons, and without the osctrl change they are never sent.
jmpsec/osctrldGitHub
10/23/2026, 7:56 PM