Prepare v6.4.0-rc.7 release

Package durable alert lifecycle recovery, richer scheduling and routing, capacity forecasting, host disk policy, external availability monitoring, and governed action verification for the next prerelease.

Change-source: pulse-maintainer
This commit is contained in:
Richard Courtman
2026-08-28 00:22:44 +01:00
parent e4ba1baea6
commit 595c369d85
13 changed files with 150 additions and 73 deletions
+1 -1
View File
@@ -1 +1 @@
6.4.0-rc.6
6.4.0-rc.7
+4 -4
View File
@@ -2,9 +2,9 @@ apiVersion: v2
name: pulse
description: Helm chart for deploying the Pulse hub and optional Docker, Kubernetes, or OpenShift monitoring agent.
type: application
version: 6.4.0-rc.6
appVersion: "6.4.0-rc.6"
icon: https://raw.githubusercontent.com/rcourtman/Pulse/v6.4.0-rc.6/docs/images/pulse-logo.svg
version: 6.4.0-rc.7
appVersion: "6.4.0-rc.7"
icon: https://raw.githubusercontent.com/rcourtman/Pulse/v6.4.0-rc.7/docs/images/pulse-logo.svg
keywords:
- monitoring
- proxmox
@@ -32,7 +32,7 @@ annotations:
description: Smoke tests with kind cluster deployment
artifacthub.io/links: |
- name: Documentation
url: https://github.com/rcourtman/Pulse/blob/v6.4.0-rc.6/docs/KUBERNETES.md
url: https://github.com/rcourtman/Pulse/blob/v6.4.0-rc.7/docs/KUBERNETES.md
- name: Support
url: https://github.com/rcourtman/Pulse/discussions
artifacthub.io/maintainers: |
+1 -1
View File
@@ -1,6 +1,6 @@
# pulse
![Version: 6.4.0-rc.6](https://img.shields.io/badge/Version-6.4.0--rc.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 6.4.0-rc.6](https://img.shields.io/badge/AppVersion-6.4.0--rc.6-informational?style=flat-square)
![Version: 6.4.0-rc.7](https://img.shields.io/badge/Version-6.4.0--rc.7-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 6.4.0-rc.7](https://img.shields.io/badge/AppVersion-6.4.0--rc.7-informational?style=flat-square)
Helm chart for deploying the Pulse hub and optional Docker, Kubernetes, or OpenShift monitoring agent.
+1 -1
View File
@@ -2,7 +2,7 @@ version: '3.8'
services:
pulse:
image: ${PULSE_IMAGE:-rcourtman/pulse:6.4.0-rc.6}
image: ${PULSE_IMAGE:-rcourtman/pulse:6.4.0-rc.7}
container_name: pulse
restart: unless-stopped
logging:
+6 -4
View File
@@ -7,8 +7,8 @@ For historical v4 notes that previously lived in this repo, see:
`docs/releases/RELEASE_NOTES_v4.md`
For the current v6 release candidate packet (the current v6 support release candidate packet), see:
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.6.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.6.md`
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.7.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.7.md`
For the current stable v6 packet, see:
- `docs/releases/RELEASE_NOTES_v6.3.2.md`
@@ -19,10 +19,12 @@ For the preceding stable v6 packet, see:
- `docs/releases/V6_CHANGELOG_v6.3.1.md`
For the preceding v6.4 release candidate packet, see:
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.5.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.5.md`
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.6.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.6.md`
For earlier v6.4 release candidate packets, see:
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.5.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.5.md`
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.4.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.4.md`
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.3.md`
+6 -4
View File
@@ -4,8 +4,8 @@ This guide covers practical upgrade steps for existing Pulse installs moving to
For the current v6 release candidate packet (the current v6 support release candidate packet), see:
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.6.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.6.md`
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.7.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.7.md`
For the current stable v6 packet, see:
@@ -19,11 +19,13 @@ For the preceding stable v6 packet, see:
For the preceding v6.4 release candidate packet, see:
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.5.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.5.md`
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.6.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.6.md`
For earlier v6.4 release candidate packets, see:
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.5.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.5.md`
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.4.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.4.md`
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.3.md`
@@ -1811,27 +1811,31 @@ diagnostics. The same release workflow also executes the generated self-signed
and custom-CA Windows installer commands through Windows PowerShell 5.1 before
release assembly, so the first HTTPS fetch is release proof rather than a
string-shape assertion.
The active prerelease `v6.4.0-rc.6` cut sets the repo-root `VERSION`, repo-root
The active prerelease `v6.4.0-rc.7` cut sets the repo-root `VERSION`, repo-root
`docker-compose.yml` image default, `scripts/install-docker.sh` fallback, and
Helm chart release metadata to the same `6.4.0-rc.6` release version. It follows
`v6.4.0-rc.5` on the published `v6.4.0` candidate line. This prerelease keeps
Helm chart release metadata to the same `6.4.0-rc.7` release version. It follows
`v6.4.0-rc.6` on the published `v6.4.0` candidate line. This prerelease keeps
`rollback_version=v6.3.2`, publishes a versioned public GitHub prerelease
plus versioned Docker and Helm artifacts, and does not move stable/latest
install pointers or stable semver aliases. The candidate restores complete
merged host detail on the standalone PBS surface; prevents `pct df` lock
contention and shared-deadline starvation from dropping later LXC filesystem
reports; detects SMART UDMA CRC counter growth; resolves alert configuration
through one declarative policy fold; removes the superseded transition-tracking
maps; bounds alert-event query allocation by the effective result limit; and
advances the release toolchain to Go 1.26.7. The changes since
`v6.4.0-rc.5` do not
require a Pulse Mobile client change and preserve
the existing mobile, Relay, onboarding, and mobile-facing API contracts, so the
server cut is classified `no-mobile-impact`; no companion upload or public
mobile-store rollout is part of this candidate. The canonical mobile
compatibility projection and route/method/scope, request/response, pairing, and
push checks passed against Pulse Mobile revision
`57353a83eb950d1102c90074aa8fe67e1559685b`, iOS build 12, and Android build 9.
install pointers or stable semver aliases. The candidate makes the append-only
event log authoritative for alert history and active-state reconstruction;
adds per-alert snooze, recurring scoped maintenance, destination severity
routing, repeatable escalation schedules, and external dead-man monitoring;
adds rolling-window metric policy and predictive storage-capacity alerts;
makes host SMART policy configurable without duplicating Proxmox disk risk;
converges infrastructure detail presentation; and strengthens independently
verified Docker actions plus atomic deployment enrollment and credential
persistence. The changes since `v6.4.0-rc.6` add the canonical `alert_fired`
mobile push type, but preserve the existing `view_alert` navigation action and
all route, request/response, pairing, and authorization contracts. Published
Pulse Mobile iOS build 12 and Android versionCode 9 already route
`action_type=view_alert`, so the server cut is classified
`existing-mobile-build-compatible`; no companion upload or public mobile-store
rollout is part of this candidate. Published candidate source revision
`763e95138b840bae795ad6ca5affe930cfd0ef80` contains that navigation behavior,
and Pulse Mobile revision `471d158e7bca7348a2cd8e7e36b8b44f343934bb`
synchronizes the generated compatibility inventory with no required runtime
navigation change.
The prerelease Windows path
retains exact-SHA, checksum, and detached-signature verification without
Authenticode. Stable `v6.4.0` also skips SignPath under the standing unavailable
@@ -1841,10 +1845,15 @@ only after the release owner explicitly confirms that production credentials
and certificate authorization are ready and a reviewed policy/code change
restores it.
The preceding `v6.4.0-rc.6` cut published from exact source SHA
`8fde82b8a24229fffb628732d10fc320be643099`. Its tag and versioned artifacts
remain immutable; `v6.4.0-rc.7` supersedes it without moving stable install
pointers or stable semver aliases from `v6.3.2`.
The preceding `v6.4.0-rc.5` cut published from exact source SHA
`3b21d4c257a5e140af05af0973ce6cb1f1effc4d`. Its tag and versioned artifacts
remain immutable; `v6.4.0-rc.6` supersedes it without moving stable install
pointers or stable semver aliases from `v6.3.2`.
remain immutable; later `v6.4.0` prereleases supersede it without moving stable
install pointers or stable semver aliases from `v6.3.2`.
The preceding `v6.4.0-rc.4` cut published from exact source SHA
`8fb7b3764183168f93140d83e2b18b4e953b6cd8`. Its tag and versioned artifacts
@@ -2293,8 +2302,8 @@ For the active stable `v6.1.2` cut, the repo-root compose default and
`scripts/install-docker.sh` fallback must both pin `6.1.2` whenever the
governed `VERSION` is that stable cut. The stable promotion guard remains in
force and rejects leftover `-rc.` defaults.
For the active prerelease `v6.4.0-rc.6` cut, the repo-root compose default and
`scripts/install-docker.sh` fallback must both pin `6.4.0-rc.6` until the next
For the active prerelease `v6.4.0-rc.7` cut, the repo-root compose default and
`scripts/install-docker.sh` fallback must both pin `6.4.0-rc.7` until the next
governed stable cut moves them forward. Each new release moves
these two pins together with the repo-root `VERSION` and the Helm chart metadata
in the same commit; a cut that leaves any of the four on a superseded value is a
@@ -0,0 +1,24 @@
# Pulse v6.4.0-rc.7 Release Notes
`v6.4.0-rc.7` strengthens alerting as an operational system. Histories survive restarts, alerts can be scheduled and routed more precisely, and new forecasting detects storage risk earlier.
## What's improved
- **Durable alert lifecycles** - Alert history and active state now rebuild from the event log after restarts, with persisted identities migrated automatically and false all-clear states prevented during hydration.
- **Better notification control** - Alerts can be snoozed individually, maintenance can recur by scope, escalation repeats can target specific destinations, and delivery routes can filter by severity.
- **Earlier capacity warnings** - Rolling metric windows and predictive storage forecasts surface sustained pressure and likely exhaustion before a single threshold breach becomes an outage.
- **Host disk policies** - SMART sector, media, endurance, spare, and CRC thresholds can be tuned per host while Proxmox-linked agents continue to avoid duplicate disk-risk alerts.
- **External availability monitoring** - Dead-man checks can notify when an expected external signal stops arriving, with configuration and recovery state persisted.
- **Clearer infrastructure details** - Resource drawers, Proxmox backup views, and alert timelines present more complete and consistent context across desktop and narrow layouts.
- **Safer governed actions** - Docker action results now carry independently observed post-action state, while deployment enrollment and credential changes persist atomically.
## Before you upgrade
- This is a release candidate. Stable installations remain on v6.3.2 unless an operator explicitly selects this version.
- Existing configurations remain valid. Alert identity and history migrations run automatically, with no manual data migration required.
- Existing Pulse Mobile iOS build 12 and Android versionCode 9 remain compatible. The new `alert_fired` push uses the already-supported `view_alert` action, so no companion update is required for this candidate.
- Windows Unified Agent binaries are checksum- and detached-signature-verified but are not Authenticode-signed, so Windows may show an Unknown Publisher warning.
## Known issues
- Windows Authenticode signing remains unavailable for this candidate. Use the published checksum and detached signature when verifying Windows agent downloads.
+40
View File
@@ -0,0 +1,40 @@
# Pulse v6.4.0-rc.7
_This changelog describes the changes since `v6.4.0-rc.6` included in
`v6.4.0-rc.7`._
## Added
- Rolling-window metric evaluation supports sustained CPU and memory policies, including workload inheritance from host defaults.
- Predictive storage-capacity alerts estimate exhaustion risk from retained usage history and recover when the forecast clears.
- Per-alert snooze, recurring scoped maintenance, destination severity routing, repeatable escalation schedules, and external dead-man monitoring expand operator control over alert delivery.
- Resolved host SMART policy covers health failure, sector counters, media errors, remaining life, NVMe spare, and CRC growth without creating duplicate Proxmox disk alerts.
- Canonical `alert_fired` push events use the existing mobile `view_alert` navigation action.
## Changed
- The append-only event log is the authority for alert history and active lifecycle reconstruction, including restart recovery, acknowledgement, resolution, suppression, notification, and migration evidence.
- Alert identities and persisted history migrate to canonical resource keys, while active state uses durable atomic snapshots and ordered recovery.
- Escalation and delivery decisions are destination-specific, repeated holds are coalesced, and destination updates persist before the active runtime changes.
- Resource detail drawers use shared information-card and detail-table primitives across infrastructure, Docker, storage, and Proxmox backup surfaces.
- Docker lifecycle results distinguish command acceptance from independently observed post-action state, and deployment enrollment plus credential updates commit atomically.
## Fixed
- Alert hydration no longer exposes a false all-clear state before persisted incidents are restored.
- Restart recovery, history queries, and mock alert timelines preserve lifecycle order, observation time, and complete incident evidence.
- Fresh rolling-window metric data remains authoritative, including when older samples or counter resets are present.
- Offline mock hosts remain on the normal host-alert lifecycle instead of losing active incidents during refresh.
- API token watcher updates remain ordered across successive persistence mutations.
- Proxmox backup health, inventory refresh, offline fixtures, and drawer detail presentation retain complete current context.
## Release Metadata
- Version: `v6.4.0-rc.7`
- Previous candidate tag: `v6.4.0-rc.6`
- Previous stable: `v6.3.2`
- Rollback target: `v6.3.2`
- Rollback command: `./scripts/install.sh --version v6.3.2`
- Promotion path: exact-SHA single-build release candidate from `main`
- Windows signing decision: prereleases publish checksum- and detached-signature-verified Windows agents without Authenticode while SignPath remains unavailable. Windows may show an Unknown Publisher warning.
- Mobile decision: `existing-mobile-build-compatible`. Published iOS build 12 and Android versionCode 9 already route `action_type=view_alert`, which is the action used by the new `alert_fired` push type, so no companion upload is required.
+6 -4
View File
@@ -4,8 +4,8 @@ This guide covers practical upgrade steps for existing Pulse installs moving to
For the current v6 release candidate packet (the current v6 support release candidate packet), see:
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.6.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.6.md`
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.7.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.7.md`
For the current stable v6 packet, see:
@@ -19,11 +19,13 @@ For the preceding stable v6 packet, see:
For the preceding v6.4 release candidate packet, see:
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.5.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.5.md`
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.6.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.6.md`
For earlier v6.4 release candidate packets, see:
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.5.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.5.md`
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.4.md`
- `docs/releases/V6_CHANGELOG_v6.4.0-rc.4.md`
- `docs/releases/RELEASE_NOTES_v6.4.0-rc.3.md`
+1 -1
View File
@@ -6,7 +6,7 @@ set -euo pipefail
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
DOCKER_IMAGE_REPO="${DOCKER_IMAGE_REPO:-rcourtman/pulse}"
CANONICAL_DEFAULT_PULSE_VERSION="6.4.0-rc.6"
CANONICAL_DEFAULT_PULSE_VERSION="6.4.0-rc.7"
resolve_default_pulse_version() {
if [ -n "${PULSE_IMAGE_VERSION:-}" ]; then
@@ -887,40 +887,35 @@ func TestCurrentPrereleasePacketTracksInstallMetadata(t *testing.T) {
"## What's improved",
"## Before you upgrade",
"## Known issues",
"Complete standalone PBS details",
"Complete LXC filesystem coverage",
"Earlier disk-cabling warnings",
"More predictable alerts",
"Safer alert-history queries",
"Pulse Mobile does not consume the changed PBS browser detail or alert evaluation internals",
"Durable alert lifecycles",
"Better notification control",
"Earlier capacity warnings",
"Host disk policies",
"External availability monitoring",
"Clearer infrastructure details",
"Safer governed actions",
"Existing Pulse Mobile iOS build 12 and Android versionCode 9 remain compatible",
"The new `alert_fired` push uses the already-supported `view_alert` action",
"not Authenticode-signed",
"Unknown Publisher warning",
)
assertFileDoesNotContain(t, releaseNotesPath, "## Fixes")
for _, issueURL := range []string{
"https://github.com/rcourtman/Pulse/issues/1723",
"https://github.com/rcourtman/Pulse/issues/1477",
"https://github.com/rcourtman/Pulse/issues/1776",
} {
assertFileContainsExactlyOnce(t, releaseNotesPath, issueURL)
assertFileContainsExactlyOnce(t, changelogPath, issueURL)
}
assertFileContainsAllNormalized(t, changelogPath,
"Version: `v"+version+"`",
"Previous stable: `v"+previous+"`",
"Rollback target: `v"+previous+"`",
"Promotion path: exact-SHA single-build release candidate from `main`",
"This changelog describes the changes since `v"+comparisonVersion+"`",
"SMART UDMA CRC counter growth now raises a disk-health warning",
"Alert configuration resolves through one declarative policy fold",
"Legacy transition-tracking maps have been removed",
"Standalone PBS rows open the canonical resource drawer",
"Proxmox LXC filesystem collection uses host-namespace `statfs`",
"Alert-event queries allocate from the bounded effective result limit",
"Release builds use Go 1.26.7",
"Rolling-window metric evaluation supports sustained CPU and memory policies",
"Predictive storage-capacity alerts estimate exhaustion risk",
"Per-alert snooze, recurring scoped maintenance, destination severity routing",
"The append-only event log is the authority for alert history and active lifecycle reconstruction",
"Alert hydration no longer exposes a false all-clear state",
"Docker lifecycle results distinguish command acceptance from independently observed post-action state",
"Windows signing decision: prereleases publish checksum- and detached-signature-verified Windows agents without Authenticode",
"Mobile decision: `no-mobile-impact`",
"no companion build or public store rollout is required",
"Mobile decision: `existing-mobile-build-compatible`",
"Published iOS build 12 and Android versionCode 9 already route `action_type=view_alert`",
"no companion upload is required",
)
if version == "6.3.0-rc.6" {
assertFileContainsAllNormalized(t, releaseNotesPath,
@@ -965,7 +960,8 @@ func TestCurrentPrereleasePacketTracksInstallMetadata(t *testing.T) {
"The active prerelease `v"+version+"` cut sets the repo-root `VERSION`, repo-root `docker-compose.yml` image default, `scripts/install-docker.sh` fallback, and Helm chart release metadata to the same `"+version+"` release version.",
"This prerelease keeps `rollback_version=v"+previous+"`, publishes a versioned public GitHub prerelease plus versioned Docker and Helm artifacts, and does not move stable/latest install pointers or stable semver aliases.",
"For the active prerelease `v"+version+"` cut, the repo-root compose default and `scripts/install-docker.sh` fallback must both pin `"+version+"` until the next governed stable cut moves them forward.",
"The changes since `v"+comparisonVersion+"` do not require a Pulse Mobile client change and preserve the existing mobile, Relay, onboarding, and mobile-facing API contracts, so the server cut is classified `no-mobile-impact`; no companion upload or public mobile-store rollout is part of this candidate.",
"The changes since `v"+comparisonVersion+"` add the canonical `alert_fired` mobile push type, but preserve the existing `view_alert` navigation action and all route, request/response, pairing, and authorization contracts.",
"Published Pulse Mobile iOS build 12 and Android versionCode 9 already route `action_type=view_alert`, so the server cut is classified `existing-mobile-build-compatible`; no companion upload or public mobile-store rollout is part of this candidate.",
"The prerelease Windows path retains exact-SHA, checksum, and detached-signature verification without Authenticode. Stable `v"+stableTarget+"` also skips SignPath under the standing unavailable policy",
)
}
@@ -3100,11 +3096,11 @@ func TestReleaseNotesGeneratorResolvesChannelSpecificComparisonRanges(t *testing
commit("stable 6.3.2 hotfix")
runGit("tag", "v6.3.2")
runGit("checkout", "main")
for rc := 1; rc <= 5; rc++ {
for rc := 1; rc <= 6; rc++ {
commit("release candidate " + strconv.Itoa(rc))
runGit("tag", "v6.4.0-rc."+strconv.Itoa(rc))
}
commit("release candidate 6 changes")
commit("release candidate 7 changes")
generator, err := filepath.Abs(repoFile("scripts", "generate-release-notes.sh"))
if err != nil {
@@ -3142,8 +3138,8 @@ func TestReleaseNotesGeneratorResolvesChannelSpecificComparisonRanges(t *testing
return strings.TrimSpace(string(output))
}
if got := resolve("6.4.0-rc.6"); got != "v6.4.0-rc.5" {
t.Fatalf("RC comparison base = %q, want v6.4.0-rc.5", got)
if got := resolve("6.4.0-rc.7"); got != "v6.4.0-rc.6" {
t.Fatalf("RC comparison base = %q, want v6.4.0-rc.6", got)
}
if got := resolve("6.4.0-rc.1"); got != "v6.3.2" {
t.Fatalf("RC1 comparison base = %q, want v6.3.2", got)
@@ -3152,13 +3148,13 @@ func TestReleaseNotesGeneratorResolvesChannelSpecificComparisonRanges(t *testing
t.Fatalf("GA comparison base = %q, want v6.3.2", got)
}
cmd := exec.Command("bash", generator, "6.4.0-rc.6", "v6.4.0-rc.4")
cmd := exec.Command("bash", generator, "6.4.0-rc.7", "v6.4.0-rc.5")
cmd.Dir = repo
output, err := cmd.CombinedOutput()
if err == nil {
t.Fatal("generator accepted a comparison tag older than the immediately preceding RC")
}
if !strings.Contains(string(output), "expected 'v6.4.0-rc.5'") {
if !strings.Contains(string(output), "expected 'v6.4.0-rc.6'") {
t.Fatalf("unexpected comparison-range rejection:\n%s", output)
}
}
@@ -147,6 +147,7 @@ func TestPreviousStableForPrereleaseVersionCrossesMinorBoundaries(t *testing.T)
{version: "6.4.0-rc.4", want: "6.3.2"},
{version: "6.4.0-rc.5", want: "6.3.2"},
{version: "6.4.0-rc.6", want: "6.3.2"},
{version: "6.4.0-rc.7", want: "6.3.2"},
}
for _, test := range tests {
@@ -378,7 +379,8 @@ func TestInstallDockerProofTracksPrereleaseContract(t *testing.T) {
"The active prerelease `v"+version+"` cut sets the repo-root `VERSION`, repo-root `docker-compose.yml` image default, `scripts/install-docker.sh` fallback, and Helm chart release metadata to the same `"+version+"` release version.",
comparisonLine,
"This prerelease keeps `rollback_version=v"+previous+"`, publishes a versioned public GitHub prerelease plus versioned Docker and Helm artifacts, and does not move stable/latest install pointers or stable semver aliases.",
"The changes since `v"+comparisonVersion+"` do not require a Pulse Mobile client change and preserve the existing mobile, Relay, onboarding, and mobile-facing API contracts, so the server cut is classified `no-mobile-impact`; no companion upload or public mobile-store rollout is part of this candidate.",
"The changes since `v"+comparisonVersion+"` add the canonical `alert_fired` mobile push type, but preserve the existing `view_alert` navigation action and all route, request/response, pairing, and authorization contracts.",
"Published Pulse Mobile iOS build 12 and Android versionCode 9 already route `action_type=view_alert`, so the server cut is classified `existing-mobile-build-compatible`; no companion upload or public mobile-store rollout is part of this candidate.",
"The prerelease Windows path retains exact-SHA, checksum, and detached-signature verification without Authenticode. Stable `v"+stableTarget+"` also skips SignPath under the standing unavailable policy",
"For the active prerelease `v"+version+"` cut, the repo-root compose default and `scripts/install-docker.sh` fallback must both pin `"+version+"` until the next governed stable cut moves them forward.",
)