Explain actions previously opened a blank conversation and discarded richer
finding context. Dispatch the selected explanation through shared chat
handling, retain evidence and drafts, and cancel pending work on tenant
switches. Keep unrelated workflow starters out of scoped conversations.
Record the remaining real-model and customer-outcome qualification gap
without treating scripted browser responses as proof of product value.
The shell multi-tenant suite previously selected a spec ignored by every project, preventing real backend diagnosis. Add an explicit desktop-only configuration that rejects tier identity, while retaining the normal quarantine. Cover discovery and tier refusal and document the evidence boundaries. A local source-built diagnostic returned five passes, one failure at organisation-switch login, and one skip; this is not release qualification.
Change-source: pulse-maintainer
Incorporate the upstream main frontier recorded before this coordination batch while retaining the reviewed runner-isolation commit unchanged.
Change-source: pulse-maintainer
Withdraw the imposed minor-release calendar following clarified founder
intent. Preserve exact-candidate and clean-soak requirements while leaving
scope, version, maturity and timing to evidence-informed judgment.
Keep required backend matrix check names present on documentation-only
changes so policy updates can land without weakening branch protection.
Contract-Neutral: Backend CI check reporting only. The shard test commands,
dependency security proof and deployment contracts are unchanged.
Installed PBS qualification must distinguish accurate metric history from API load and persistence write traffic. File growth and whole-device counters alone cannot attribute write cost to Pulse, so an unqualified measurement could lead to incorrect regression or wear claims.
Document matched baseline and repaired measurement windows, counter limitations and backup I/O separation without changing runtime behaviour or claiming installed recovery.
Validation: git diff --check passed; documentation-only change. Installed artifact qualification remains dependent on an authorised environment.
Change-source: pulse-maintainer
Aggregate historical row counts across unlike resources do not establish whether the integrated PBS source-time repair works on an installed artifact. Release qualification needs common observation windows and independent source timestamps to distinguish valid unchanged-value samples from restamped cached data.
Document an operator-run check covering mixed polling, outage, recovery and whole-process restart, with exact artifact identity and per-metric SQL measurements. This provides acceptance criteria, not installed proof or grounds to close#1882.
Validation: documented SQL previously exercised against synthetic SQLite healthy-cadence, duplicate-identity and empty-window cases; git diff --check passes. Documentation only; no production behaviour changed.
Change-source: pulse-maintainer
A reproduced admission HTTP 503 after socket recovery removed platform destinations despite populated inventory. Retain the last valid facet on request failure, keep tenant resets and successful empty responses authoritative, and cover desktop/mobile interruption and recovery.
Change-source: pulse-maintainer
Keep resource snapshot receipt separate from alert hydration and tenant-scoped across reconnect. Include matching subsystem contracts, architecture coverage and fresh browser receipt.
Validation: 87 focused tests and three real-backend Chromium checks pass at 1440, 1100 and 390px. Exact release-candidate qualification remains outstanding.
Change-source: pulse-maintainer
Scheduled reconciliation fails when gh api refuses ANSI-bearing Actions logs. Use the dedicated sanitising log reader without disabling terminal protection, preserving private authentication and fail-closed evidence handling. Focused reconciliation and policy tests pass; a read-only live job probe retains failure evidence without ESC bytes.
Change-source: pulse-maintainer
A TrueNAS WARNING progressing to EMERGENCY updated the live severity but never dispatched the critical transition. Bring provider incidents into line with metric critical re-notification using the existing rate-limit and delivery policy gates, without replacing lifecycle identity.
Add fixture-to-manager coverage for escalation, unchanged observations, downgrade, acknowledgement suppression and confirmed recovery. The new active transition case failed before the fix (one callback instead of two). TrueNAS tests passed 20 repeats and five race repeats; alerts and truenas package suites passed. External appliance and transport receipt remain unverified.
Change-source: pulse-maintainer
TrueNAS documents EMERGENCY above ALERT, but native projection rejected it as an unknown level. Reproduced zero incidents and zero notification callbacks for this severity while the other six documented levels passed. Map it to critical so the most severe native condition is not silently omitted or mistaken for recovery.\n\nCover all seven native severity mappings, synchronous dispatch and confirmed recovery callbacks, and retention across repeated EMERGENCY observations. The two affected package suites and focused race checks pass; appliance and real notification-provider receipt remain unqualified.
Change-source: pulse-maintainer
The INFO noise repair also suppressed NOTICE because both native levels map to monitor risk. TrueNAS documents NOTICE as notification-worthy. Retain native severity so NOTICE stays actionable without inflating its canonical severity; INFO suppression and confirmed recovery remain intact.
A native-projection regression fails with the blanket filter and passes with the correction. Affected TrueNAS, unified resources, alerts and incident-memory package tests pass.
Change-source: pulse-maintainer
Reconcile coverage rows by logical keys before windowing. Isolated Chromium checks at desktop and narrow widths preserve keyboard focus, expanded evidence, route and scroll across replacement HTTP snapshots. Include subsystem completion obligations and a content-bound browser receipt.
Does not qualify the full application scroll-jump report in #1869 or reporter resolution.
Change-source: pulse-maintainer
Issue #1892 reports successful replication information requiring acknowledgement. Preserve provider information on resources while excluding TrueNAS INFO-level conditions from active alert synchronisation. Warning conditions still activate and clear when downgraded to information.
Resource-incident timeline events contain numeric placeholders, not threshold evidence. Avoid displaying these as a fictitious 0 >= 0 trigger while retaining numeric metric formatting. Focused regressions reproduce both failures and pass with these changes.
Change-source: pulse-maintainer
TrueNAS emits FINISHED for successful replication, but the recovery mapper treated it as unknown. Recognise that provider state while preserving error precedence and the missing-run guard; add regression coverage reproducing the reported outcome.
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
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
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
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.
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
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.
Canonical registry rebuilds were assigning fresh timestamps to unchanged PBS datastore values, so unrelated poll completions wrote duplicate history rows. Preserve the metric source observation time so repeated rebuilds collapse onto the one upstream sample.
Change-source: pulse-maintainer
On 2026-09-03 registry.npmjs.org returned 503s and then timeouts from its
bulk advisory endpoint for over an hour. `npm audit` exits non-zero both
for a real advisory and for an endpoint it cannot reach, so the Frontend
job failed four times running and, because it is a required check, no
pull request could land at all - including Go-only ones that touch no
JavaScript. Every one of those failures was the outage. In two of the
runs the other audit call in the same job succeeded and reported zero
vulnerabilities.
The audits now run through scripts/npm-audit-retry.sh, which separates
the two cases and does nothing else. A conclusive result is acted on
immediately, and the gate stays exactly as strict as before: any
vulnerability at any severity still fails, and no severity threshold is
introduced. Only an unreachable endpoint is retried, with backoff.
When retries are exhausted the outcome depends on whether the answer is
actually unknown. A change that touches frontend-modern/package.json,
frontend-modern/package-lock.json, or the runner itself fails, because
the dependency graph moved and no result means no answer. A change that
touches none of them warns and continues, because the graph is then
identical to the base commit that already produced a passing answer.
Advisories published later against unchanged dependencies are what
Dependabot security updates are for, not a per-pull-request audit.
Deliberately not done: relaxing the severity threshold. That was my first
instinct, but the evidence does not support it. None of the four failures
was an advisory, the lockfile reports zero vulnerabilities at every
severity, and a threshold would have weakened the gate without fixing
anything. The contract's rule that audit suppression is not a valid
closure stands.
The pinning test now requires the runner's invocation and the dependency
detection wiring, and additionally asserts the runner carries no
--audit-level flag, so the strictness cannot be quietly traded away
later.
normalizeVersionString assigns 0.0.0-<sanitized> to any build string it
cannot parse as a release version — a branch name, an ad-hoc test or
qualification label, an empty VERSION file — but usageDataVersionChannel
only called a build "dev" when it carried git build metadata or its
prerelease was exactly "dev" or "dev.*". Everything else fell through to
"prerelease" with version_is_development clear, so the flag did not mean
what its name says: on 2026-09-03 the receiver held 317 installs of
0.0.0-test-version and 18 of 0.0.0-dev-pro, all flagged as ordinary
prereleases, while only 0.0.0-dev was marked development. A receiver-side
read that filtered on that flag would have excluded none of them.
Pulse never publishes a 0.0.0 release, so the sentinel itself is the
signal and it now decides the channel ahead of the prerelease-text rules.
The existing test named "source branch falls back to prerelease dev
identity" asserted wantDevelopment false, encoding the defect; it is
corrected and joined by the test-version, dev-pro, qual, and empty-string
cases that reached the receiver.
A development build is also no longer reported as a published release at
the same time. The sentinel 0.0.0-rc.1 satisfies
IsPublishedReleaseAssetVersion on prerelease spelling alone, which would
have set both flags for a build that no install can be running. The guard
lives in DescribeUsageDataVersion rather than in
IsPublishedReleaseAssetVersion, which agent update logic in
internal/api/unified_agent.go also relies on and which this change should
not disturb.
Historical rows keep the values they were sent with; only builds
reporting after this lands carry the corrected identity.
A three-week decline in investigations/new_findings (7.2% to 5.0%) looked
like a Patrol regression. It is not one. The ratio is not a rate at all:
the two counters come from different stores, cover different spans, and
are drawn from populations that barely overlap.
new_findings_30d sums run.NewFindings over history.Runs, which
SavePatrolRunHistory caps at MaxPatrolRunHistory, so it covers at most the
last hundred runs rather than thirty days. investigations_30d instead
scans the current findings store and counts surviving finding records
investigated in-window, including findings created before it, which is how
the paid cohort read 128.57% in the week to 2026-08-25. Finding
ShouldInvestigate returns false at monitor autonomy and effective autonomy
is licence-gated, so free installs produced 4384 findings and 1
investigation while 67 paid installs produced 242.
The decline was composition: flat in version-stable installs, and fleet
investigations rose once the single install that swung the total by 38 was
excluded. Finding-detection code is identical between v6.3.2 and v6.4.1.
The new test pins the asymmetry behind the bad denominator. Its twin
already asserts that runs_30d ignores the history cap after 63c40ebe5e;
nothing asserted that the findings loop immediately below it does not, so
the truncation could regress or be mistaken for a thirty-day total
unnoticed. Fixing it needs a per-day findings tally alongside DailyRuns,
which the coverage gap tracks as its own slice.
Go 1.26.8 supersedes the prior patch release, so every release builder and local toolchain guard must move together to prevent candidate artifacts from retaining an older compiler and runtime.
Contract-Neutral: toolchain-only patch update; no product or runtime contract changed
Change-source: pulse-maintainer
Retry only explicit registry failures with bounded one-minute attempts while preserving immediate advisory failures. Defer the aggregate audit verdict so frontend tests and builds still report during npm service incidents.