diff --git a/VERSION b/VERSION index 007193270..19b860c18 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.4.0-rc.13 +6.4.0 diff --git a/deploy/helm/pulse/Chart.yaml b/deploy/helm/pulse/Chart.yaml index f70fdcfe1..97f482c85 100644 --- a/deploy/helm/pulse/Chart.yaml +++ b/deploy/helm/pulse/Chart.yaml @@ -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.13 -appVersion: "6.4.0-rc.13" -icon: https://raw.githubusercontent.com/rcourtman/Pulse/v6.4.0-rc.13/docs/images/pulse-logo.svg +version: 6.4.0 +appVersion: "6.4.0" +icon: https://raw.githubusercontent.com/rcourtman/Pulse/v6.4.0/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.13/docs/KUBERNETES.md + url: https://github.com/rcourtman/Pulse/blob/v6.4.0/docs/KUBERNETES.md - name: Support url: https://github.com/rcourtman/Pulse/discussions artifacthub.io/maintainers: | diff --git a/deploy/helm/pulse/README.md b/deploy/helm/pulse/README.md index 8dc1c1647..7ddd2f47d 100644 --- a/deploy/helm/pulse/README.md +++ b/deploy/helm/pulse/README.md @@ -1,6 +1,6 @@ # pulse -![Version: 6.4.0-rc.13](https://img.shields.io/badge/Version-6.4.0--rc.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 6.4.0-rc.13](https://img.shields.io/badge/AppVersion-6.4.0--rc.13-informational?style=flat-square) +![Version: 6.4.0](https://img.shields.io/badge/Version-6.4.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 6.4.0](https://img.shields.io/badge/AppVersion-6.4.0-informational?style=flat-square) Helm chart for deploying the Pulse hub and optional Docker, Kubernetes, or OpenShift monitoring agent. diff --git a/docker-compose.yml b/docker-compose.yml index cfba7a08b..eb311e15f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.8' services: pulse: - image: ${PULSE_IMAGE:-rcourtman/pulse:6.4.0-rc.13} + image: ${PULSE_IMAGE:-rcourtman/pulse:6.4.0} container_name: pulse restart: unless-stopped logging: diff --git a/docs/RELEASE_NOTES.md b/docs/RELEASE_NOTES.md index 6de456cbe..f46285855 100644 --- a/docs/RELEASE_NOTES.md +++ b/docs/RELEASE_NOTES.md @@ -6,19 +6,23 @@ Pulse release notes live on GitHub: 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.13.md` -- `docs/releases/V6_CHANGELOG_v6.4.0-rc.13.md` - For the current stable v6 packet, see: +- `docs/releases/RELEASE_NOTES_v6.4.0.md` +- `docs/releases/V6_CHANGELOG_v6.4.0.md` + +For the preceding stable v6 packet, see: - `docs/releases/RELEASE_NOTES_v6.3.2.md` - `docs/releases/V6_CHANGELOG_v6.3.2.md` -For the preceding stable v6 packet, see: +For the preceding v6.4 release candidate packet, see: +- `docs/releases/RELEASE_NOTES_v6.4.0-rc.13.md` +- `docs/releases/V6_CHANGELOG_v6.4.0-rc.13.md` + +For the earlier stable v6 packet, see: - `docs/releases/RELEASE_NOTES_v6.3.1.md` - `docs/releases/V6_CHANGELOG_v6.3.1.md` -For the preceding v6.4 release candidate packet, see: +For the earlier v6.4 release candidate packet, see: - `docs/releases/RELEASE_NOTES_v6.4.0-rc.12.md` - `docs/releases/V6_CHANGELOG_v6.4.0-rc.12.md` diff --git a/docs/UPGRADE_v6.md b/docs/UPGRADE_v6.md index 57bb25754..3b603e744 100644 --- a/docs/UPGRADE_v6.md +++ b/docs/UPGRADE_v6.md @@ -2,22 +2,27 @@ This guide covers practical upgrade steps for existing Pulse installs moving to v6. -For the current v6 release candidate packet (the current v6 support release candidate packet), see: - -- `docs/releases/RELEASE_NOTES_v6.4.0-rc.13.md` -- `docs/releases/V6_CHANGELOG_v6.4.0-rc.13.md` - For the current stable v6 packet, see: +- `docs/releases/RELEASE_NOTES_v6.4.0.md` +- `docs/releases/V6_CHANGELOG_v6.4.0.md` + +For the preceding stable v6 packet, see: + - `docs/releases/RELEASE_NOTES_v6.3.2.md` - `docs/releases/V6_CHANGELOG_v6.3.2.md` -For the preceding stable v6 packet, see: +For the preceding v6.4 release candidate packet, see: + +- `docs/releases/RELEASE_NOTES_v6.4.0-rc.13.md` +- `docs/releases/V6_CHANGELOG_v6.4.0-rc.13.md` + +For the earlier stable v6 packet, see: - `docs/releases/RELEASE_NOTES_v6.3.1.md` - `docs/releases/V6_CHANGELOG_v6.3.1.md` -For the preceding v6.4 release candidate packet, see: +For the earlier v6.4 release candidate packet, see: - `docs/releases/RELEASE_NOTES_v6.4.0-rc.12.md` - `docs/releases/V6_CHANGELOG_v6.4.0-rc.12.md` diff --git a/docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md b/docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md index d1583104d..bb8ceeac8 100644 --- a/docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md +++ b/docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md @@ -475,9 +475,33 @@ TLS-unverified receipts leave the claim at `implemented` or silently change release behavior. - Windows artifacts remain bound by the exact release SHA, immutable candidate manifest, SHA-256 checksums, detached `.sig` and `.sshsig` - signatures, and published-digest verification. Public notes must disclose - that the binaries are not Authenticode-signed and may display an Unknown - Publisher warning. + signatures, and published-digest verification. Public notes must disclose + that the binaries are not Authenticode-signed and may display an Unknown + Publisher warning. +17. v6.4.0 expedited stable-cutoff exception: + - On 2026-08-28, the release owner explicitly directed stable `v6.4.0` + publication from runtime cutoff + `18b22d1ebbfe542484652e419320fc7643a792f0`, promoted from published + `v6.4.0-rc.12`, without another public candidate or the remainder of the + normal 72-hour soak. The dated decision record is + `docs/release-control/v6/internal/records/v6.4.0-stable-cutoff-owner-approval-2026-08-28.md`. + - The accepted reason is active customer harm from incorrect same-name + Proxmox agent links, repeated inspection load on stopped-container-heavy + Docker hosts, incomplete Proxmox backup and TrueNAS SMART detail, and + unstable rolling metric history. The decision explicitly includes the + bounded product fixes after `v6.4.0-rc.12`. + - This is a version-bound owner-risk acceptance, not soak evidence and not + a standing exception for later releases. The workflow input + `hotfix_exception=true` transports the approved waiver through the shared + resolver and does not reclassify v6.4.0 as a patch hotfix. + - The final release-preparation commit may change only governed version, + release-note, qualification, test-guardrail, and release-control metadata. + The integrated single-build workflow must pass its exact-SHA preflight and + immutable readiness gates before any publication boundary. Under the + current single-build policy, a separate Release Dry Run is optional. + - The standing Windows Authenticode-unavailable policy from v6.3.2 applies + independently. It retains checksum, detached-signature, immutable-manifest, + published-digest, and public Unknown Publisher disclosure controls. ## Single-Build Release Path diff --git a/docs/release-control/v6/internal/records/v6.4.0-stable-cutoff-owner-approval-2026-08-28.md b/docs/release-control/v6/internal/records/v6.4.0-stable-cutoff-owner-approval-2026-08-28.md new file mode 100644 index 000000000..7660e9c66 --- /dev/null +++ b/docs/release-control/v6/internal/records/v6.4.0-stable-cutoff-owner-approval-2026-08-28.md @@ -0,0 +1,53 @@ +# v6.4.0 Stable Cutoff Owner Approval + +- Decision date: `2026-08-28` +- Release: `v6.4.0` +- Runtime content cutoff: `18b22d1ebbfe542484652e419320fc7643a792f0` +- Promoted published prerelease: `v6.4.0-rc.12` +- Rollback target: `v6.3.2` +- Exact rollback reinstall command: `./scripts/install.sh --version v6.3.2` + +## Owner Decision + +The release owner explicitly directed stable `v6.4.0` publication from the +latest `main` cutoff and authorized shortening the normal 72-hour prerelease +soak. The approval covers the bounded product fixes after published +`v6.4.0-rc.12` and the final release-preparation metadata commit. The in-repo +`v6.4.0-rc.13` packet was not published and is not represented as additional +public prerelease lineage. + +The accepted reason is active customer harm from incorrect same-name Proxmox +agent links, repeated inspection load on stopped-container-heavy Docker hosts, +incomplete Proxmox backup and TrueNAS SMART detail, and unstable rolling metric +history. Promoting the bounded corrections avoids extending those known harms +only to manufacture another candidate observation window. + +This is a one-version owner-risk acceptance, not 72-hour soak evidence and not +a standing exception for later releases. The workflow input +`hotfix_exception=true` carries the approved waiver through the shared +promotion resolver. It does not reclassify this stable minor release as a patch +hotfix. + +The final release-preparation commit may change only governed version, +release-note, qualification, test-guardrail, and release-control metadata. The +normal single-build release workflow must consume the pushed exact SHA and pass +its integrated frontend, backend, mobile, candidate, signing-policy, staging, +activation, and convergence gates. Current policy does not require a separate +Release Dry Run because the publication workflow runs the same exact-SHA +preflight before crossing the release boundary. + +## Rollback And Compatibility Boundary + +The rollback target remains stable `v6.3.2` using the exact command above. +Pulse Mobile iOS build 12 and Android versionCode 9 already support +`action_type=view_alert`. The v6.4.0 server and Unified Agent changes do not +alter mobile routes, pairing, push, or resource payload contracts, so the +decision is `existing-mobile-build-compatible` and no companion upload is +required. + +The standing Windows Authenticode-unavailable policy from v6.3.2 applies +independently. Windows agents remain bound to the exact release SHA, immutable +candidate manifest, SHA-256 checksums, detached `.sig` and `.sshsig` +signatures, and published-digest verification. Public notes must disclose that +the binaries are not Authenticode-signed and may display an Unknown Publisher +warning. diff --git a/docs/release-control/v6/internal/status.json b/docs/release-control/v6/internal/status.json index 88388ab1a..906657a50 100644 --- a/docs/release-control/v6/internal/status.json +++ b/docs/release-control/v6/internal/status.json @@ -9766,7 +9766,21 @@ } ], "candidate_lanes": [], - "work_claims": [], + "work_claims": [ + { + "id": "ga-release-6-4-0-lane-l1", + "agent_id": "ga-release-6-4-0", + "summary": "Prepare and publish v6.4.0 GA from the latest main cutoff under the owner-authorized expedited promotion, with exact-SHA qualification and release convergence.", + "target_id": "v6-product-lane-expansion", + "claimed_at": "2026-08-28T22:31:03Z", + "heartbeat_at": "2026-08-28T22:31:03Z", + "expires_at": "2026-08-29T06:31:03Z", + "work_item": { + "kind": "lane", + "id": "L1" + } + } + ], "open_decisions": [], "source_of_truth_file": "docs/release-control/v6/internal/SOURCE_OF_TRUTH.md", "resolved_decisions": [ @@ -10757,6 +10771,18 @@ "lane_ids": [ "L1" ] + }, + { + "id": "v6-4-0-expedited-stable-cutoff", + "summary": "On 2026-08-28 the release owner explicitly directed stable v6.4.0 publication from runtime cutoff 18b22d1ebbfe542484652e419320fc7643a792f0, promoted from published v6.4.0-rc.12, without another public candidate or the remainder of the normal 72-hour soak. The accepted reason is active customer harm from incorrect same-name Proxmox agent links, repeated Docker inspection load, incomplete backup and SMART detail, and unstable rolling metric history. This is a version-bound owner-risk acceptance that includes the bounded post-RC product fixes. It is not soak evidence or a standing exception.", + "kind": "release-policy", + "decided_at": "2026-08-28", + "subsystem_ids": [ + "deployment-installability" + ], + "lane_ids": [ + "L1" + ] } ] } diff --git a/docs/release-control/v6/internal/subsystems/deployment-installability.md b/docs/release-control/v6/internal/subsystems/deployment-installability.md index 3825eefaa..7b2a10258 100644 --- a/docs/release-control/v6/internal/subsystems/deployment-installability.md +++ b/docs/release-control/v6/internal/subsystems/deployment-installability.md @@ -1856,14 +1856,19 @@ 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.13` cut sets the repo-root `VERSION`, repo-root +The active stable `v6.4.0` 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.13` release version. It -follows `v6.4.0-rc.12` 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 makes the append-only +Helm chart release metadata to the same `6.4.0` release version. This stable +minor release uses `promoted_from_tag=v6.4.0-rc.12`, +`rollback_version=v6.3.2`, and the explicit version-bound owner decision +recorded on 2026-08-28 to accept a shortened soak and the bounded product fixes +after that published candidate. The workflow input `hotfix_exception=true` +transports that approved waiver through the shared promotion resolver. It does +not reclassify v6.4.0 as a patch hotfix. The integrated single-build workflow +must pass its exact-SHA preflight and immutable readiness gates before +publication. Under the current single-build policy, a separate Release Dry Run +is optional. Stable/latest install pointers and stable semver aliases move only +after the exact public and private candidate paths pass. The release 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; @@ -1894,24 +1899,23 @@ state, which removes one daemon call per historical container from each normal 30-second report. It also restores same-name standalone Proxmox host-agent links when unique provider-observed interface addresses disambiguate the sites, while reused addresses remain ambiguous and fail closed. -It also checkpoints a crash-safe active-state recovery envelope after durable +The post-rc.12 cutoff also checkpoints a crash-safe active-state recovery envelope after durable lifecycle failure and prevents any Pulse host interface from satisfying an -external dead-man signal. The changes since +external dead-man signal. The stable server cut is classified +`existing-mobile-build-compatible`. 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 +rollout is part of this stable release. 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 -policy and retains the same exact-SHA, checksum, detached-signature, manifest, +Stable `v6.4.0` skips SignPath under the standing unavailable policy and +retains exact-SHA, checksum, detached-signature, immutable-manifest, published-digest, and Unknown Publisher disclosure controls. Signing returns only after the release owner explicitly confirms that production credentials and certificate authorization are ready and a reviewed policy/code change @@ -2445,9 +2449,10 @@ 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.13` cut, the repo-root compose default and -`scripts/install-docker.sh` fallback must both pin `6.4.0-rc.13` until the next -governed stable cut moves them forward. Each new release moves +For the active stable `v6.4.0` cut, the repo-root compose default and +`scripts/install-docker.sh` fallback must both pin `6.4.0` until the next +governed release moves them forward. The stable promotion guard remains in +force and rejects leftover `-rc.` defaults. 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 release-packet blocker. @@ -2740,13 +2745,13 @@ release-body verification: the exact claim is pinned in must still pass canonical shape validation. The `v6.4.0-rc.2` packet therefore binds the non-running container stale-health correction under **Fixes** without changing candidate artifact identity or dispatch authority. -The `v6.4.0-rc.13` packet may continue accumulating compatible fixes while its -public observation window prevents publication. When that happens, customer -notes and the categorized changelog must be refreshed in the same commit as -the added fix, and release-body proof must pin the new customer-facing claim. -The TrueNAS SMART follow-up is therefore bound to its supported typed-counter -claim; packet proof must reject notes that drop that claim or cease to pass -canonical shape validation. +The stable `v6.4.0` packet synthesizes the complete difference from `v6.3.2` +rather than concatenating candidate notes. It retains the supported TrueNAS +typed-counter claim, post-rc.12 Docker and Proxmox corrections, rolling-history +snapshot fix, standing unsigned-Windows disclosure, mobile compatibility +decision, rollback target, and owner-authorized expedited-promotion record. +Packet proof must reject notes that drop those required release boundaries or +cease to pass canonical shape validation. Release-note transport is file-backed and fail-closed: operator helpers must send the Markdown through JSON input rather than multiline form-field substitution, and every `gh workflow run --json` input value must be encoded as diff --git a/docs/releases/RELEASE_NOTES_v6.4.0.md b/docs/releases/RELEASE_NOTES_v6.4.0.md new file mode 100644 index 000000000..7db1cef85 --- /dev/null +++ b/docs/releases/RELEASE_NOTES_v6.4.0.md @@ -0,0 +1,24 @@ +# Pulse v6.4.0 Release Notes + +`v6.4.0` is a stable minor release that makes alerts more trustworthy and actionable, detects capacity and hardware risk earlier, and keeps large or mixed infrastructure estates fast, accurate, and easier to operate. + +## What's improved + +- **Alerts that survive restarts** - Active incidents, acknowledgements, snoozes, resolutions, and delivery evidence now rebuild from a durable event log without briefly showing a false all-clear. +- **More control over notifications** - Use informational severity, snooze alerts, schedule scoped recurring maintenance, route destinations by severity, repeat critical escalations, and see why delivery was sent, held, suppressed, or failed. +- **Earlier resource warnings** - Rolling CPU averages detect sustained pressure instead of reacting to one sample, while predictive storage alerts warn when current growth could exhaust capacity. +- **Stronger disk-health monitoring** - Expanded SMART policies cover sector, media, endurance, spare, and CRC risks. TrueNAS evidence stays visible, empty Unraid slots stay neutral, and duplicate Proxmox disks merge. +- **External monitoring for Pulse itself** - Pulse can ping a Healthchecks-compatible service every minute, report interruptions after restart, and reject endpoints on the Pulse host that could mask an outage. +- **Faster large estates** - Windowed tables and keyed live updates cut the measured Storage cold load from about 15.6 seconds to 1.1 seconds. Docker also avoids re-inspecting unchanged stopped containers every 30 seconds. +- **Clearer desktop and mobile workflows** - Consistent tables, drawers, timelines, charts, touch controls, and searchable phone Settings make infrastructure details and alert investigations easier to navigate. +- **More accurate Proxmox and PBS coverage** - Node identity, history, networking, backups, RAID members, LXC filesystems, and linked agents now retain the correct source and context, even when installations reuse node names. +- **More reliable agents and actions** - Credential changes are atomic, re-enrolment is available from diagnostics, install tokens are easier to copy, and Proxmox VM or LXC actions no longer require a QEMU guest agent. +- **More dependable Patrol runs** - Patrol retries provider startup on each schedule, reconciles existing findings when enabled, verifies Docker recovery, and uses current Anthropic model pricing for budget enforcement. +- **Updates that work through rate limits** - If GitHub releases are rate limited, Pulse selects the correct release and signed archive for the current Linux architecture so in-app updates can still start. + +## Before you upgrade + +- Existing configurations remain valid. Alert identity and history migrations run automatically, with no manual data migration required. +- Pulse Mobile iOS build 12 and Android versionCode 9 remain compatible. The new `alert_fired` push uses the existing `view_alert` action, so no companion mobile release is required. +- Windows Unified Agent binaries are not Authenticode-signed while SignPath remains unavailable and may show an Unknown Publisher warning. Verify downloads with the published checksums and detached signatures. +- The rollback target is stable `v6.3.2`. Use `./scripts/install.sh --version v6.3.2` if you need to return to the previous stable release. diff --git a/docs/releases/V6_CHANGELOG_v6.4.0.md b/docs/releases/V6_CHANGELOG_v6.4.0.md new file mode 100644 index 000000000..68c8f502e --- /dev/null +++ b/docs/releases/V6_CHANGELOG_v6.4.0.md @@ -0,0 +1,68 @@ +# Pulse v6.4.0 + +This changelog describes the complete stable release train since `v6.3.2`. + +## Added + +- Rolling-window CPU evaluation detects sustained pressure from retained metric history while holding incident state when the sample window is incomplete. +- Predictive storage-capacity alerts estimate exhaustion risk from retained usage trends and recover when trustworthy evidence moves the forecast outside the risk window. +- Per-alert snooze, recurring scoped maintenance, destination severity routing, repeating escalation schedules, and external Healthchecks-compatible dead-man monitoring expand operator control over alert delivery. +- Resolved host SMART policy covers overall health, sector counters, media errors, remaining life, NVMe spare, and CRC growth without creating duplicate Proxmox disk alerts. +- Informational alerts retain an explicit `info` severity through configuration, persistence, API responses, filtering, notification routing, and presentation. +- Canonical `alert_fired` push events use the existing mobile `view_alert` navigation action. +- Diagnostics can re-enrol a blocked agent, and the generated agent install flow makes the newly issued token available for a deliberate copy action. + +## Changed + +- The append-only event log is authoritative for alert history and active lifecycle reconstruction, including restart recovery, acknowledgement, snooze, 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 without a false all-clear during hydration. +- Alert delivery and recovery decisions are destination-specific, repeated holds are coalesced, and destination updates persist before the active runtime changes. +- Large infrastructure views use windowed rows, keyed deltas, incremental hydration, and interaction-aware live update deferral to keep navigation and scrolling responsive. +- Resource tables and detail drawers share consistent information, filtering, history, touch, and responsive layout patterns across infrastructure, Docker, storage, Proxmox, and alerts. +- Phone Settings use a searchable two-level workspace with a sticky section title and touch-sized controls. +- Narrow alert investigations use a dedicated timeline dialog, while shared history charts synchronize hover timestamps and retain readable axes. +- Standalone Proxmox identity reconciliation uses provider endpoints and TLS evidence to distinguish installations that reuse node names without borrowing another site's linked agent. +- Proxmox and PBS views retain source-specific node, network, backup, RAID, LXC filesystem, inventory, and history context. +- Unchanged inactive Docker container details are cached for 15 minutes. Running, paused, restarting, changed, and incompletely described containers remain on the live inspection path. +- Docker lifecycle results distinguish command acceptance from independently observed post-action state, and Patrol requires observed health recovery before closing a finding. +- API token creation, agent install issuance, agent removal, and deployment enrollment share atomic live-and-durable credential boundaries. +- GitHub Atom fallback parsing retains release timestamps and selects the current Linux architecture's signed archive from a validated version tag. +- Patrol retries provider startup on each scheduled run, reconciles existing actionable findings when enabled, and reports the blocking reason when the provider remains unavailable. +- Anthropic cost accounting distinguishes current Opus and Haiku generations from legacy aliases when enforcing Patrol budgets. +- Release, telemetry, update, and GitHub-star prompts share a quieter non-blocking presentation and do not claim published notes for development builds. + +## Fixed + +- Docker hosts with many stopped containers no longer re-inspect every historical container on each 30-second report. Lifecycle changes invalidate cached detail immediately and daemon reconnects clear the cache. +- Separate standalone Proxmox sites that reuse a short node name no longer lose correct agent links when provider-observed addresses uniquely disambiguate them. +- Sequential standalone Proxmox connections no longer reuse the first connection's linked agent when names are ambiguous or endpoints do not match. +- Proxmox backup details remain on the Backups surface with complete current server and datastore context instead of being duplicated or displaced on Overview. +- Configured PVE node interface names and IPv4 or IPv6 addresses remain visible even when no host agent is linked. +- TrueNAS SMART alerts retain uniquely resolved critical disk evidence and supported uncorrectable-error and spare-reserve counters instead of allowing a damaged disk to appear healthy. +- Empty Unraid array slots no longer materialize as physical disks or contribute a false degraded state. +- PVE and agent observations of the same RAID-controller volume no longer render duplicate resources when serial and WWN framing differ. +- Fresh rolling-window metric data remains authoritative when persisted history contains an older point at the same timestamp, and concurrent history replacement keeps one stable evaluation snapshot. +- Unchanged remote agent configuration refreshes no longer create repetitive log noise. +- GitHub API rate limiting no longer leaves in-app release checks with a new version but no archive URL or publication timestamp. +- Failed token persistence no longer leaves an undisclosed token active, evicts an older valid token, or allows an apparent revocation to reverse after restart. +- Mobile alert timelines remain scroll-stable, selected incident history revalidates correctly, chart labels stay readable, and grouped hover timestamps remain aligned. +- Restart recovery, history queries, and mock alert timelines preserve lifecycle order, observation time, and complete incident evidence. +- Proxmox backup health, inventory refresh, offline fixtures, and drawer detail presentation retain complete current context. +- Current Anthropic Opus usage is no longer overestimated at legacy rates, and Haiku 4.5 is no longer underestimated at Haiku 3 rates. +- Informational active-alert cards use the blue severity palette, while unknown severity values fail safe to warning presentation. +- Alert-lifecycle failures synchronously checkpoint a crash-safe recovery envelope before shutdown, and malformed degraded-state markers cannot make startup trust a stale SQLite projection. +- Dead-man configuration and dial-time DNS validation reject every address assigned to the Pulse host. + +## Release Metadata + +- Version: `v6.4.0` +- Previous stable: `v6.3.2` +- Promoted prerelease: `v6.4.0-rc.12` +- Runtime content cutoff: `18b22d1ebbfe542484652e419320fc7643a792f0` +- Rollback target: `v6.3.2` +- Rollback command: `./scripts/install.sh --version v6.3.2` +- Promotion path: owner-approved expedited exact-SHA stable cutoff from `main` +- Promotion decision: the release owner accepted a shortened soak to deliver bounded fixes for active monitoring correctness and collection-load harm. This is version-bound risk acceptance, not soak evidence or a standing exception. +- Windows signing decision: the standing SignPath-unavailable policy applies. Windows agents are not Authenticode-signed, may show an Unknown Publisher warning, and retain exact-SHA checksums, detached signatures, immutable-manifest verification, and published-digest verification. +- Mobile decision: `existing-mobile-build-compatible` +- Mobile evidence: Pulse Mobile iOS build 12 and Android versionCode 9 already support `action_type=view_alert`. Server and Unified Agent changes do not alter mobile routes, pairing, push, or resource payload contracts, so no companion upload is required. diff --git a/frontend-modern/public/docs/UPGRADE_v6.md b/frontend-modern/public/docs/UPGRADE_v6.md index 57bb25754..3b603e744 100644 --- a/frontend-modern/public/docs/UPGRADE_v6.md +++ b/frontend-modern/public/docs/UPGRADE_v6.md @@ -2,22 +2,27 @@ This guide covers practical upgrade steps for existing Pulse installs moving to v6. -For the current v6 release candidate packet (the current v6 support release candidate packet), see: - -- `docs/releases/RELEASE_NOTES_v6.4.0-rc.13.md` -- `docs/releases/V6_CHANGELOG_v6.4.0-rc.13.md` - For the current stable v6 packet, see: +- `docs/releases/RELEASE_NOTES_v6.4.0.md` +- `docs/releases/V6_CHANGELOG_v6.4.0.md` + +For the preceding stable v6 packet, see: + - `docs/releases/RELEASE_NOTES_v6.3.2.md` - `docs/releases/V6_CHANGELOG_v6.3.2.md` -For the preceding stable v6 packet, see: +For the preceding v6.4 release candidate packet, see: + +- `docs/releases/RELEASE_NOTES_v6.4.0-rc.13.md` +- `docs/releases/V6_CHANGELOG_v6.4.0-rc.13.md` + +For the earlier stable v6 packet, see: - `docs/releases/RELEASE_NOTES_v6.3.1.md` - `docs/releases/V6_CHANGELOG_v6.3.1.md` -For the preceding v6.4 release candidate packet, see: +For the earlier v6.4 release candidate packet, see: - `docs/releases/RELEASE_NOTES_v6.4.0-rc.12.md` - `docs/releases/V6_CHANGELOG_v6.4.0-rc.12.md` diff --git a/scripts/install-docker.sh b/scripts/install-docker.sh index 0db3d2cd6..4343c8b4f 100755 --- a/scripts/install-docker.sh +++ b/scripts/install-docker.sh @@ -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.13" +CANONICAL_DEFAULT_PULSE_VERSION="6.4.0" resolve_default_pulse_version() { if [ -n "${PULSE_IMAGE_VERSION:-}" ]; then diff --git a/scripts/installtests/build_release_assets_test.go b/scripts/installtests/build_release_assets_test.go index 6148ab6d6..c0c8b6118 100644 --- a/scripts/installtests/build_release_assets_test.go +++ b/scripts/installtests/build_release_assets_test.go @@ -812,20 +812,23 @@ func TestCurrentStableMinorReleasePacketTracksInstallMetadata(t *testing.T) { assertFileContainsAllNormalized(t, releaseNotesPath, "`v"+version+"` is a stable minor release", "stable `v"+previous+"`", - "## Highlights", - "Operational Trust", - "Actions provides a dedicated inbox", - "existing Pulse Mobile candidate", + "## What's improved", + "Alerts that survive restarts", + "More control over notifications", + "Earlier resource warnings", + "More accurate Proxmox and PBS coverage", + "Pulse Mobile iOS build 12 and Android versionCode 9 remain compatible", "not Authenticode-signed", "Unknown Publisher warning", - "The rollback target is `v"+previous+"`", + "The rollback target is stable `v"+previous+"`", ) assertFileContainsAllNormalized(t, changelogPath, "Version: `v"+version+"`", "Previous stable: `v"+previous+"`", "Rollback target: `v"+previous+"`", - "Promotion path: owner-approved exact-SHA stable cutoff from `main`", + "Promotion path: owner-approved expedited exact-SHA stable cutoff from `main`", "Mobile decision: `existing-mobile-build-compatible`", + "standing SignPath-unavailable policy applies", ) assertFileContainsAll(t, repoFile("docs", "RELEASE_NOTES.md"), "docs/releases/RELEASE_NOTES_v"+version+".md", @@ -855,9 +858,10 @@ func TestCurrentStableMinorReleasePacketTracksInstallMetadata(t *testing.T) { assertFileContainsAllNormalized(t, repoFile("docs", "release-control", "v6", "internal", "subsystems", "deployment-installability.md"), "The active stable `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.", "`rollback_version=v"+previous+"`", - "The exact stable `main` SHA must pass the no-publication dry run before the same SHA is dispatched through the single-build publish workflow.", + "The integrated single-build workflow must pass its exact-SHA preflight and immutable readiness gates before publication.", "The stable server cut is classified `existing-mobile-build-compatible`.", - "explicit version-bound decision", + "explicit version-bound owner decision", + "standing unavailable policy", "For the active stable `v"+version+"` cut, the repo-root compose default and `scripts/install-docker.sh` fallback must both pin `"+version+"`", ) } diff --git a/scripts/installtests/install_docker_sh_test.go b/scripts/installtests/install_docker_sh_test.go index 4c66a8aa4..9a1bfa1ee 100644 --- a/scripts/installtests/install_docker_sh_test.go +++ b/scripts/installtests/install_docker_sh_test.go @@ -353,9 +353,10 @@ func TestInstallDockerProofTracksStableMinorContract(t *testing.T) { assertFileContainsAllNormalized(t, repoFile("docs", "release-control", "v6", "internal", "subsystems", "deployment-installability.md"), "The active stable `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.", "`rollback_version=v"+previous+"`", - "`hotfix_exception=true` transports that approved waiver through the shared promotion resolver; it does not reclassify v"+version+" as a patch hotfix.", - "The release owner separately approved a v"+version+"-only unsigned-Windows exception", - "The Windows packet must disclose the Unknown Publisher warning and retain exact-SHA, checksum, detached-signature, immutable-manifest, and published-digest verification.", + "`hotfix_exception=true` transports that approved waiver through the shared promotion resolver. It does not reclassify v"+version+" as a patch hotfix.", + "The integrated single-build workflow must pass its exact-SHA preflight and immutable readiness gates before publication.", + "The stable server cut is classified `existing-mobile-build-compatible`.", + "Stable `v"+version+"` skips SignPath under the standing unavailable policy and retains exact-SHA, checksum, detached-signature, immutable-manifest, published-digest, and Unknown Publisher disclosure controls.", "For the active stable `v"+version+"` cut, the repo-root compose default and `scripts/install-docker.sh` fallback must both pin `"+version+"`", ) } diff --git a/scripts/release_control/release_promotion_policy_test.py b/scripts/release_control/release_promotion_policy_test.py index c1f09ad65..b81338c98 100644 --- a/scripts/release_control/release_promotion_policy_test.py +++ b/scripts/release_control/release_promotion_policy_test.py @@ -1824,6 +1824,32 @@ class ReleasePromotionPolicyTest(unittest.TestCase): self.assertIn("not Authenticode-signed", patch_signing_record) self.assertIn("Unknown Publisher warning", patch_signing_record) + def test_v640_expedited_stable_cutoff_is_version_bound(self) -> None: + policy = normalize_ws( + read("docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md") + ) + owner_record = normalize_ws( + read( + "docs/release-control/v6/internal/records/" + "v6.4.0-stable-cutoff-owner-approval-2026-08-28.md" + ) + ) + + self.assertIn("v6.4.0 expedited stable-cutoff exception", policy) + self.assertIn("not soak evidence and not a standing exception", policy) + self.assertIn("Runtime content cutoff: `18b22d1ebbfe542484652e419320fc7643a792f0`", owner_record) + self.assertIn("Promoted published prerelease: `v6.4.0-rc.12`", owner_record) + self.assertIn("Rollback target: `v6.3.2`", owner_record) + self.assertIn( + "Exact rollback reinstall command: `./scripts/install.sh --version v6.3.2`", + owner_record, + ) + self.assertIn("active customer harm", owner_record) + self.assertIn("not 72-hour soak evidence", owner_record) + self.assertIn("standing Windows Authenticode-unavailable policy", owner_record) + self.assertIn("not Authenticode-signed", owner_record) + self.assertIn("Unknown Publisher warning", owner_record) + unavailable_signing_record = normalize_ws( read( "docs/release-control/v6/internal/records/" diff --git a/scripts/release_control/render_release_body_test.py b/scripts/release_control/render_release_body_test.py index 3b9beaff8..e26de02c0 100644 --- a/scripts/release_control/render_release_body_test.py +++ b/scripts/release_control/render_release_body_test.py @@ -29,6 +29,25 @@ def _discover_rc_draft_packet_paths() -> tuple[str, ...]: class RenderReleaseBodyTest(unittest.TestCase): + def test_v640_stable_packet_keeps_release_boundaries_visible(self) -> None: + notes = ( + _REPO_ROOT / "docs" / "releases" / "RELEASE_NOTES_v6.4.0.md" + ).read_text(encoding="utf-8") + + for expected in ( + "Alerts that survive restarts", + "More control over notifications", + "Earlier resource warnings", + "More accurate Proxmox and PBS coverage", + "Pulse Mobile iOS build 12 and Android versionCode 9 remain compatible", + "not Authenticode-signed", + "Unknown Publisher warning", + "The rollback target is stable `v6.3.2`", + ): + self.assertIn(expected, notes) + self.assertNotIn("## Fixes", notes) + render_release_body.validate_release_notes_shape(notes, "6.4.0") + def test_rc13_packet_keeps_typed_truenas_smart_evidence_visible(self) -> None: notes = ( _REPO_ROOT / "docs" / "releases" / "RELEASE_NOTES_v6.4.0-rc.13.md"