Commit Graph

7 Commits

Author SHA1 Message Date
Anso e9c262ae6a feat: split Host Alerts into Host Alerts, Container Alerts, and Stacks guardrails (#1461)
* feat: split Host Alerts into Host Alerts, Container Alerts, and Stacks guardrails

Move global_crash from Host Alerts to new Monitoring > Container Alerts section.
Move health gate and env deploy guardrails from Host Alerts to
Infrastructure > Stacks > Deploy Guardrails subsection.

Host Alerts now contains only host threshold settings (CPU, RAM, disk,
alert suppression, and the master host_alerts_enabled toggle).
Stacks gains a Deploy Guardrails subsection (node-scoped, admin-gated)
alongside the existing Workflow controls (browser-local).

Dashboard Crash detection row now routes to Container Alerts.

* docs: update crash detection toggle description to match new Container Alerts section
2026-06-25 21:04:55 -04:00
Anso 8d9e6574cc feat(appearance): add Calm/Signature visual style, readability mode, and chart palette (#1407)
* feat(appearance): add Calm/Signature visual style, readability mode, and chart palette

Turn the "too intense / italic headers hurt / the security graph fights my
eyes" feedback into a token-driven Visual style with Calm as the new default
and Signature one click back to the prior look.

- Heading family routes through a `.font-heading` utility driven by
  `--font-heading`/`--heading-style`: operational headings render upright in the
  interface face under Calm and italic Instrument Serif under Signature. Base
  rule sets family + style only, so each call site keeps its own weight/tracking
  and Signature stays a true no-op; the Calm lift is a `[data-headings="clean"]`
  descendant rule. Brand lockup, empty-state heroes, and onboarding stay serif.
- Severity charts resolve through `--sev-*` tokens with Muted, Heat, and
  Signature palettes; FindingsByType routes its series through the severity ramp
  plus a neutral so no brand-cyan sits next to rose. The risk trend flattens its
  gradient under Muted/Heat/reduced and keeps the gradient under Signature.
- Appearance settings gain Visual style cards, a Security visualization palette,
  a Readability master toggle, a Motion & effects group, and a "Reset to default"
  button (restores the Calm axes, disabled while readability is on). Contrast
  moves under Readability and Ambient glow under Motion & effects. A card is
  selected only while the stored sub-axes match its preset, so a custom
  combination de-selects both.
- The topbar Theme quick-switch swaps the interface/data font pickers for a
  Visual style switch and a Readability toggle (text size kept); its footer
  Settings link jumps straight to Appearance.
- Readability is a sticky master that forces the calm resolution and a contrast
  lift at apply time without mutating the stored sub-axes.
- New users default to Calm; any pre-existing persisted appearance state keeps
  the Signature look. The pre-paint script mirrors the store.
- SegmentedControl gains a `disabled` prop and a nullable value (no active
  segment for a custom combination, with a roving-tabindex keyboard anchor).
  Adds unit/component coverage for the store, migration, chart shape logic, the
  disabled control, the reset/de-selection, and the quick-switch.

* fix(appearance): migrate Blueprint serif headings and surface readability locks

- Migrate the two operational Blueprint headings (catalog tile name, drift-policy
  option title) from font-serif italic to the .font-heading utility; the first
  pass only covered font-display, so Calm still left these italic. font-serif and
  font-display both resolve to the same display face, so this is the same fix.
- Lock the Visual style cards under Readability (parity with the topbar switch and
  the on-screen guidance to turn Readability off to choose a style by hand).
- Lock the Border brightness slider under Readability and show its forced +0.03
  readout, since Readability overrides the stored value; dragging it previously
  appeared to do nothing.
- Correct the Appearance docs sentence for the topbar quick switch (it listed
  fonts; the quick switch now carries visual style, readability, and text size).
2026-06-22 00:19:57 -04:00
Anso 058cf8f2c7 feat: make image-update check cadence configurable and visible (#1377)
* feat: make image-update check cadence configurable and visible

The background image-update scanner polled registries on a hardcoded
6-hour interval, with no way to see when it last ran or when the next
run was due. Operators testing updates read this as auto-update being
unreliable: a manual update checks the registry immediately and applies,
so the slow background scan rarely raised the "update available"
notification before the stack was already current.

Backend:
- ImageUpdateService reads image_update_check_interval_minutes (15-1440,
  default 120) and drives a single generation-guarded self-rescheduling
  timer with 10% per-run jitter so fleet nodes do not poll in lockstep.
  restartPolling() applies a new interval live, with no restart, and
  cannot leave a duplicate timer when a save lands mid-scan.
- GET /api/image-updates/status now returns checking, intervalMinutes,
  lastCheckedAt, nextCheckAt, and the manual-cooldown fields. New
  admin-only PUT /api/image-updates/interval persists the setting and
  reschedules.

Frontend:
- New Settings > Automation > Image update checks section to choose the
  interval (read-only for non-admins; admin enforced on the backend).
- The Auto-Update readiness view shows last-checked, next-check, and a
  ticking manual-recheck cooldown, and the copy distinguishes registry
  detection from scheduled auto-update execution.

Adds backend unit and route tests and frontend component tests, and
updates the auto-update documentation.

* fix: drop stale image-update status response in the readiness strip

loadCadence() ran on mount and again after a Recheck with no request
token, so a slow initial /image-updates/status response could resolve
after the recheck-triggered one and overwrite the fresh cooldown with
stale data, or set state after the view unmounted. Guard setCadence with
a monotonic token mirroring loadReadiness, and bump it on unmount. Adds a
regression test for the out-of-order resolution.
2026-06-15 20:06:13 -04:00
Anso ebf66fd92a feat(settings): add Stacks section for stack workflow preferences (#1366)
Move the browser-local Deploy progress, Progress style, and Diff preview
before save controls out of Appearance into a new Stacks section under the
Infrastructure group. These are stack lifecycle and editor workflow
preferences, not visual style, so Settings now groups them where operators
expect to find them.

Add a browser-local masthead scope so these localStorage-backed sections read
SCOPE browser instead of the misleading global, and apply it to both
Appearance and Stacks. Control behavior, storage keys, and backing hooks are
unchanged; this is an information-architecture move only.
2026-06-12 18:40:53 -04:00
Anso 2a4955f56d feat: add dedicated Security page and policy-pack foundation (#1362)
* feat: add dedicated Security page and policy-pack foundation

Bring vulnerability scanning, scan history, suppressions, Compose risks,
secrets, policy packs, and scanner setup into one node-scoped Security
command center instead of scattering them across Resources and Settings.

- New top-level Security view with Overview, Images, Compose risks,
  Secrets, Policies, Suppressions, History, and Scanner setup tabs
  (status masthead + signal rail; controlled tabs with deep-link support).
- Backend: GET /security/overview rollup and GET /security/policy-packs
  static catalog (auth-only, Community). DatabaseService gains an uncapped
  scan-status count and a node-eligible block-policy count, and
  getImageScanSummaries now projects secret and misconfig counts.
- Reuse existing surfaces: the scan-history sheet, the control-governed
  suppression and acknowledgement panels, and the scan-detail sheet (now
  with an initial-tab prop so it opens on the matching finding type).
- Extract a shared SeverityBadge (from Resources) and a TrivyManager
  (from Settings) so both surfaces render identical controls.
- Resources "Scan history" now links into the Security page History tab.
- Docs for the new Security surface and tests for the new endpoints,
  helpers, nav wiring, and tabs.

* refactor: consolidate scanner and policy management onto the Security page

Remove the Settings "Vulnerability Scanning" section now that the Security
page covers the same ground, with every option preserved:

- Scanner install / update / uninstall / auto-update live on the Scanner setup
  tab (TrivyManager).
- Scan policies, the honor-suppressions toggle, and the replica
  managed-by-control / demote controls move into a new ScanPolicyManager on the
  Policies tab (paid; Community sees only the policy-pack catalog).
- CVE suppressions and acknowledgements remain on the Suppressions tab.

Wiring removed: the registry section and the now-empty Security settings group,
the SectionId, the SettingsSectionContent case and the isPaid prop it was the
sole consumer of, and SecuritySection itself. The dashboard configuration-status
"Vulnerability scanning" row now navigates to the Security page Policies tab.

Docs that pointed at "Settings -> Security -> Vulnerability Scanning" are swept
to the relevant Security page tabs.

* fix: harden Security page scanner refresh, policy-load errors, and secret-only badges

Address independent-review findings on the Security page:

- Scanner setup now refreshes Trivy state when the active node changes, so the
  displayed scanner status matches the node TrivyManager's actions target (both
  follow x-node-id). Previously, switching nodes on the tab left stale state.
- ScanPolicyManager surfaces an explicit error state on a failed policy fetch
  instead of falling through to a false "No scan policies configured".
- The shared SeverityBadge and the Images findings column no longer label a scan
  "clean" when it has secrets or misconfigurations but no CVE severity
  (highest_severity is derived from vulnerabilities only); they show a "Findings"
  state and the secret/misconfig counts instead.
- The Overview enforcement note points to the Policies tab, not the removed
  Settings section.
- The History tab auto-opens the scan-history sheet only on a deep-link (mount
  with the History tab active), not on every manual tab selection.

Adds tests for the badge secret/misconfig state and the policy-load error state.
2026-06-12 10:41:39 -04:00
Anso 2298f470bd feat: allow local Docker Hub, GHCR, and custom registry credentials on Community (#1338)
Private registry credentials are no longer paid-only. Community admins can add
and manage Docker Hub, GHCR, and custom/self-hosted registry credentials, stored
locally on the node. AWS ECR (short-lived token refresh, AWS region) stays on the
paid tier.

Backend gates ECR per-type via a single helper applied at create, update (using
the effective type so an existing row cannot be switched to ECR), the per-id
connection test (gated on the stored type), and the stateless test. The admin
role and API-token-scope rejection are unchanged on every route. The frontend
drops the blanket paywall on the Registries section, filters ECR out of the type
selector for Community, and states the ECR requirement inline.
2026-06-08 08:59:27 -04:00
Anso ce08a593d7 feat(settings): reorganize the settings hub into domain groups (#1321)
* refactor(settings): split System Limits and regroup the hub

System Limits had grown into a grab-bag of host alert thresholds, Docker
cleanup, and mesh data-plane controls under one mislabeled section. Split it
into Host Alerts, Docker & Storage, and Fleet Mesh, and split Developer into
Developer Diagnostics and Data Retention. Reorganize the sidebar into ten
domain groups: Personal, Access, Infrastructure, Monitoring, Notifications,
Automation, Organization, Security, Operations, Help.

Each section now saves only its own keys, so a concurrent edit in one section
no longer clobbers another. Data Retention sends the audit-log window only on
a paid plan, matching the field's existing visibility, so a Community save no
longer fails on a key the operator cannot set. NumberChip moves to a shared
module and the toggle reuses the existing shared component. The /settings API
is unchanged.

* test(settings): cover registry structure and per-section save payloads

Add structural invariants for the ten-group registry (every item maps to a
real group, ids are unique, the System Limits and Developer splits land in the
right groups with the right gates, renamed labels and the Registries paid gate
hold) and per-section payload tests asserting each split section patches only
its own keys, including the Community path where Data Retention omits the paid
audit-log key.

* docs(settings): document the regrouped settings hub

Rewrite the settings reference for the ten-group layout, replace the System
Limits page with Host Alerts, Docker & Storage, and Fleet Mesh, and document
the prune-on-update, reclaimable-space banner, and mesh auto-recreate settings
that were previously undocumented. Update the Settings navigation breadcrumbs
across the feature docs and refresh the affected screenshots.

* fix(settings): show Access sections as instance-global, not operator-scoped

License, Users, SSO, and API Tokens are instance-global settings but the
masthead scope label rendered them as operator-scoped because it keyed off the
old Identity group. Only Personal sections (account, appearance) are
operator/browser-scoped now; everything else reads as global.

Also add a compile-time exhaustiveness guard to the section switch so a future
SectionId added without a matching case fails the build instead of silently
rendering a blank panel.

* docs(settings): remap remaining settings breadcrumbs to the new groups

Update the navigation breadcrumbs that still pointed at the removed Identity,
Alerts, and Advanced groups: API Tokens and Users now sit under Access, Webhooks
under Automation, Labels under Organization, App Store under Infrastructure,
Appearance under Personal, and scan policies under Security > Vulnerability
Scanning. Correct the settings reference scope note so Access reads as global.

* docs(settings): remap renamed-section breadcrumbs across feature docs

Sweep every feature, operations, getting-started, and reference page for
navigation paths that still named the renamed settings sections, and point them
at the current ones: Security becomes Security > Vulnerability Scanning,
Notifications becomes Notifications > Channels, Routing becomes Notifications >
Notification Routing, and Developer becomes Operations > Developer Diagnostics
(with its retention windows under Operations > Data Retention). App Store moves
under Infrastructure and the four-group overview in the getting-started intro is
rewritten to the ten groups. Separators each page already used are preserved.
2026-06-05 23:01:37 -04:00