Preserve reviewed tip 11e0946999 and incorporate exact current upstream 59ed65739c additively. Publication remains subject to combined-source validation and outstanding exact-head check repairs.
Change-source: pulse-maintainer
The drawer charts gained a min-max band (#2917) and a phone fold
(#2923); the storage disk and pool charts, drawn by the canvas
HistoryChart, had neither.
Band: each stored point is a bucket average with its lowest and highest
reading. When any bucket spreads, the chart now draws a 20% band between
them behind the line, so a short spike survives downsampling. The area
fill under the line is gone, so storage charts read like the drawer
charts; a flat series is a line alone.
Phone fold: a disk detail stacked five charts on a phone. It now shows
the first History chart plus any chart whose SMART card is out of
bounds, and folds the rest, Live I/O included, behind one button. Folded
charts read nothing until opened. The button is a shared
PhoneChartsToggle that the drawer History now uses too.
The visual pass also caught short windows repeating a time label
("Oct 2" four times); the time axis now states each label once.
Preserve the accepted cc6eb37ae9 history while incorporating current published History alert ownership and removal of the refresh control.
Change-source: pulse-maintainer
A final review of the drawer series (screenshots plus the full diff)
and a real alert on the preview found several problems:
- A Docker host drew its container's 85% memory trigger on the host's
own memory chart and turned the host reading red. Needs attention
rightly lists nested alerts; the charts now take triggers only from
getOwnAlertsForUnifiedResource, the resource's exact-key alerts.
- A container drawer listed none of its own alerts. The matcher now
answers to docker:<host>/<container id> (or /name:<name>), the key
the alert engine writes, so it lists them and charts the trigger.
- Docker and resource-detail drawers printed the alert's breach-time
message ("memory at 99.5%") beside a chart reading 70%. They now use
the shared attention copy the Proxmox drawers use: "Memory 70% now,
recovering".
- Disk temperature and storage capacity alerts reached no chart; an
alert line drawn before any history sat at an arbitrary height; the
dashed line had no visible label (the legend now says "alert at
85.0%"); a phone panel shown for an alert hid again when the alert
cleared, under a reader mid-inspection; facts strips stated a used
memory amount for a retained reading.
The Refresh history button is gone: the charts poll every 30 seconds.
Retry history still appears for a failed read, and when a successful
retry removes it, focus moves to the history region instead of the
page. Tests that used Refresh to trigger a read now advance the poll on
a fake interval clock.
The required CodeQL check misclassifies two typed API-group array membership assertions as URL substring sanitization. Use one explicit exact-equality predicate for both readers and retain the existing role, resource, verb and private-token controls. Positive and lookalike-group cases protect the equivalent matching semantics without suppressing security analysis or changing runtime behaviour.
Contract-Neutral: Test-only exact API-group predicate and regression cases; Kubernetes guide, permissions, runtime and security contracts are unchanged.
Change-source: pulse-maintainer
The deployment table still calls the typed helper a pct reader, while the implementation uses socket-free discovery and command fallback cannot recover within PrivateNetwork. Link the deployment choice, collector help and support matrix to one shipped explanation of partial, unavailable and older-helper readings, without recommending privilege or state changes.
Contract-Neutral: Guidance and consuming-proof coverage only; no telemetry, privilege, API, installer or availability contract delta.
Change-source: pulse-maintainer
The original complete Docs proof timed out in a five-second rendered-link batch. Split the same two bases, ten untrusted paths and sixteen links into separately bounded cases, retaining every setter assertion, all-path completion and the original per-base minimum of 120 rewritten links. Do not raise a timeout or change the renderer.
Contract-Neutral: Test batching only; all adversarial vectors and security predicates are preserved, with no runtime or contract delta.
Change-source: pulse-maintainer
Match the current Support navigation and phone control labels, explain absent exports, and lead reporting with existing evidence. Keep live-check, full-bundle and privacy limits intact; verify the shipped guide against the actual route and state owners.
Contract-Neutral: Existing help and diagnostic-state tests only; no runtime, renderer, routes, access, exports or live-check behaviour changes.
Change-source: pulse-maintainer
Use the renderer's preserved same-page hrefs and retain real heading-target checks. Qualify the existing OS-specific guidance without changing the renderer or guest-read behaviour.
Contract-Neutral: Correct rendered-guide test selectors only; no runtime, route or subsystem contract delta.
Change-source: pulse-maintainer
Use the assigned offline dependency export after the canonical formatter path refused a read; preserve that refusal and keep the assertions unchanged.
Contract-Neutral: Formatting of documentation regression checks only; no runtime or contract delta.
Change-source: pulse-maintainer
Existing Windows restart reports supply unsupported meminfo reads beside working guest filesystems. Explain the distinction and existing safe views without new probes, agent churn, wider permissions or an unverified recovery claim.
Contract-Neutral: Existing documentation and rendered-guide regression coverage only; no monitoring, permission, API or runtime contract change.
Change-source: pulse-maintainer
Guide existing phone readers through Show and Show fewer charts without refreshing, probing or restarting. Keep older layouts, selected ranges, empty samples and unavailable/access states distinct, and clarify that PBS CPU/memory is already in Utilization.
Contract-Neutral: Existing chart navigation help and its regression tests only; no runtime, API, access or collection contract changes.
Change-source: pulse-maintainer
Replace the removed PBS drawer History route with the current Overview chart and range control, while preserving older installed tabs and safe no-replay diagnosis. Explain bucket averages, low-high bounds and local peaks without treating them as continuous coverage or incident timestamps. Keep both shipped guide mirrors and their rendered links checked.
Contract-Neutral: Existing documentation and consuming guide tests only; no monitoring, storage, permissions, entitlement or navigation contract changes.
Change-source: pulse-maintainer
Preserve the exact 9eb52f5c candidate ancestry. Select its already browser-verified whole NodeDrawerOverview file and retain current disk guidance, pressure fixture and viewport protection. No new combined frontend content or changed release packet.
Change-source: pulse-maintainer
Preserve accepted 0efe3f7a12 and exact upstream ebfdc9d669 additively. Keep quiet unavailable captions, keyboard and touch reading explanations, stopped-agent provenance and primary CPU readings. Preserve stable denied-update help outside Details and all regression assertions.
Change-source: pulse-maintainer
The drawer range picker said "24 hours", the physical disk detail said
"Last 24 hours" and the storage pool detail said "24h", so the same
choice read three ways depending on where a reader opened history.
historyChartModel now owns one label table, and the drawer, disk and
pool pickers all take their option names from it: "1 hour", "24 hours",
"7 days". That matches how the rest of the app names durations (system
settings, Patrol schedule). The chart header's compact segmented range
buttons keep their short "24h" tokens; they are a different control and
are hidden inside these details.
Repair the two exact formatting failures found by the composed source check, without changing their assertions or product behavior.
Contract-Neutral: Mechanical formatting of tests only; no runtime or contract change.
Change-source: pulse-maintainer
The existing minimal role omitted the API metrics reads used by the collector, while its optional host recipe prescribed node-wide privilege and a shared host identity. Include only node/pod metrics reads, explain incomplete inventory and kubelet-summary limits, and replace that unsafe shortcut with deliberately separate host telemetry. Preserve the private-file Secret recipes and existing bookmarks.
Contract-Neutral: Correct existing Kubernetes operator guidance and consuming regression controls; no agent, API, RBAC runtime, token scope, entitlement or navigation change.
Change-source: pulse-maintainer
PR 2913 moved the Proxmox guest and node drawers' charts onto Overview
and removed their History tab. The Docker host drawer and the shared
resource-detail drawer (agent machines, containers, PBS, TrueNAS,
Kubernetes and other platform rows) still kept the charts a tab away,
so the same kind of drawer behaved two ways depending on the page.
Both now render the history charts on Overview under the attention
list, opening on 24 hours with the range picker beside them, and drop
the History tab. Charts stop polling while another tab shows, and an
active alert on a charted metric draws its trigger the same way as in
the Proxmox drawers. A resource whose metrics target drops for one
snapshot simply loses its charts until the target returns; the
selected tab is kept.
Storage page disk and pool details keep their own History tab; they
are separate components and their Overview has no charts to repeat.
E2E specs 27 and 63 no longer click History; the drawer read starts
when it opens. The manual tab-retention proof now selects Manage. Its
fixture page fails before the drawer renders (no WebSocket provider)
on main as well, so it was not run.
Record actual desktop and phone consuming proof and native pixel inspection. Correct the test to distinguish native same-page fragments from routed cross-document links; the served guides are unchanged. Preserve the first failed suite and its three unrelated five-second timeouts for final validation.
Contract-Neutral: Documentation proof and test correction only; no runtime contract change.
Change-source: pulse-maintainer
Replace pre-retirement plan wording, unbounded log readers and speculative re-pairing or restarts with preserved evidence, bounded server log help and the approved phone-alert alternatives. Keep existing bookmarks and continuing Relay subscriber terms. This changes server documentation only, not app or Relay behaviour.
Contract-Neutral: Existing help correction only; no app, Relay, entitlement, API or runtime contract changes.
Change-source: pulse-maintainer
Separate resource-owned PBS health and identity from inventory loading/error gates. Preserve source-specific notices, unknown counts and ordinary retries; make complete optional signing environment names readable on phones without changing trust or copying.
Change-source: pulse-maintainer
Select each rendered workflow by its unique label instead of a position. Keep every copied-command safety assertion from current source and the memory distinction from the PBS candidate; their merge changed row order, not guidance semantics.
Contract-Neutral: Documentation regression selectors only; no public behaviour or subsystem contract change.
Change-source: pulse-maintainer
Final composed frontend source-bqtf8ld2 passed types, all lint and 23379 tests, but five fixture assertions still assumed denied updates stayed outside Details and the troubleshooting intake had no copied-command row. Require neutral denied status inside usable Details while guidance and dialog identity remain visible, and cover all ten workflow entries and seventeen real heading destinations. Runtime and safety assertions are unchanged.
Contract-Neutral: Integration fixture assertions only; no runtime, documentation, graph or policy changes.
Change-source: pulse-maintainer
Keep the same API-recovery assertion while normalising Markdown whitespace, as the other guide assertions already do. Preserve the initial failed proof and unchanged five-second deadlines.
Contract-Neutral: Documentation regression assertion only; no public behaviour or contract change.
Change-source: pulse-maintainer
Add a safe missing-PBS path to the existing guide and troubleshooting entry. Separate connection polling, the server row, direct inventory and History without requesting credential changes, an agent install or repeated diagnostics.
Contract-Neutral: Documentation and consuming proof only; no API, monitoring, permissions or runtime behaviour change.
Change-source: pulse-maintainer
Use a POSIX root/sudo prefix inside the isolated subshell rather than duplicating the long quoted reader. Synchronise PTY command entry and exit with the caller prompt, retain full terminal/privacy/overflow assertions, and follow current help rows by their labels. The browser driver now inspects the full Linux card.
Change-source: pulse-maintainer
Preserve exact reviewed d636bfdaea and published 0a44d276db ancestry. Retain both contract additions, readable System evidence and stable accessible update help alongside upstream alert-first trends, facts and Details.
Change-source: pulse-maintainer
Distinguish private prompt preparation, preflight and read-only profile inspection from installation and destructive removal. Keep existing unavailable-agent and automatic-update investigations separate, and route FAQ and troubleshooting readers to the existing private-file and recovery guides.
Contract-Neutral: Help copy and rendered-document regression checks only; installer, credential, lifecycle and monitoring contracts are unchanged.
Change-source: pulse-maintainer
The Proxmox guest and node drawer Overview had grown into a grid of
equal-weight inventory cards (coverage, platform, hardware, telemetry,
thermals, observation paths), much of it repeating the table row, while
the trend that answers "is this getting worse?" sat on the History tab.
Overview now leads with active alerts, or one "No active alerts" line,
then 24h trend cards for the metrics the row shows: CPU, memory and disk
for guests; CPU, memory, CPU temperature and root disk for nodes. An
active alert on a card's metric colours it and draws the alert's own
trigger. Any warning- or danger-toned detail row moves into a "Worth
checking" section in front, so demoting inventory never hides a reason a
reading cannot be trusted. Guest filesystems, physical disks, RAID, node
GPU/NVMe sensors and any availability check that is not fresh and healthy
stay visible; a facts strip carries OS, address, a healthy last completed
backup and tags. Everything else sits in a closed Details disclosure that
keeps its rows mounted for find-in-page.
The trend cards and the History tab share one query and cache key, and
each polls only while its tab shows: the node drawer's History no longer
stays mounted and polling while hidden. Node cards read only the node's
own alerts, which the Proxmox node table now passes by identity (the
drawer's list also carries its guests' alerts by node name), and withhold live values
when the node is offline or its Proxmox readings are stale. Ranges use
bucket extremes, so an averaged-away spike still shows.
This deliberately amends the frontend-primitives rule that curated drawer
facts must not need another tap, for these two drawers only, as a named
bet in the demand ledger (pulse-pro#419) to grade at +30 days.
A guest's per-filesystem disk alert is raised under <guest>-disk-<key>,
which names nothing the resource registry can resolve, so the Alerts
overview left its name linking to the top of the platform page. A full
filesystem is the most common guest alert, and the operator still had to
find the guest among every other one.
CheckGuest now stamps the owning guest on every filesystem alert as
guestResourceId metadata: the same guest ID the guest's own alerts are
raised under, on the canonical-spec and legacy checkMetric paths alike.
The card links a filesystem alert to ?resource=<guestResourceId>, so the
workloads table opens that guest's drawer, where the Filesystems panel
shows the mount that filled. Filesystem alerts raised before this change
carry no stamp and keep the platform page link; the card never falls
back to the filesystem id.
Preserve exact Web candidate c8e4276ca4 with published alert navigation. Retain its complete source and per-content browser proof; native guest safety and restart recovery remain separate owning work.
Change-source: pulse-maintainer
Share byte-reading admission across host summaries and filesystem drawers. Keep unavailable rows neutral without counting missing capacity or unknown usage as healthy space, while preserving genuine omitted-zero bytes and independent aggregate readings. Exercise canonical resource refreshes through desktop and phone host tables and register the contract regression proofs.
Change-source: pulse-maintainer
A VM or container alert's name linked to the top of its platform page,
so after a notification the operator had to find the guest among every
other guest on Proxmox or vSphere.
The card now adds ?resource=<alert resource id> for guest alerts whose
page is Proxmox or vSphere. The shared workloads table already resolves
that id through the resource registry, opens the guest's drawer and
reveals it, so the card adds no identity mapping of its own. Other alert
types, per-filesystem guest alerts and orphaned backup alerts keep their
platform page link because their ids name nothing the table can open.
The monitoring policy menu still reads its platform from the page path.
When Pulse cannot reach the saved provider (a wrong Ollama URL, a server
that is down, a network fault), readiness reports provider_connection
and the Patrol setup card offered "Check Patrol model", with a hint that
provider connectivity can be healthy. The model check cannot fix an
unreachable provider. The card now sends the operator to Provider &
Models, where the URL and the provider test live, with a subtitle that
says Pulse cannot reach the provider. It does not open the setup panel,
because a passing network blip must not ask a cloud user for a key that
works.
The setup panel brought the AI settings client, provider configs and cost
helpers into the Patrol page chunk, which pushed AIIntelligence to
73.42 kB gzip against its 70.86 kB budget. Only an install that cannot
run Patrol needs that code, so the workspace now loads the panel
lazily and passes the readiness provider in, and the panel resolves its
starting provider itself. AIIntelligence is 70.38 kB (main 69.89 kB).
18 of 60 paid installs on the current telemetry schema have no AI
provider. Getting Patrol running meant three pages: turn on Pulse
Intelligence, pick one of 14 providers and paste a key, choose a model
from a raw list, then find Check Patrol model on another page.
When Patrol is blocked because no provider is connected, Pulse
Intelligence is off, or the provider refused the saved key, the setup
card now connects a provider in place. It covers a cloud API key
(Anthropic, OpenAI, Gemini, DeepSeek, OpenRouter) or Ollama, names the
model Pulse will use from the Patrol guidance table, prices it before
anything is saved, then saves it, runs the provider test and the Patrol
model check, and offers the first run. A per-token model on the
untouched 6-hour schedule gets the same slower schedule Patrol settings
would propose. Everything else stays on Provider & Models.
The panel stays mounted once started, because polling flips the
readiness cause mid-setup and would otherwise remove the verdict. A
refused key (provider_auth) now routes to Provider & Models instead of
the model check, which could not fix it.
Pro sells Patrol investigation, but every install starts in Watch only
and stays there unless the operator finds the mode control. In the paid
telemetry read on 12 October, 20 of 35 Pro installs with Patrol on ran
Watch only, and none of those 20 ran an investigation in 30 days, so
the feature they paid for never ran.
An install that never saved a Patrol mode now runs Ask first when it
holds a positive investigation licence. Patrol investigates new and
re-detected warning and critical findings and proposes a fix; nothing
changes without approval. The default only applies to a positive
licence answer: a missing licence checker counts as unlicensed, so a
startup window cannot spend provider budget on a free install. Free
installs and explicit choices are unchanged.
The Patrol header says so once, with the cost (the operator's AI
provider and 30-day budget) and two actions that save Ask first or
Watch only. The notice never renders on a plan-locked install. The
header also stops claiming "Watching your infrastructure" while Patrol
cannot run yet and reads "Patrol is not running yet" instead.
Reverts #2863 before any release ships it. The live Pro pricing and
Patrol pages, in English, German and Spanish, sell both modes ("applies
safe fixes in the mode you choose: Ask first, Safe auto-fix, or
Autopilot"), and paying installs chose them. Shipping the retirement
would have silently downgraded those installs while the sales page still
promised the modes.
If the modes are retired, that needs a dated notice: stop selling them
first, warn installs on those modes in-app, and then re-ship the change.
It should not arrive through an engineering cleanup.
The receipt #2863 landed stays in place; this commit adds the receipt
for the restored content.
Exact composed-source proof source-4nemvi_a passes types and four guide controls but fails locked Prettier 3.9.9. Apply that formatter only to the fixture; preserve all guide, runtime and assertion behaviour and the original failed receipt.
Contract-Neutral: Locked formatter-only test correction; no runtime or guide-content change.
Change-source: pulse-maintainer
Preserve reviewed guide commits and upstream Patrol retirement and release-registry repairs without rewriting either history.
Change-source: pulse-maintainer
Retain exact PI commits and source-bound guide proof. Explain existing display hours separately from alert days and preserve the v6.5.0 critical-Off caveat.
Change-source: pulse-maintainer
Patrol could run some fixes on its own in two paid modes: assisted (Safe
auto-fix) and full (Autopilot, behind a server-owned acknowledgement).
Schema-v17 telemetry for the week to 2026-10-11 counts 1 assisted and 2
full installs out of 612 reporting Patrol, 4 executed Patrol actions in
30 days, all on one install, and no GitHub request for more autonomy,
while the automatic path carried its own policy leases, acknowledgement
store, per-resource allowlist, release gate and Colima lab. Investigation
is what paid installs use, so it stays.
Patrol now has two modes. Watch only reports findings. Ask first
investigates and proposes fixes, and every fix waits in Actions for an
operator to approve and run it.
- A saved assisted, full or autonomous level reads as approval, and the
update routes refuse those levels with 400 invalid_autonomy_level.
- The core Patrol action broker only plans: Plan and Submit persist the
plan and return. ExecuteUnderPolicy, the policy authorization lease,
the policy admission store methods, the Autopilot acknowledgement
persistence, routes and dialog, and the per-resource automatic-action
allowlist (store column now written as NULL) are gone.
GetPatrolFullModeUnlocked stays on the extension contract and reports
false.
- Historical action records keep their policy lease and tenant/resource
reason codes decodable, labelled as retired modes.
- The Patrol inbox no longer splits issues into "continuing without a
decision"; every current issue is an operator decision.
- Release gate RG-06 now proves Patrol never executes without an operator
decision (integration tier) instead of limited unattended autonomy,
and RG-02/RG-04 point at the surviving human-admission proofs.
- Pro plan copy, AI docs, privacy telemetry wording and the subsystem
contracts describe the two modes.