Integrate reviewed stored-chart navigation and peak help

Accept exact PI commits c670f6b6 and 647664b6: correct existing PBS and metrics guides, preserve shipped mirrors and bookmarks, and retain source-bound Docs/browser proof. Documentation maintenance adds no product surface.

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-10-14 01:57:22 +01:00
6 changed files with 249 additions and 14 deletions
+22
View File
@@ -4,6 +4,19 @@ Pulse persists metrics history to disk so trend views and sparklines survive res
## Read a History panel
In current drawers, open the affected resource's **Overview** and use **History
range** beside its charts. Proxmox guests and nodes, Docker hosts and resource
drawers (including PBS) show stored charts there instead of a separate History
tab. If your installed version still has a **History** tab, use that tab; do not
upgrade or restart just to follow this guide. A resource without a supported
history target may have no chart.
These charts are separate from **Alerts → History**, table sparklines and
current summary cards. A current card or a short trend preview does not
establish the observations in the selected stored range. For a PBS host, use
the [Backup Server chart](PBS.md#pbs-is-connected-but-history-stays-empty),
not its datastore or the VM that happens to host it.
Start with the existing chart, not a restart or a storage change. A current
reading does not prove that it was stored, and a selected time range does not
prove continuous coverage. **Window start** and **Window end** bound the
@@ -20,12 +33,21 @@ than borrowing one from the current overview.
| **current**, **last known** or **freshness unknown** with no stored history | A separately qualified fallback reading. Keep its label and explanation. | Not proof that the value was persisted or belongs to a past incident. |
| **Single observation. No trend yet.** | One stored time in that panel. | Not a flat trend or sustained recovery. |
| **Missing observations** | Some series lack readings at other stored times in that panel; lines stop across those gaps. | Not the cause or duration of a monitoring outage. Missing is not measured zero. |
| **Shaded low–high band** | The recorded minimum and maximum within an aggregated bucket, when supplied; the line shows its average. | Not continuous coverage, every original sample, or the duration of a spike. |
| **peak** while inspecting | That metric's maximum in the inspected bucket, when the panel shows it beside the average. | Not necessarily the highest value in the whole selected range or the value at an alert's exact time. |
For example, CPU **22% at 12:02** and memory **95% at 12:01** are not one
observation. At **Latest stored · 12:02**, memory is a dash if there is no
memory point at 12:02; the earlier 95% remains inspectable. Network and disk
I/O panels have their own times, not a shared snapshot of the guest.
An aggregated CPU bucket can show **22% average, 10% to 95%**. The line at 22%
does not rule out the recorded 95% peak, and the band does not say how long
that peak lasted. No visible band may mean a single reading, equal bounds or
unavailable bounds; it does not prove that usage stayed constant. Older panels
may not show these bounds. Keep that limitation rather than inferring a peak
from the line alone.
1. Keep the same resource, metric and range when comparing existing readings.
**Inspect history**, when offered, steps through stored times: focus the
slider and use the arrow keys, **Home** or **End**, or move it by touch.
+15 -7
View File
@@ -429,12 +429,19 @@ the pause. Monitoring and alerts are unavailable while Pulse is stopped.
### PBS is connected but History stays empty
Open **Proxmox → Backups → Backup Server → History**, not a datastore or the
PBS virtual machine's row in **Overview**. Record which route fails. A working
VM chart can use a different metrics target from the PBS host chart; it does
not establish that the PBS chart can read the same series. Current CPU and
memory values, a green connection badge, and an **API+Agent** label also do not
prove that stored host history is available.
Open **Proxmox → Backups**, choose the **Backup Server** row, then use the
drawer's **Overview** charts and **History range** selector. If your installed
version still has a separate **History** tab, use that tab instead; no upgrade
or restart is needed just to find the chart. This is not a datastore chart,
**Alerts → History**, or the PBS virtual machine's row in Proxmox **Overview**.
Record which route fails. A working VM chart can use a different metrics target
from the PBS host chart; it does not establish that the PBS chart can read the
same series. Current CPU and memory values, a green connection badge, and an
**API+Agent** label also do not prove that stored host history is available.
Use the chart's selected stored range, not a current summary card or table
sparkline. For observation times, missing samples and aggregated low–high bands,
see [reading a History panel](METRICS_HISTORY.md#read-a-history-panel).
Start with one affected PBS and a recent, unlocked time range:
@@ -447,7 +454,8 @@ Start with one affected PBS and a recent, unlocked time range:
2. If the target is already known, inspect the chart's request instead of
collecting the identities again. In your signed-in browser, open developer
tools → **Network**, filter for `metrics-store/history`, then open the
affected **History** tab. Do not refresh or restart the server. Inspect one
affected drawer's **Overview** charts (or **History** tab on older versions).
Do not refresh or restart the server. Inspect one
completed request for the drawer's `resourceType`, `resourceId` and `range`.
The drawer normally fetches all chart metrics together: a request **without
`metric`** is expected, so do not wait for a separate `metric=cpu` request.
@@ -0,0 +1,68 @@
{
"version": 1,
"result": "passed",
"base_sha": "c670f6b6666e6f91241e6ba2e20f77b768c3bc1e",
"changed_paths": [
"frontend-modern/public/docs/PBS.md",
"frontend-modern/public/docs/METRICS_HISTORY.md"
],
"content_sha256": {
"frontend-modern/public/docs/PBS.md": "a4e7aa00bf32f8269a20f8f1c3609214d8dadb1da79a3ed0e7b4b980789741cf",
"frontend-modern/public/docs/METRICS_HISTORY.md": "24d00753afb3bc8a15f079958d6fcb964cecfbfcf14f2f9e42e8916be5fd8250"
},
"routes": [
"/docs/PBS#pbs-is-connected-but-history-stays-empty",
"/docs/METRICS_HISTORY#read-a-history-panel"
],
"states": [
"Actual canonical/shipped Markdown through production Docs and sanitised renderer in a Vite source preview; only local security/API GET fixtures.",
"PBS host Overview chart/range versus old installed History tab, VM/datastore and Alerts History.",
"Stored observation/window semantics and aggregated averages/minimum/maximum/local peaks without continuous-coverage or incident-time claims."
],
"interactions": [
"Desktop keyboard Enter and390px WebKit touch follow both cross-guide links to existing bookmarks.",
"Scroll to bounds/peak rows and worked example in the real article. Actual served Markdown hashes match their committed producers."
],
"viewports": [
{
"width": 1440,
"height": 1000
},
{
"width": 390,
"height": 844
}
],
"verified_at": "2026-10-14T00:23:19.647Z",
"runtime": {
"playwright": "1.56.1",
"chromium": "141.0.7390.37",
"webkit": "26.0"
},
"pixel_review": {
"tool": "native view_image",
"opened": [
"chromium-pbs-navigation.jpg",
"chromium-history-navigation.jpg",
"chromium-bucket-bounds.jpg",
"chromium-peak-example.jpg",
"webkit-pbs-navigation.jpg",
"webkit-history-navigation.jpg",
"webkit-bucket-bounds.jpg",
"webkit-peak-example.jpg"
],
"observations": [
"Desktop: revised PBS host route, old-tab compatibility, Overview/range guidance and both cross-guide links are readable; the complete bounds/peak table fits the page.",
"390 px WebKit: new navigation and no-upgrade/no-restart caveat wrap within the page. All three columns of the bounds/peak rows remain readable without page overflow, and the22% average/95% peak example and its duration/constant-usage limits are visible.",
"Desktop bucket-bounds capture is byte-identical to the already presented history-navigation image; that same presented pixel content covers both cases.",
"Keyboard Enter and phone touch followed both preserved bookmarks in both directions. No API, guest, backup, credential or installed monitoring operation was performed."
],
"remaining": null
},
"browser_cleanup": {
"closed": true,
"preview_exit": 143,
"preview_signal": null
},
"evidence": "PI OUTCOME.md/RECEIPTS.md/BROWSER.json and eight retained native-inspected captures bind ten consuming cases to c670f6b6. Does not establish native guest/PBS recovery, installed acceptance, protected delivery or release availability."
}
@@ -4,6 +4,19 @@ Pulse persists metrics history to disk so trend views and sparklines survive res
## Read a History panel
In current drawers, open the affected resource's **Overview** and use **History
range** beside its charts. Proxmox guests and nodes, Docker hosts and resource
drawers (including PBS) show stored charts there instead of a separate History
tab. If your installed version still has a **History** tab, use that tab; do not
upgrade or restart just to follow this guide. A resource without a supported
history target may have no chart.
These charts are separate from **Alerts → History**, table sparklines and
current summary cards. A current card or a short trend preview does not
establish the observations in the selected stored range. For a PBS host, use
the [Backup Server chart](PBS.md#pbs-is-connected-but-history-stays-empty),
not its datastore or the VM that happens to host it.
Start with the existing chart, not a restart or a storage change. A current
reading does not prove that it was stored, and a selected time range does not
prove continuous coverage. **Window start** and **Window end** bound the
@@ -20,12 +33,21 @@ than borrowing one from the current overview.
| **current**, **last known** or **freshness unknown** with no stored history | A separately qualified fallback reading. Keep its label and explanation. | Not proof that the value was persisted or belongs to a past incident. |
| **Single observation. No trend yet.** | One stored time in that panel. | Not a flat trend or sustained recovery. |
| **Missing observations** | Some series lack readings at other stored times in that panel; lines stop across those gaps. | Not the cause or duration of a monitoring outage. Missing is not measured zero. |
| **Shaded low–high band** | The recorded minimum and maximum within an aggregated bucket, when supplied; the line shows its average. | Not continuous coverage, every original sample, or the duration of a spike. |
| **peak** while inspecting | That metric's maximum in the inspected bucket, when the panel shows it beside the average. | Not necessarily the highest value in the whole selected range or the value at an alert's exact time. |
For example, CPU **22% at 12:02** and memory **95% at 12:01** are not one
observation. At **Latest stored · 12:02**, memory is a dash if there is no
memory point at 12:02; the earlier 95% remains inspectable. Network and disk
I/O panels have their own times, not a shared snapshot of the guest.
An aggregated CPU bucket can show **22% average, 10% to 95%**. The line at 22%
does not rule out the recorded 95% peak, and the band does not say how long
that peak lasted. No visible band may mean a single reading, equal bounds or
unavailable bounds; it does not prove that usage stayed constant. Older panels
may not show these bounds. Keep that limitation rather than inferring a peak
from the line alone.
1. Keep the same resource, metric and range when comparing existing readings.
**Inspect history**, when offered, steps through stored times: focus the
slider and use the arrow keys, **Home** or **End**, or move it by touch.
+15 -7
View File
@@ -429,12 +429,19 @@ the pause. Monitoring and alerts are unavailable while Pulse is stopped.
### PBS is connected but History stays empty
Open **Proxmox → Backups → Backup Server → History**, not a datastore or the
PBS virtual machine's row in **Overview**. Record which route fails. A working
VM chart can use a different metrics target from the PBS host chart; it does
not establish that the PBS chart can read the same series. Current CPU and
memory values, a green connection badge, and an **API+Agent** label also do not
prove that stored host history is available.
Open **Proxmox → Backups**, choose the **Backup Server** row, then use the
drawer's **Overview** charts and **History range** selector. If your installed
version still has a separate **History** tab, use that tab instead; no upgrade
or restart is needed just to find the chart. This is not a datastore chart,
**Alerts → History**, or the PBS virtual machine's row in Proxmox **Overview**.
Record which route fails. A working VM chart can use a different metrics target
from the PBS host chart; it does not establish that the PBS chart can read the
same series. Current CPU and memory values, a green connection badge, and an
**API+Agent** label also do not prove that stored host history is available.
Use the chart's selected stored range, not a current summary card or table
sparkline. For observation times, missing samples and aggregated low–high bands,
see [reading a History panel](METRICS_HISTORY.md#read-a-history-panel).
Start with one affected PBS and a recent, unlocked time range:
@@ -447,7 +454,8 @@ Start with one affected PBS and a recent, unlocked time range:
2. If the target is already known, inspect the chart's request instead of
collecting the identities again. In your signed-in browser, open developer
tools → **Network**, filter for `metrics-store/history`, then open the
affected **History** tab. Do not refresh or restart the server. Inspect one
affected drawer's **Overview** charts (or **History** tab on older versions).
Do not refresh or restart the server. Inspect one
completed request for the drawer's `resourceType`, `resourceId` and `range`.
The drawer normally fetches all chart metrics together: a request **without
`metric`** is expected, so do not wait for a separate `metric=cpu` request.
@@ -0,0 +1,107 @@
import { readFileSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';
import { createGuideFixture } from './guideFixture';
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../..');
const read = (file: string) => readFileSync(path.join(root, file), 'utf8');
const shipped = (name: string) => read(`frontend-modern/public/docs/${name}.md`);
const render = createGuideFixture(shipped);
const prose = (element: Element) => (element.textContent ?? '').replace(/\s+/g, ' ').trim();
function section(name: string, fragment: string) {
const heading = render(name).querySelector(`#${fragment}`);
expect(heading).not.toBeNull();
const element = document.createElement('section');
for (let next = heading!.nextElementSibling; next; next = next.nextElementSibling) {
if (next.matches('h1, h2, h3')) break;
element.appendChild(next.cloneNode(true));
}
return element;
}
const pbs = () => section('PBS', 'pbs-is-connected-but-history-stays-empty');
const history = () => section('METRICS_HISTORY', 'read-a-history-panel');
describe('stored-chart navigation and interpretation help', () => {
it.each(['PBS', 'METRICS_HISTORY'])('ships the exact canonical %s guide', (name) => {
expect(shipped(name)).toBe(read(`docs/${name}.md`));
});
it('routes PBS to its host Overview, not its datastore, VM or alert history', () => {
const text = prose(pbs());
expect(text).toContain('Proxmox → Backups, choose the Backup Server row');
expect(text).toContain("drawer's Overview charts and History range selector");
expect(text).toContain('not a datastore chart, Alerts → History');
expect(text).toContain("PBS virtual machine's row in Proxmox Overview");
expect(text).not.toContain('Backup Server → History');
expect(text).toContain('resourceType, resourceId and range');
expect(text).toContain('a request without metric is expected');
expect(text).toContain('metrics.cpu');
expect(text).toContain('points array for that single metric');
});
it('supports older installed tabs without making an upgrade part of diagnosis', () => {
expect(prose(pbs())).toContain('If your installed version still has a separate History tab');
expect(prose(pbs())).toContain('no upgrade or restart is needed just to find the chart');
expect(prose(history())).toContain('If your installed version still has a History tab');
expect(prose(history())).toContain('do not upgrade or restart just to follow this guide');
expect(prose(history())).toContain(
'A resource without a supported history target may have no chart',
);
});
it('binds the new instructions to the current consuming drawer and control', () => {
const overview = read(
'frontend-modern/src/components/Infrastructure/ResourceDetailDrawerOverviewTab.tsx',
);
expect(overview).toContain('<GuestDrawerHistory');
expect(overview).toContain("enabled={drawer.activeTab() === 'overview'}");
expect(overview).toContain('onRangeChange={drawer.setMetricsHistoryRange}');
const panel = read('frontend-modern/src/components/Workloads/GuestDrawerHistory.tsx');
expect(panel).toContain('label="History range"');
expect(panel).toContain('point.min ?? point.value');
expect(panel).toContain('point.max ?? point.value');
expect(panel).toContain('average, ${low} to ${high}');
});
it('explains stored buckets and peaks without inventing coverage or an incident time', () => {
const text = prose(history());
expect(text).toContain('22% average, 10% to 95%');
expect(text).toContain('does not rule out the recorded 95% peak');
expect(text).toContain('does not say how long that peak lasted');
expect(text).toContain('does not prove that usage stayed constant');
const rows = [...history().querySelectorAll('tbody tr')];
const band = rows.find((row) => prose(row).startsWith('Shaded low–high band'))!;
const peak = rows.find((row) => prose(row).startsWith('peak while inspecting'))!;
expect(prose(band)).toContain('Not continuous coverage, every original sample');
expect(prose(peak)).toContain('Not necessarily the highest value');
expect(prose(peak)).toContain("alert's exact time");
expect(text).toContain('Missing is not measured zero');
expect(text).toContain('Window start and Window end bound the requested interval');
expect(text).toContain('not the first and last successful observations');
});
it('keeps both existing bookmarks and the new cross-guide links usable', () => {
for (const [element, name, fragment] of [
[pbs(), 'METRICS_HISTORY', 'read-a-history-panel'],
[history(), 'PBS', 'pbs-is-connected-but-history-stays-empty'],
] as const) {
expect(element.querySelector(`a[href="/docs/${name}#${fragment}"]`)).not.toBeNull();
expect(render(name).querySelector(`#${fragment}`)).not.toBeNull();
}
});
it('retains the safe no-replay and private-evidence investigation path', () => {
expect(prose(pbs())).toContain('Do not edit or replay the request');
expect(prose(pbs())).toContain('Do not refresh or restart the server');
expect(prose(pbs())).toContain('Do not share a HAR export');
expect(prose(pbs())).toContain('Do not delete and re-add connections');
expect(prose(history())).toContain('do not run Diagnostics or guest-agent probes');
expect(prose(history())).toContain('not chart inspection');
expect(
history().querySelector('a[href="/docs/VM_DISK_MONITORING#backup-safety"]'),
).not.toBeNull();
});
});