Issue #1869 reports views resetting during refresh. Exercise the mounted backup coverage view through three replacement workload snapshots so losing expanded restore evidence is caught before release. Confirm each refreshed workload name renders to exclude stale-state false positives.
Contract-Neutral: regression coverage only; no runtime or API changes.
Change-source: pulse-maintainer
Exercise the mounted credential slot through repeated snapshots and a different edit target. A mutation that stops marking strategy selections dirty fails the new regression test.
Contract-Neutral: regression coverage only; no runtime or API changes
Change-source: pulse-maintainer
Issue #1895 reports parity alerts when mdNumDisks=0 on a pool-only Unraid system. Array service state alone does not establish that a parity array exists.
Preserve the optional disk count from collection through canonical runtime conversion and suppress only the no-parity warning for an explicit zero. Missing or malformed counts retain legacy behaviour, and disk failure reasons remain active.
Validated focused Unraid tests in hostagent, storagehealth, monitoring, unifiedresources and alerts, including JSON zero preservation and canonical round trip. The new pool-only regression fails against the previous warning condition. Both agent and server need this change; no release or reporter retest is claimed.
Change-source: pulse-maintainer
Exercise the NodeCredentialSlot dirty-edit path across repeated server snapshots and verify Save retains operator values and the current edit target. Removing the dirty guard reproduces the failure.
Contract-Neutral: regression coverage only; no runtime or API changes
Change-source: pulse-maintainer
Host and Docker collectors can enter the same mount probe before either timeout expires. Register the in-flight call atomically and share its result and deadline so a blocked syscall cannot accumulate duplicate workers. Preserve the guard until the syscall returns even when a waiter is cancelled.
Change-source: pulse-maintainer
Issue #1890 reports macOS agent updates stopping because the root group does not exist. Use numeric superuser ownership in the two shared lifecycle writes without relaxing failure handling or the least-privilege group boundary. Add a regression fixture that rejects named root ownership and checks that chown failures still prevent replacement.
Change-source: pulse-maintainer
Near-synchronous host and Docker reports consumed a shared CPU baseline, measuring collection bursts rather than each module's reporting interval. Retain a collector per host collector and a separate Docker module collector while preserving the package-level convenience API and disk filters.
Add an interleaved-counter regression covering both collection entry points. It fails when routed through the shared baseline and passes with isolated state. All hostmetrics, hostagent and dockeragent tests pass, as do the focused CPU regression tests under the race detector.
Change-source: pulse-maintainer
Reapply the reviewed same-runner base/candidate benchmark job after later integration merges retained its runner and contract tests but reverted the workflow block itself.
Contract-Neutral: restores already-reviewed CI behavior without changing product interfaces
Refs: 9720f672c8e050a822773104885431583e4f661e
Change-source: pulse-maintainer
Reapply the reviewed Go 1.26.8, OCI Helm recovery, and non-login-shell test expectations that later upstream merges accidentally replaced while retaining the corresponding implementations.
Contract-Neutral: test-only reconciliation; no product or runtime behavior changed
Change-source: pulse-maintainer
Credential slots froze the configured-node snapshot when the editor mounted, so a later server refresh could leave an untouched form stale even after the poll-clobber remount was removed. Keep node and security inputs reactive while the existing dirty guard protects operator edits, and cover both component refresh and browser polling paths.
Contract-Neutral: frontend polling-state bugfix; no API or persisted-data change
Change-source: pulse-maintainer
A published release packet is a customer-visible surface in its own right. Deriving newer published versions only from matching Git refs lets that surface escape continuity validation when the corresponding ref is absent. Evaluate every stable-shaped release record independently and pin the detached-ref case with a regression test.
Change-source: pulse-maintainer
Update the retained canonical Python contract for the upstream wall-clock timeout mechanism and the single complete per-PR audit, while preserving the two-view scheduled audit expectations.\n\nChange-source: pulse-maintainer
Change-source: pulse-maintainer
A failed v6.4.2 release left newer stable-shaped source and public container tags behind after its GitHub Release packet was removed. Extend the scheduled continuity audit across the stable tag and public registry frontier so this partial publication cannot remain hidden behind an older latest release.
Change-source: pulse-maintainer
GitHub's Atom feed can retain entries for deleted releases. Probe the deterministic runtime archive without following redirects before exposing a feed candidate, and continue to the next published version when the candidate is stale. Keep custom update servers from falling through to the public feed on a 403.
Contract-Neutral: Update discovery validation only; no wire, persisted-data, or subsystem contract change
Refs: #1881
Change-source: pulse-maintainer
The security workflow moved to the scoped npm audit retry runner, but its
dependency-policy test still asserted the retired direct invocation. Assert the
checked-in all and production modes so the script suite tests the active
scheduled scan.
Contract-Neutral: test expectation only; scheduled audit behaviour is unchanged
Change-source: pulse-maintainer
The benchmark gate compared five-sample PR results with a cache produced on
another hosted VM. Two unrelated changes failed today while the same main code
passed, and benchstat reports infinite 95% confidence intervals for that sample
size.
Collect ten base and candidate samples on the PR runner in alternating order,
retain both inputs and the comparison, and reject under-sampled verdicts. Keep
non-PR benchmark evidence without the cross-run baseline cache.
Contract-Neutral: CI performance evidence collection only; no product or release contract changes
Change-source: pulse-maintainer
The retry hardening added in #1885 bounded attempts but not time. npm's own
fetch-timeout defaults to five minutes and it retries internally, so three
"attempts" against a hanging advisory endpoint ran for 10m56s on job
100986651307, and a second audit step added 3m36s. The Frontend job was
cancelled 31s into type-check with all 1183 test files already passing, and a
cancelled job reports as a failed required check, so a green run blocked every
pull request. #1888 raised the job timeout to 40 minutes to unblock delivery;
this decides the policy instead.
Each attempt now runs under a hard wall-clock bound and the sequence stops at
a total deadline (60s and 240s by default). npm's internal retry loop is
disabled in favour of this one, since it was the hidden multiplier. The bound
is enforced by a watchdog subshell rather than timeout(1), which is not
present on every developer machine.
What happens when the endpoint stays unreachable is unchanged, because that
split was already right: the run fails when the change touches the dependency
graph and the answer is genuinely unknown, and warns without failing when it
does not, because the graph is then identical to a base commit that already
produced a passing answer. Any advisory at any severity still fails.
Also drops the production-only audit from the per-pull-request path. It audits
a subset of the same packages, so it reports a subset of the same advisories,
and because the complete audit fails the job on any finding, the production
step could only ever execute in the cases where it was already guaranteed
clean. The dev-versus-production split still runs for every npm workspace in
the scheduled security-scan job, where it informs rather than blocks delivery,
and Dependabot security updates remain the route for advisories published
against unchanged dependencies.
With the audit bounded to 4 minutes against an ~11 minute baseline, the job
timeout returns to 30: a stalled endpoint should surface as a warning, not be
absorbed by a budget large enough to hide it.
The status audit requires coverage_gaps to be sorted by recorded_at then id,
and main currently fails it: patrol-investigation-rate-metric-invalid (#1883)
was appended after telemetry-test-binary-production-pings (#1878), which share
a recorded_at of 2026-09-03 and are the wrong way round on id.
The pre-commit hook runs that audit, so every commit from a local checkout is
blocked until this is corrected, whatever it touches.
This swaps the two adjacent entries and nothing else; no gap content changes.
Some identity providers publish unsupported Ed448 or X448 keys alongside supported signing keys. go-oidc v3.20 rejects the whole set, blocking otherwise valid logins; v3.21 skips only those unsupported keys while retaining normal token verification, and the Pulse service regression test pins that behaviour.
Contract-Neutral: dependency-only OIDC interoperability fix; no product or runtime contract changed
Change-source: pulse-maintainer
The npm audit hardening added on 2026-09-04 retries through registry
outages instead of failing on the first 503. That is the right behaviour,
but the two audit steps then took 10m56s and 3m36s, and with roughly 11
minutes of install, lint, 1183 test files and type-check behind them the
job no longer fits timeout-minutes 25. It was cancelled 31 seconds into
type-check with every test already passing, which reads as a failed
required check and blocks every pull request.
Raising the budget to 40 leaves headroom for a slow audit without
weakening any gate. Bounding the retry itself is the better long-term
answer, but that trades delivery availability against audit coverage
during an outage and is a security-posture decision rather than a CI
tuning one.
Contract-Neutral: CI job time budget only; no dependency-security or contract behaviour changes
Extend the existing poll-clobber regression with the exact setup strategy, SSL verification and cleared fingerprint controls reported in #1869. This pins the user-owned form state while refreshed server snapshots arrive.
Contract-Neutral: regression coverage only; no runtime or API change.
Change-source: pulse-maintainer
Replace the remaining Node 20 action pins before GitHub removes that runtime, and make the reviewed Node 24 pins a workflow trust invariant.
Change-source: pulse-maintainer
GitHub's release list now exceeds the update check's 1 MiB safety limit,
causing valid installations to report that updates are unavailable. Keep the
bound and use the existing bounded Atom feed only for the typed over-limit
condition so malformed metadata remains a hard error.
Accept both release-name and bare-tag feed entries, and do not substitute the
public GitHub feed for a configured custom update server.
Contract-Neutral: Update discovery error handling only; no wire, persisted-data, or subsystem contract change
Refs: #1881
Change-source: pulse-maintainer
Retire the unused self-hosted live qualification workflow and reject future secret- or write-capable jobs on persistent or dynamically selected runners. Keep live Patrol qualification as a disposable lab operation.
Change-source: pulse-maintainer
The gap recorded that the receiver could not filter these installs on
version_is_development, which was true when it was written and is no
longer. The emitter now classifies every 0.0.0 sentinel build as
development, so pings sent after 2026-09-04 carry the flag.
Stored rows keep the values they were sent with and are not backfilled,
so the note now states the boundary rather than the old blanket warning,
and still points reads whose window reaches earlier at
version_is_published_release. Merging main also interleaved this gap with
a peer's, so the list is re-sorted by recorded_at then id.
The HTTP JSON observer samples on its own goroutine, and that goroutine
queues the wake before it persists the health lease. The test gated on
the wake (pending trigger count) and then read coverage immediately, so
a runner that descheduled the goroutine in that window saw a half-applied
sample: an installed observer with a nil ValidUntil, which coverage
reports as degraded/observer_health_unknown. That is what blocked the
required backend check on an unrelated PR, not a regression.
Gate on the lease instead. It is the sample's last state-visible action
and it goes through the store mutex, so observing it orders every earlier
side effect of the sample -- the queued trigger included -- against the
assertions that follow. Coverage is also evaluated at a fixed instant
derived from the sample time rather than time.Now(), so the verdict no
longer depends on how long the goroutine took to get there.
Verified by inserting a 150ms delay between the wake and the lease write
via a build overlay: the old test fails 5/5 with exactly the CI symptom,
the new one passes 20/20, and 50/50 under GOMAXPROCS=1 with -race. The
unmodified test is 300/300 under -race.