Commit Graph

4843 Commits

Author SHA1 Message Date
pulse-triage[bot] 7cbde2e3bf Keep observed unacknowledged alerts through retention cleanup
Age-based housekeeping deleted continuing conditions when automatic acknowledgement was disabled. Require last-observation inactivity as well as occurrence age, retain legacy timestamp fallback and inactive cleanup, and document the unchanged acknowledgement/recovery boundaries. Regression exercises cached, absent and failed Docker registry reports, callback/history identity and actual checkpoint restart.

Change-source: pulse-maintainer
2026-10-01 01:26:14 +01:00
pulse-triage[bot] 5dea312f2b Bound asynchronous alert checkpoints during bursts
Coalesce full active-alert snapshots into one worker and one requested follow-up instead of queueing a goroutine per mutation. Preserve immediate lifecycle durability, fresh snapshots, failure recovery and the final shutdown save; reproduce the old burst amplification and validate the new admission and persistence boundaries.

Change-source: pulse-maintainer
2026-10-01 00:28:53 +01:00
courtmanr@gmail.com 119ac49d10 Keep the update progress modal moving when the update stream goes quiet
Updating to v6.4.5-rc.5 and then v6.4.5 left the progress modal on
"Downloading update... 10%" even though the update finished in the
background. The status stream could go silent behind a proxy (Tailscale
Serve, nginx buffering) and the modal only advanced on stream events.

Backend: the update SSE endpoint now sends the current status on connect,
writes events through one ordered writer with an explicit flush, sends a
15s heartbeat and sets X-Accel-Buffering: no.

Frontend: a silence watchdog falls back to status polling, the restart
phase is entered only on real restart evidence (restarting status, the
server going away, or a version change) rather than a single failed poll,
and the page never auto-reloads on unconfirmed completion without a
pre-update version baseline to compare against.
2026-09-30 23:39:35 +01:00
pulse-triage[bot] b0a4d2f392 test(telemetry): run background health checks with a test delay
Retain the two-minute production constant and extract the same background runner with an explicit test-only delay argument. Correct the startup non-blocking regression after exact-source proof found its invalid constant assignment.

Contract-Neutral: Extract the unchanged telemetry background runner for deterministic testing; production scheduling, payload and privacy contracts are unchanged.
Change-source: pulse-maintainer
2026-09-30 21:46:58 +01:00
pulse-triage[bot] fffaa64e57 fix(server): make local service-health probes dual-stack and bounded
Try both loopback families for IPv6 wildcard listeners without changing explicit or IPv4-only binds. Reserve each family a share of the API deadline, keep all later checks on the responding address, and retry a failed observation once with a fresh bounded budget in the telemetry background runner.

Keep genuine API, UI and asset failures visible and report only a closed timeout category, never transport details. Cover both real listener families, startup recovery, failure and privacy boundaries; synchronise the disclosure and subsystem contract.

Change-source: pulse-maintainer
2026-09-30 21:36:39 +01:00
pulse-triage[bot] 21a35494ae fix(truenas): request supported reporting aggregations
Use TrueNAS default summaries for reporting queries so SCALE 25.04 can validate its History responses. Preserve raw samples, time windows, CORE live telemetry and existing error boundaries.

Refs #2346

Change-source: pulse-maintainer
2026-09-30 19:48:10 +01:00
pulse-triage[bot] 901274ee92 Reduce snapshot and clone allocations without trusting ID hints
Batch WebSocket identity decoding from the encoded arrays and retain decoder-owned entry buffers. Keep canonical metadata refresh on every resource clone while replacing membership maps with small scope slices and a single sensitivity-tag scan. Preserve delta identity, scope ordering, policy precedence and clone isolation with reference/fuzz and transition tests.

Adapt the remaining performance work proposed in Pulse PR #2342 for issue #2199. The contributor's first-ID check cannot verify a stale tail; this candidate uses standard JSON decoding for every encoded identity instead. Keep the imported contributor history and branch unchanged.

Co-authored-by: Andy Prosser <andy.prosser@icloud.com>
Based-on: https://github.com/rcourtman/Pulse/pull/2342
Original-Commit: 0cbfa43186
Change-source: pulse-maintainer
2026-09-30 13:21:56 +01:00
pulse-triage[bot] ffc44a0f8c Honour configured alert flapping thresholds above ten
A fixed ten-entry history made accepted higher thresholds unreachable and silently disabled storm suppression. Bound retained observations to the configured threshold while preserving the existing diagnostic allowance, expiry and one-shot cooldown. Verify normal config updates, callback admission, delivery diagnosis, window expiry, rearming and threshold changes, and register the focused proof owner.

Change-source: pulse-maintainer
2026-09-30 08:12:35 +01:00
pulse-triage[bot] a0081d676b Keep PBS Agent identity fresh and reject host-local IP matches
Direct PBS host correlation could lend Agent History and SMART ownership through loopback, Docker-local or stale address evidence, and a stale Agent could block its fresh replacement. Reuse the provider address filter and the five-minute observation boundary, preserve IPv6 URL hosts, and cover unsafe evidence, private management controls, link replacement and the three-PBS/nine-Agent topology.

Change-source: pulse-maintainer
2026-09-30 00:36:07 +01:00
pulse-triage[bot] 2ad36fe4d1 Reject PBS connection labels as Agent identity
A user-chosen PBS label could attach an unrelated Agent before the exact guest-IP/Agent link was evaluated, putting host History and SMART ownership on the wrong server. Use reported node and endpoint evidence instead, and cover both the collision and label-only cases.

Change-source: pulse-maintainer
2026-09-29 23:52:56 +01:00
pulse-triage[bot] 4363493597 Correlate PBS guest agents through fresh PVE IP evidence
When a PBS API token cannot report nodeName and the in-guest Agent omits interface addresses, use a unique running PVE VM at the exact PBS endpoint IP plus its state-owned Agent link. Reject stale or ambiguous observations instead of guessing from display names. This restores the source-native host target for corroborated PBS VMs while preserving the separate PBS service target.

Change-source: pulse-maintainer
2026-09-29 23:28:27 +01:00
pulse-triage[bot] 463482f67d Make PBS recovery history test bucket-safe
The metrics store retains second-resolution samples. Verify a changed observed memory value after recovery, rather than requiring a second row when polls share a bucket.

Change-source: pulse-maintainer
2026-09-29 22:56:34 +01:00
pulse-triage[bot] 5e57a07780 Record PBS node status in service History
Persist measured PBS CPU and memory on the service metrics target when node status succeeds. Keep host-agent history separate and avoid false samples on unavailable status. Cover service reads, denial and recovery.

Change-source: pulse-maintainer
2026-09-29 22:53:25 +01:00
pulse-triage[bot] fd9e836ca4 Notify continuing symptoms after primary recovery
A supported endpoint failure may outlive its primary host incident. When synthesis removes the supported cause, dispatch its first independent notification without reopening the occurrence or duplicating a symptom previously notified before grouping.

Change-source: pulse-maintainer
2026-09-29 21:18:19 +01:00
pulse-triage[bot] 38b66ad000 Keep supported symptoms out of escalation delivery
A verified primary infrastructure alert already owns the initial notification for its supporting symptoms. Apply that same ownership to scheduled escalation, queued callback admission, and quiet-hours replay so a late duplicate cannot be sent. Preserve independent escalation for uncorroborated observation sets.

Change-source: pulse-maintainer
2026-09-29 20:51:42 +01:00
pulse-triage[bot] 82cdcd8f61 Keep monitor-only alerts out of escalation and replay
Treat monitor-only as terminal before quiet-hours replay and flapping, and reject scheduled or queued escalations when the current alert is monitor-only. Align firing, recovery and delivery diagnosis with that policy; cover ordinary and critical-repeat scheduling plus a policy change after callback queueing.

Change-source: pulse-maintainer
2026-09-29 20:06:55 +01:00
pulse-triage[bot] e2430fb759 Stop operator-suppressed alerts before delivery dispatch
Keep resource maintenance, mute and expected-offline policy terminal in the internal alert callback path. Quiet-hours deferral remains replayable, while delivery diagnosis and event history report the actual operator suppression. Cover pre-reconciliation active alerts and unaffected performance signals.

Change-source: pulse-maintainer
2026-09-29 19:35:43 +01:00
pulse-triage[bot] a5aa881ac5 Treat resource identity lists as sets in change history
Avoid configuration-history rows when source merges only reorder identity addresses or represent an absent list as empty. Real identity changes remain recorded. The #2319 serial-bearing disk fixture and registry-generation check cover the tags-only and no-op identity paths.

Change-source: pulse-maintainer
2026-09-29 19:11:39 +01:00
pulse-triage[bot] 0204fe000f Keep Agent-only SMART disks out of PVE poll readback
Linked Agent SMART disks inherit a PVE instance for presentation. Restrict skipped-poll readback to actual PVE observations so an empty disks/list cannot alternate fabricated inventory, tags and history rows. Pin repeated cycles and the source boundary in the monitoring contracts.

Change-source: pulse-maintainer
2026-09-29 18:16:44 +01:00
pulse-triage[bot] 5e7c6bb7d9 Restore PBS History for mixed Agent and PVE sources
Preserve the registry-corroborated PBS-to-Agent link on the service row while selecting the Agent host metrics target in the Backups drawer. Reject PVE-only name collisions and retain the target through a transient missing host row. Recompose the unchanged #1723 runtime repair on current main with fresh desktop and phone browser proof.

Change-source: pulse-maintainer
2026-09-29 17:43:53 +01:00
rcourtman 97f894b009 Retire Relay labels and upsells inside Pulse
Relay left public checkout on 2026-09-29: it only ever connected the
Pulse Mobile app, which retires on 31 March 2027, and existing Relay
subscribers now carry Pro entitlements. The app still sold it. Every
Community install saw a "Get alerts on your phone ... Available with
Relay and Pro plans" upgrade panel on Alerts destinations, the plan
screen offered a Relay card with "Remote web access via Relay", and the
settings section was called Remote Access although Relay never reached
the web UI.

The Alerts push panel now renders only on instances that have the relay
feature, with no upsell. The settings section, nav, header and locale
catalogs say Pulse Mobile and carry the retirement date. Community sees
only the Pro comparison card and Relay-tier licenses see none; gated
mobile features name Pro as their minimum plan. The relay feature is
labelled "Pulse Relay (Mobile Connection)" in the catalog, plan copy no
longer claims remote web access, the backend pairing diagnostics point
at Settings > Pulse Mobile, and the user docs, including PRIVACY.md,
state that Relay does not provide remote web UI access.
2026-09-29 13:19:54 +01:00
pulse-triage[bot] e4dbbcde8a Preserve sensor chip on sysfs fallback name collision
An existing cpu_thermal chip with an unusable CPU value can still carry valid fan readings. Use a free synthetic CPU-chip key instead of replacing that entry when supplementing Pulse #2311, and cover the collision with a regression test.

Change-source: pulse-maintainer
2026-09-28 21:42:58 +01:00
pulse-triage[bot] b5360c1e5a Supplement unusable CPU sensor output from sysfs
A named CPU chip with no valid CPU temperature must not suppress an identified SoC thermal reading. Preserve other lm-sensors readings and existing valid CPU precedence.

Change-source: pulse-maintainer
2026-09-28 21:17:04 +01:00
pulse-triage[bot] 2eff4c9954 Supplement non-CPU sensor output with identified sysfs temperature
When lm-sensors returns disk or other readings without a CPU chip, retain those readings and add a bounded, identified SoC temperature from sysfs. Preserve existing CPU output and ignore unusable optional sysfs data. Cover combined and precedence paths for Pulse #2311.

Change-source: pulse-maintainer
2026-09-28 21:02:38 +01:00
pulse-triage[bot] 60f455fd2a Read identified ARM CPU temperatures without lm-sensors
Fall back to bounded, type-checked thermal-zone and hwmon sysfs readings when lm-sensors is absent or empty. Classify Armada thermal JSON as a CPU reading, preserve nonempty sensor output, and cover units, invalid values, and the agent mapping.

Change-source: pulse-maintainer
2026-09-28 20:26:28 +01:00
pulse-triage[bot] 5b249fb307 Match structured PBS comments to guest backup badges
Recognise exact node.VMID.name notes on Root PBS snapshots so a newer completed CT backup can replace an older name-only match. Keep colliding VMIDs fail-closed when node and name do not distinguish connections, and cover completed and in-flight attribution for Pulse #2292.

Contract-Neutral: Preserve backup attribution safety without changing API fields, persisted shapes, or source contracts.
Change-source: pulse-maintainer
2026-09-28 19:43:42 +01:00
pulse-triage[bot] cbb9122bcc Merge commit 'ad15366f3dc02480ede74dce80a074c190e83d3c'
Change-source: pulse-maintainer
2026-09-28 16:07:25 +01:00
Richard Courtman 3cb5d5bef2 Show container-console route for the setup token
The unlock screen told Docker users to run `docker exec` from the host,
which does not fit the Unraid, Portainer and TrueNAS app UIs, where the
console already runs inside the container. Those `container_other`
installs are the largest group stalling before first setup: in the week
to 2026-09-28, 158 of 3114 persistent Docker installs never got past
first start, against 94 of 5462 binary and systemd installs.

The startup log also suggested revealing the token "by reading the token
file path". That file holds ciphertext, as the security-privacy contract
requires, so anyone following the hint pasted JSON the unlock screen
rejects. The log now names the command, including the console form, and
the install docs and the contract gain the same guidance.

Contract-Neutral: copy-only: new unlock-screen command row and corrected startup log text; no API payload, lifecycle, storage or primitive change; owning security-privacy clause updated
2026-09-28 15:29:15 +01:00
pulse-triage[bot] 894d7409b7 Merge pre-batch upstream main dispatch repair
Incorporate protected Pulse #2300 at the batch frontier while preserving reviewed local health-gate test commits.

Change-source: pulse-maintainer
2026-09-28 12:57:07 +01:00
courtmanr@gmail.com 9e2ee3d535 Fail typed dispatches fast when their agent session drops
The agentexec read loop removed a dead session from the agent map but never
closed its done channel, so any dispatch already sent on that session kept
waiting for a result that could never arrive and only returned at its
operation timeout. That's what made the Proxmox cancellation replay test
flaky on the shared CI runner. The restarted action runner dropped its first
session right after registering, the replay had already been sent there,
and the server waited the full 30s while the runner sat reconnected on a
new session.

The read loop now signals the session done on exit, so in-flight typed
dispatches and commands report the disconnect straight away. The
integration test sends the same request again on the runner's next
session when that happens, which is the same durable replay it is there
to prove, still with exactly one mutation. It also keeps the runner's log
and prints it on failure so the cause of any future drop is visible.
2026-09-28 10:31:58 +01:00
pulse-triage[bot] bc3a73063a Make release health-gate tests synchronize on observed state
Wait for the agent supervisor to check false readiness before asserting its commit gate, and give the race-instrumented fixture a non-expiring window. Hold the monitoring request at target resolution after its history snapshot so replacement is deterministic. Keep production paths and assertions unchanged.

Change-source: pulse-maintainer
2026-09-28 10:27:09 +01:00
courtmanr@gmail.com d4ef5a1910 Merge remote-tracking branch 'origin/main' into fix/updates-tests-arm64
# Conflicts:
#	internal/updates/issue2285_update_check_observation_test.go
2026-09-28 08:44:55 +01:00
courtmanr@gmail.com 130fc61061 Give update-check test fixtures the exact runtime archive
Main is failing Backend tests (rest-1) on
TestIssue2285LastUpdateCheckRecordsEffectiveChannelOutcome. The exact
server archive rule (ab0aa1ef0) offers an update only when the release
carries the archive for the host architecture, and the #2285 test
releases carried no assets, so its update-offered cases could never
report available. The two check tests also hard-coded a linux-amd64
archive, which failed on arm64 hosts.

Build every fixture archive from the same runtime asset helper the
updater uses. Test only.
2026-09-28 08:28:16 +01:00
pulse-triage[bot] f7a43d2794 Retain observed Docker update alert age through cleanup
Hourly cleanup previously aged pending image updates by first detection, so a continuing update older than 24 hours lost its tracking and could restart its delay. Track observation activity separately, keep unknown checks pending, and reclaim state when observations stop or an affirmative clear arrives. Cover 24- and 48-hour delays and cleanup.

Contract-Neutral: Preserve the existing Docker update alert policy and public contract while correcting internal tracking expiry.
Change-source: pulse-maintainer
2026-09-28 05:03:26 +01:00
pulse-triage[bot] d704afa68a Reject shared-node PBS ties despite learned source
A globally observed second cluster can leave a PBS source apparently mapped to the first while both clusters match a shared-node snapshot. Do not promote a positive but tied guest match into the VMID-only inference path. Regression covers both VM and CT completed and in-flight snapshots with the second cluster visible on another PBS instance.

Contract-Neutral: Preserve existing PBS backup attribution safety without changing API fields, persisted shapes, or source contracts.
Change-source: pulse-maintainer
2026-09-28 04:32:02 +01:00
pulse-triage[bot] 7d7b1a0b85 Scope PBS backup recency to uniquely attributed guests
A newer snapshot from another cluster can share the same typed VMID and node namespace. Compare each positive match with competing guests before selecting by recency; a stronger competitor excludes it and a tie needs independent attribution. Cover VM and CT completed and in-flight snapshots while preserving the newer weaker unique match.

Contract-Neutral: Repair existing backup badge attribution and age selection without changing API fields, persisted shapes, or PBS source contracts.
Change-source: pulse-maintainer
2026-09-28 04:25:04 +01:00
pulse-triage[bot] 6f99faf268 Use newest attributable PBS snapshot for guest backup badges
A stronger namespace or comment score currently makes an old snapshot beat a newer, still attributable snapshot. Keep the existing typed-VMID and cross-instance eligibility guards, then choose the latest eligible backup for LastBackup and in-flight state. Add VM and CT regressions for unique fallback and colliding IDs.

Contract-Neutral: Repair existing backup-age selection without changing API fields, persisted shapes, or PBS attribution eligibility.
Change-source: pulse-maintainer
2026-09-28 04:09:20 +01:00
pulse-triage[bot] c941a1165a Keep queued alerts safe and restore reliable update checks (#2288)
## What changed and why
Keep queued notifications from being cancelled while saved destinations
load, and make stable-channel update discovery work with GitHub's large,
prerelease-heavy release list (#2282). Update download selection now
requires the exact server archive for the runtime architecture; ARMv6
and ARMv7 are distinguished by the build variant rather than silently
choosing ARMv7. The batch also retains the reviewed disk-monitoring
round-trip correction.

## Reviewed source

`b1e75fb9e4693c5706b2242760d6277e5291e7f9..18f2dc1f19416bd83ab72e7f82f2287063b0bedc`
(notification test isolation and startup gate, integration of update
metadata, exact-archive selection, ARM variant correction).

## Validation
Provenance and diff checks passed for the complete range. Prior
committed-source offline proofs passed for the update package through
`ab0aa1ef02698f7727b134a6f6b5ed520930cc61` and for the notification
startup race scenario. The new ARM mapping has a focused regression test
in this head; exact-head protected CI remains required before landing.
These source checks do not establish installed update or alert-delivery
results, nor release readiness.


[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-09-28 00:10:29 +00:00
pulse-triage[bot] 3a362f0afb fix(updates): report installability-aware update checks
Combine the protected schema-v18 sender with the exact-archive updater. Require installable archives in positive fixtures, classify missing archives and unavailable Pro checks without claiming an offer, and avoid caching an unactivated Pro result. Record the contract and exact combined-source browser receipt.

Change-source: pulse-maintainer
2026-09-28 00:53:28 +01:00
pulse-triage[bot] 6d7e3342e5 Merge protected update-check telemetry into exact-archive candidate
Combine the reviewed main-line sender with the in-flight archive correction so the interaction can be repaired and proved at exact source.

Change-source: pulse-maintainer
2026-09-28 00:41:20 +01:00
courtmanr@gmail.com 81e92bff95 Report update channel and last update check outcome in telemetry (#2285)
A failed update check never reaches the update history, because nothing
was applied, so telemetry could not tell an install whose check is broken
from one that was offered an update and ignored it. The 6.4.3-rc.1 installs
looked healthy while their check failed on every call (#2282).

The update manager now records a closed outcome for every check on the
install's effective channel (up_to_date, available, no_release,
rate_limited, network_error, metadata_error, skipped, error), tagging
lookup failures without changing their error text, and ignores previews of
another channel from Settings. Telemetry schema v18 exports update_channel,
update_check_outcome and update_available. No version, URL or error text
leaves the install. The Settings preview type, privacy disclosure, adoption
report and subsystem contracts are updated to match; the Pulse Pro receiver
change lands separately and the parity check passes against it.
2026-09-27 23:50:23 +01:00
pulse-triage[bot] 18f2dc1f19 fix(updates): select ARM release archive from build variant
ARMv6 and ARMv7 server binaries both report GOARCH=arm. Read the release binary GOARM build setting and fail closed when it does not name a published server archive, rather than offering an ARMv7 update to ARMv6 installations. Cover the architecture mapping and document the installability boundary.

Change-source: pulse-maintainer
2026-09-27 23:29:44 +01:00
pulse-triage[bot] ab0aa1ef02 fix(updates): require exact server archive for update download
Release metadata contains agent, MCP and multiple architecture archives. An incomplete release must not offer an unrelated tarball or advertise an update that cannot be applied. Retain server archive names only, require the exact tag and runtime architecture, and record this installability boundary with regression coverage.

Change-source: pulse-maintainer
2026-09-27 23:08:56 +01:00
pulse-triage[bot] e02eeb8fa3 Merge reviewed update metadata repair into Core candidate
Change-source: pulse-maintainer
2026-09-27 22:41:23 +01:00
courtmanr@gmail.com daef38dd3c Stream release metadata so update checks see stable releases (#2282)
GitHub's release list is now ~9.6 MB because every 6.4.x release embeds
349 assets (~600 KB of JSON each). The update check buffered the whole
response behind a 1 MiB bound, so the primary path always failed and fell
through to the Atom feed. That feed holds ten entries and each release now
spends three of them, so stable-channel checks on main failed outright
("no suitable release found for channel stable") and 6.4.5 stable would
have shipped relying on it.

Decode the release list and the single-release notes response as a token
stream, keeping only tag, name, body, draft, prerelease, publish time and
the Pulse linux server archives. Memory now tracks what the updater keeps,
so the byte bound rises to 64 MiB while staying typed; the Atom feed stays
as the last resort for that over-limit condition only.

Verified against live GitHub: stable resolves v6.4.1 and rc resolves
v6.4.5-rc.3 through the primary path with no feed fallback.
2026-09-27 22:07:42 +01:00
pulse-triage[bot] 25e526b7e5 fix(notifications): gate queued work until destinations load
The monitor restored notification destinations after constructing a queue whose five-second ticker could consume due jobs. Defer processor installation through destination restore, then wake the backlog before external alert callbacks admit first agent reports. Cover both forced pre-configuration processing and the actual monitor restart path; update the notifications, monitoring and agent-lifecycle contracts.

Change-source: pulse-maintainer
2026-09-27 17:58:07 +01:00
pulse-triage[bot] 75aaf1391c test(notifications): isolate queued routing snapshot
SetProcessor wakes the live queue worker while this test processes a fetched row manually. Defer the row beyond GetPending before installing the processor so a competing worker cannot decide the synchronous assertion.

Change-source: pulse-maintainer
2026-09-27 17:28:04 +01:00
pulse-triage[bot] e85f1a4eed fix(alerts): preserve empty PVE disk alert reference
Keep the persisted empty-device alert ID distinct from the root-device ID while excluding incomplete disks from alias claims. Extend the unified-resources contract and identity tests in the same commit.

Change-source: pulse-maintainer
2026-09-26 21:39:11 +01:00
pulse-triage[bot] 5817c95153 fix(alerts): resolve PVE disk alerts to physical-disk policy
Keep persisted PVE disk alert identities stable while indexing them as exact physical-disk aliases. A muted disk now clears and suppresses its wearout alert without suppressing neighbouring disks. Update both subsystem contracts and add alert-identity, canonical-alias and registry-backed policy proofs.

Change-source: pulse-maintainer
2026-09-26 20:49:02 +01:00
pulse-triage[bot] 322e5f04d2 fix(alerts): confirm physical-disk wearout recovery
A single healthy-looking disk poll could resolve a worn SSD alert, so the next
low reading re-fired its occurrence and notification even after the host-agent
SMART merge correction. Feed reported wearout through the canonical reducer
with three recovery confirmations, retain the failing value during a pending
recovery, and leave absent evidence unchanged. Repeated alternating polls now
keep one active occurrence and one dispatch; sustained recovery still clears it.

Refs #2112

Change-source: pulse-maintainer
2026-09-26 18:53:11 +01:00