Remove dead autoUpdateCheckInterval and autoUpdateTime settings

Found while triaging #1643 and #1637: both fields were stored via
system.json and accepted, validated, and echoed by the settings API,
but nothing ever consumed them. The unattended update schedule is owned
entirely by the systemd timer install.sh renders, and no UI control ever
set the fields, so the API persisted a schedule preference that could
never take effect.

Remove the fields from config.Config, SystemSettings, the settings
handlers, and the frontend config type, along with the interval
validation and the .env AUTO_UPDATE_CHECK_INTERVAL rewrite (a legacy
line is now preserved verbatim). Legacy clients that still send the
keys get them silently ignored instead of validated, and a system.json
written before the removal still loads cleanly - both behaviors are
pinned by new tests. User docs no longer describe the phantom schedule
settings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
courtmanr@gmail.com 2026-07-28 11:12:16 +01:00
parent 9db25ba60e
commit 193c96afc3
19 changed files with 151 additions and 139 deletions

View file

@ -58,7 +58,7 @@ In **Settings → System → Updates**:
| Setting | Description |
|---------|-------------|
| **Update Channel** | Stable (recommended for production) or Pre-release (opt-in preview) |
| **Auto-Check** | Background update check interval (hours); `0` disables |
| **Auto-Check** | Enable or disable automatic updates |
### Stored Settings (system.json)
@ -67,13 +67,11 @@ Auto-update preferences are stored in `system.json` and edited via the UI.
```json
{
"autoUpdateEnabled": false,
"updateChannel": "stable",
"autoUpdateCheckInterval": 24,
"autoUpdateTime": "03:00"
"updateChannel": "stable"
}
```
**Note:** `autoUpdateTime` is stored for UI reference. The systemd timer still runs on its own schedule (02:00 + jitter). Background update checks follow `autoUpdateCheckInterval`.
**Note:** The update schedule itself lives in the systemd timer (daily at 02:00 plus up to 4 hours of random delay), not in `system.json`. The legacy `autoUpdateCheckInterval` and `autoUpdateTime` fields were never consumed by anything and are ignored if present in older files.
**Channel policy note:** `stable` is the default and only recommended channel for paid or production environments. `rc` remains the internal channel key, but the user-facing meaning is an explicit pre-release preview path. In v6, unattended systemd auto-updates remain `stable`-only even if `updateChannel` is set to `rc`.

View file

@ -144,7 +144,6 @@ Controls runtime behavior like logging, polling intervals, and UI preferences. L
```
> **Note**: `logFormat` is only configurable via the `LOG_FORMAT` environment variable, not in `system.json`.
> **Note**: `autoUpdateTime` is stored by the UI, but the systemd timer uses its own schedule.
</details>
### Supported system.json Keys
@ -170,8 +169,6 @@ Numeric intervals are **seconds** unless noted otherwise.
| `webhookAllowedPrivateCIDRs` | Allowlist for private webhook targets |
| `updateChannel` | Update channel (`stable` or `rc`) |
| `autoUpdateEnabled` | Allow one-click updates |
| `autoUpdateCheckInterval` | Update check interval (hours) |
| `autoUpdateTime` | UI-stored preferred update time |
| `publicURL` | Public URL used in links/notifications |
| `hideLocalLogin` | Hide username/password login form |
| `temperatureMonitoringEnabled` | Enable temperature monitoring (where supported) |
@ -354,10 +351,8 @@ These are stored in `system.json` and managed via the UI.
| ----- | ------------- | --------- |
| `updateChannel` | Update channel (`stable` or `rc`) | `stable` |
| `autoUpdateEnabled` | Allow one-click updates | `false` |
| `autoUpdateCheckInterval` | Background update check interval in hours (`0` disables) | `24` |
| `autoUpdateTime` | Stored UI preference (systemd timer has its own schedule) | `03:00` |
> **Note**: Update settings are stored in `system.json`. Legacy `.env` entries (`UPDATE_CHANNEL`, `AUTO_UPDATE_ENABLED`, `AUTO_UPDATE_CHECK_INTERVAL`, `AUTO_UPDATE_TIME`) are kept in sync for backwards compatibility but are not read at runtime.
> **Note**: Update settings are stored in `system.json`. Legacy `.env` entries (`UPDATE_CHANNEL`, `AUTO_UPDATE_ENABLED`) are kept in sync for backwards compatibility but are not read at runtime. The former `autoUpdateCheckInterval` / `autoUpdateTime` fields were never consumed and are ignored if present; the update schedule lives in the systemd timer.
>
> `stable` is the default and recommended production channel. `rc` is an
> opt-in preview channel. In v6, unattended systemd auto-updates remain

View file

@ -2201,6 +2201,15 @@ Agent` secondary handoff against the live setup wizard instead of relying
## Current State
### Shared system-settings boundary dropped dead auto-update schedule fields
The shared `internal/api` system-settings surface this subsystem consumes
(`internal/api/system_settings.go`, `internal/api/config_system_handlers.go`)
removed the never-consumed `autoUpdateCheckInterval` / `autoUpdateTime`
fields. No agent-lifecycle behavior keyed off them — agent update targeting
and command admission are unaffected — and the extension-point expectations
on the system-settings boundary are otherwise unchanged.
### Monitor housekeeping prunes only live memory-evidence caches
The shared monitor housekeeping pass in `internal/monitoring/monitor_agents.go`

View file

@ -3668,6 +3668,21 @@ auto-register mutation boundary.
## Current State
### System settings shed the dead auto-update schedule fields
The system settings payload (`internal/config.SystemSettings`, projected by
`internal/api/config_system_handlers.go` and mutated through
`internal/api/system_settings.go`) no longer includes
`autoUpdateCheckInterval` or `autoUpdateTime`. Nothing ever consumed the
fields — the unattended update schedule is owned entirely by the
install.sh-rendered systemd timer, and no UI control set them — so the API
accepted, validated, and persisted a schedule preference that could never
take effect. Legacy clients may still send the keys: the update endpoint
ignores them without a validation error and never writes them back into
`system.json`. `TestSystemSettingsUpdate_LegacyAutoUpdateFieldsIgnored` in
`internal/api/system_settings_telemetry_test.go` and the response snapshot in
`internal/api/contract_test.go` pin that payload shape.
### Connections command-channel liveness tolerates stale host token IDs
The `/api/connections` ledger's `RemoteControl` and `CommandPolicy` signals

View file

@ -575,6 +575,21 @@ tokens, and path-normalization variants.
## Current State
### System settings mutation surface no longer accepts dead schedule inputs
The governed system-settings write path in `internal/api/system_settings.go`
and the runtime config in `internal/config/config.go` dropped the
`autoUpdateCheckInterval` / `autoUpdateTime` fields, which were stored but
never consumed by any runtime. Dead accepted-but-unread input is surface the
security review has to reason about for no benefit, so the fields, their
validation, and their persistence were removed together. Legacy keys in a
POSTed settings body are ignored rather than rejected, and a `system.json`
written before the removal still loads cleanly with the legacy keys ignored
(`TestLoad_IgnoresLegacyAutoUpdateScheduleFields` in
`internal/config/config_load_test.go`,
`TestSystemSettingsUpdate_LegacyAutoUpdateFieldsIgnored` in
`internal/api/system_settings_telemetry_test.go`).
### Canonical mutation-plane dependency
Raw command, file-write, arbitrary pod-exec, and legacy remediation authority

View file

@ -1985,6 +1985,15 @@ that Safe auto-fix or Autopilot remediation is verified.
## Current State
### Shared system-settings boundary dropped dead auto-update schedule fields
The shared `internal/api` system-settings surface this subsystem consumes
(`internal/api/system_settings.go`, `internal/api/config_system_handlers.go`)
removed the never-consumed `autoUpdateCheckInterval` / `autoUpdateTime`
fields. Persisted `system.json` files that still carry the legacy keys load
cleanly with the keys ignored, so tenant workspace preservation and recovery
flows that copy `system.json` forward are unaffected.
### Agent exec token binding repairs are fail-closed durable writes
Command-token binding metadata (`bound_agent_id`, `bound_hostname`,