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
This commit is contained in:
Anso
2026-06-25 21:04:55 -04:00
committed by GitHub
parent 7320a86579
commit e9c262ae6a
18 changed files with 560 additions and 125 deletions
@@ -45,6 +45,14 @@ describe('settings registry', () => {
expect(hostAlerts?.scope).toBe('node');
expect(dockerStorage?.scope).toBe('node');
expect(fleetMesh?.scope).toBe('node');
const containerAlerts = SETTINGS_ITEMS.find(i => i.id === 'container-alerts');
expect(containerAlerts?.group).toBe('monitoring');
expect(containerAlerts?.scope).toBe('node');
expect(containerAlerts?.tier).toBeNull();
for (const term of ['crash', 'oom', 'healthcheck', 'container']) {
expect(containerAlerts?.keywords, `keyword ${term}`).toContain(term);
}
});
it('gates the Fleet Mesh section to admins so the sidebar entry and panel both hide', () => {
@@ -90,14 +98,17 @@ describe('settings registry', () => {
const stacks = SETTINGS_ITEMS.find(i => i.id === 'stacks');
expect(stacks?.group).toBe('infrastructure');
expect(stacks?.tier).toBeNull();
for (const term of ['stack', 'deploy', 'progress', 'diff', 'save']) {
for (const term of ['stack', 'deploy', 'guardrail', 'health gate', 'observation', 'env', 'required variable', 'progress', 'diff', 'save']) {
expect(stacks?.keywords, `keyword ${term}`).toContain(term);
}
});
it('scopes the browser-local sections (Appearance, Stacks) to the browser', () => {
it('scopes the browser-local sections to the browser', () => {
// Appearance is the only remaining browser-local section. Stacks moved to
// node scope when Deploy Guardrails (backend settings) were added to it
// alongside the existing browser-local Workflow controls.
expect(SETTINGS_ITEMS.find(i => i.id === 'appearance')?.scope).toBe('browser');
expect(SETTINGS_ITEMS.find(i => i.id === 'stacks')?.scope).toBe('browser');
expect(SETTINGS_ITEMS.find(i => i.id === 'stacks')?.scope).toBe('node');
});
it('exposes the Calm/Signature appearance keywords for search', () => {