backup_existing snapshots the configuration before the update stages, but a
staging disk-headroom failure then exited and left that snapshot behind. On a
small root filesystem each automatic retry added another full backup and made
the low-space condition progressively worse until updates could no longer run
(#2127). Record the snapshot and remove it when download_pulse aborts at the
headroom check, before anything was replaced. Add regression coverage.
Change-source: pulse-maintainer
The RETURN trap installed inside perform_update is shell-global and was left
installed after the function returned. It fired again when a later function
returned, expanding the now out-of-scope local installer_tmp/signature_tmp
under set -u, so pulse-update.service reported a successful install as failed
with 'installer_tmp: unbound variable' (#2128). Clear the trap as it runs and
cover it with a regression test.
Change-source: pulse-maintainer
The five unified syncs ran serially and each waited for its own SQLite commit, so a registry rebuild that carried new data for several resource types opened one transaction per type and re-committed the same WAL. Collect the agent, VM, storage and app-container writes through a batch sink and commit them once; the per-series replay guard still runs first, so the series, values and source observation times are unchanged. Standalone callers keep the immediate write. Focused proof in monitor_host_agents_test.go; contract sections recorded in monitoring.md and agent-lifecycle.md.
Change-source: pulse-maintainer
Record the unified physical-disk SMART runtime commit abaca8f9c0 and its
contract/proof follow-up 33260be25b as one reviewed completion unit so the
per-commit canonical guard evaluates the pair together.
Change-source: pulse-maintainer
The unified physical-disk sync now anchors SMART history to the source
observation time and drops exact replays, so the monitoring and
agent-lifecycle contract sections record the disk-history behaviour and its
focused proof. The proof lives in monitor_host_agents_test.go alongside the
other unified-sync rebuild tests.
Change-source: pulse-maintainer
syncUnifiedPhysicalDiskMetrics stamped every SMART sample with the registry rebuild wall clock and wrote through the unguarded buffered path, so each read-side rebuild re-issued the same physical-disk observation as fresh rows (#1966). writeSMARTMetrics now anchors both the in-memory history and the persisted batch to the source observation time and drops exact replays through the existing unified guard; the unified sync passes unifiedResourceObservedAt. Adds a two-rebuild focused proof and updates the TrueNAS disk fixture to a current observation time.
Change-source: pulse-maintainer
The unified syncs now timestamp history with the source observation time, so the TrueNAS and VMware fixtures must carry a current collectedAt for the in-memory and chart windows to retain the samples. The previous fixed 2026-03 fixtures represented data older than the 24h history retention and would be trimmed. No production behaviour changes.
Change-source: pulse-maintainer
The replay guard added in df44238797 only suppressed repeats for storage, whose samples already carry the provider LastSeen. The agent, VM and app-container syncs still stamped every write with the rebuild wall clock, so dedupeUnifiedMetricWrites could never match and each read-side registry rebuild re-issued the whole batch as fresh rows. That is the same WAL churn described in #1966, still live for VMware/TrueNAS VMs, TrueNAS apps and supplemental agents.
Resolve each resource's observation time from its metric source (unifiedResourceObservedAt) and use it for both the in-memory history point and the store write, matching the storage path. Proxmox and libvirt VMs already have native history writers, so exclude libvirt VMs from the unified VM sync to avoid writing a second timeline for the same series.
Contract sections recorded in monitoring.md and agent-lifecycle.md; focused proof added in monitor_polling_test.go and monitor_host_agents_test.go. Local Go compilation is unavailable this turn (module cache read-only, toolchain snapshot missing); the canonical completion guard passes and gofmt is clean.
Change-source: pulse-maintainer
Bind the create-release pair preflight commit to the follow-up contract and proof commit as one reviewed completion unit, matching the existing canonical completion history entries.
Change-source: pulse-maintainer
The create-release prepare job now verifies that pulse-enterprise declares docs/release-source-pairs/<expected_source_sha>.json and that it names the frozen public commit before any draft release object exists. Record that obligation in the deployment-installability contract and add the release-promotion policy proof that guards the step and its ordering ahead of create_release.
Change-source: pulse-maintainer
A 6.x release creates its draft release object before stage_private_pro_runtime dispatches the private Pro build, which resolves the payload by the exact frozen public commit (docs/release-source-pairs/<sha>.json). When that declaration is absent or names a different pulse_sha, the private build refuses and the run leaves an orphaned draft (v6.4.5-beta.2, v6.4.5-beta.3). Verify the declaration in prepare, before any draft exists, and fail with the exact path to create. This is an unconditional fact check independent of the opt-in harness gate in pulse-dev-infra #443/#444; the release steward still owns choosing the pair. Source issue: pulse-dev-infra #441.
Change-source: pulse-maintainer
Recover Windows host info when MachineGuid is braced: read MachineGuid directly when gopsutil's combined InfoWithContext fails on the host-ID field, and canonicalise Windows machine IDs so a braced GUID and its bare form resolve to one stable agent identity. Fixes#2125.
Change-source: pulse-maintainer
The Windows unified agent exits at startup when HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid is a braced GUID. gopsutil v4.26.6 reads the value through a fixed 74-byte buffer and rejects any length other than 36, so a braced 38-character GUID fails the whole InfoWithContext call and newAgent aborts with 'fetch host info'. Recover the host info on Windows when the host-ID read is the failing field: read MachineGuid directly, strip braces and fill the other fields from gopsutil accessors, while keeping any non-host-ID failure fatal. Canonicalise Windows machine IDs by removing braces so both forms map to one stable agent identity. Includes agent-lifecycle contract section and focused proof in the registry-accepted agent_new_test.go. Windows recovery is cross-compiled with GOOS=windows; runtime execution on Windows is not qualified in this environment.
Change-source: pulse-maintainer
Dependabot #2094, #2095 and #2096 bump actions/setup-go 6.4.0 -> 7.0.0, signpath/github-action-submit-signing-request 2 -> 3.0 and actions/github-script 8.0.0 -> 9.0.0. Each proposal is blocked only by the reviewed pin constants, the workflow-trust allowlist, the release-consumer action manifest and the installer governance assertions that hard-code the previous revisions. Carry all three bumps with those artifacts in one commit so the proposals can be closed as superseded.
All three actions keep the node24 runtime and their existing inputs and outputs; no consumer interface, installer behaviour or public contract changes. The deployment-installability and agent-lifecycle workflow references are pin-only.
Contract-Neutral: Reviewed action pin refresh with identical node24 consumer interfaces and unchanged inputs/outputs; no public-contract or installer-behaviour delta.
Change-source: pulse-maintainer
Register the reviewed completion pair for the TrueNAS legacy-REST memory telemetry runtime commit and its contract/proof follow-up so canonical governance evaluates them as one unit without rewriting history.
Change-source: pulse-maintainer
Record the monitoring contract section for the TrueNAS legacy-REST memory telemetry repair and move its regression coverage into the registry-accepted internal/truenas/client_test.go proof file. The runtime commit and this contract/proof follow-up are one reviewed completion unit.
Change-source: pulse-maintainer
On the legacy REST transport used by TrueNAS CORE 13, GetSystemTelemetry had no reporting.realtime subscription, so MemoryAvailableBytes and ARCSizeBytes stayed zero and trueNASEffectiveMemoryUsed collapsed to total, reporting every CORE install as 100% used (#2077). Reconstruct live telemetry and host-chart history from reporting.get_data over REST, and when no available reading exists mark agent memory UsageUnavailable instead of fabricating usage from total-0.
Change-source: pulse-maintainer
The npm-minor-patch group (Dependabot #2115) has been held since 17 Sep
because it bundles @playwright/test, playwright and playwright-core
1.56.1 -> 1.63.0 with 12 safe frontend updates. The offline
browser-verification runtime is pinned to Playwright 1.56.1, so a lockfile
bump breaks browser-proof parity; holding the whole group blocked the safe
updates instead.
Ignore Playwright version updates on the governed 1.56.1 line, matching the
docker governed-tag policy, so the remaining grouped updates can be reviewed
on their own. Security updates stay covered by the weekly npm-audit scan and
the frontend dependencySecurity proof. Extend the dependabot config guard to
lock the policy in.
Change-source: pulse-maintainer
Integrate the reviewed FreeBSD/pfSense installer checksum-tool fallback. FreeBSD base ships sha256(1) but neither GNU sha256sum nor Perl shasum, so installer_file_sha256 in scripts/install.sh now falls back through sha256sum, sha256 -q, shasum -a 256 and openssl dgst -sha256, routing the main binary, typed privileged helper and action runner checksums through it; scripts/install-mcp.sh gains the same sha256 -q branch. Contract sections agent-lifecycle.md and deployment-installability.md record the platform digest-tool contract, with install_sh_test.go and build_release_assets_test.go proof.
The reviewed tip's parent is 838ca6f26d; this merge preserves its identity.
Change-source: pulse-maintainer
Register the reviewed completion pair for the FreeBSD checksum-tool fallback runtime commit and its contract/proof follow-up so canonical governance evaluates them as one unit without rewriting history.
Change-source: pulse-maintainer
FreeBSD base ships sha256(1) but not GNU sha256sum or Perl shasum. Record the fallback contract for the unified and MCP installers and add the MCP installer proof the deployment-installability verification policy requires.
Change-source: pulse-maintainer
FreeBSD base ships sha256(1) but not GNU sha256sum or Perl shasum, so a
fresh pfSense/FreeBSD host without coreutils failed the download checksum
and refused to install. Route every installer checksum through
installer_file_sha256 and fall back through sha256sum, sha256 -q, shasum and
openssl dgst. install-mcp.sh gets the same sha256 branch. Add a focused test
that hides sha256sum/shasum and asserts the FreeBSD fallback returns the
digest.
Change-source: pulse-maintainer
Integrate the reviewed #2070 vSphere VI JSON fix. vCenter 8.0.3 rejects a composite request data object that omits the documented _typeName discriminator with HTTP 500; a bare ManagedObjectReference is special-cased and accepted. Send _typeName on PerfQuerySpec, PerfMetricId, EventFilterSpec, EventFilterSpecByEntity and the ManagedObjectReference arguments, with focused request-shape tests pinning the serialized QueryPerf and QueryEvents bodies (c978cc452c). The reviewed tip's parent is 9444da374f; this merge preserves its identity.
Change-source: pulse-maintainer
The vmware test package defines writeJSON as a function-local closure, so the new request-shape test needs its own package-level helper.
Change-source: pulse-maintainer
The vSphere VI JSON API documents _typeName on request data objects. Calls whose only argument is a bare ManagedObjectReference (QueryPerfProviderSummary, QueryAvailablePerfMetric) succeed against vCenter 8.0.3, but every call that passes a composite data object (PerfQuerySpec/PerfMetricId for QueryPerf, EventFilterSpec/EventFilterSpecByEntity for QueryEvents) is rejected with HTTP 500. Issue #2070 shows exactly that split, so add the discriminators the documented schema carries to those request bodies. Morefs now carry _typeName too, matching the same schema. Focused tests pin the serialized request bodies.
Change-source: pulse-maintainer
The vSphere JSON API represents an absent or null property (for example the parent of a top-level folder) as a successful response with an empty body, which was decoded as a spurious 'not valid JSON' enrichment error. Non-2xx responses also carry a JSON fault body that was discarded. See #2070.
Change-source: pulse-maintainer
Integrate the reviewed #2122 TrueNAS system-temperature fix (9a1cfa4c40) that rejects the synthesised cpu_package aggregate in favour of the hottest per-core reading, with its focused provider coverage and monitoring subsystem contract note. The reviewed commit's parent is 9459ec7f26; this merge preserves its identity.
Change-source: pulse-maintainer
TrueNAS SCALE on AMD reports the bare `cpu` cputemp legend series at roughly 1.5x the hottest per-core reading, and the provider trusted that mapped `cpu_package` value unconditionally, firing an 80C threshold alert at a real ~60C. Compare `cpu_package` against the hottest `cpu*` per-core entry and fall back to the per-core max only when the package value exceeds it by more than 20%. Package-only and per-core-only payloads keep their existing behaviour. Adds focused provider coverage and records the selection contract for #2122.
Change-source: pulse-maintainer
Integrate the reviewed #2121 guest-drawer filesystem panel ordering fix (958eae0744) with its contract assertion and the Playwright browser receipt recomposed into the same commit. The reviewed commit's parent is 22fd851e72; this merge preserves its identity.
Change-source: pulse-maintainer
The shared DetailSectionTable span algorithm gives the earlier of the last two compact sections the wider column. GuestDrawerOverview declared Tags before Filesystems, so a guest with tags and disks but no network section rendered Tags two tiles wide and the mount-point list one tile wide, which the reporter found hard to read (#2121). Declaring Filesystems first gives the longer list the readable panel and keeps the short tag list narrow.
Recomposes the reviewed #2121 fix and its Playwright browser receipt into a single commit on the current maintenance base (22fd851e72), because the per-commit browser guard requires the receipt in the same commit as the user-visible frontend source. The GuestDrawerOverview.tsx blob is byte-identical to the previously browser-verified content (sha256 bcfebc20), so the receipt is content-addressed to the same source; the added contract assertion and performance-and-scalability ordering note are unchanged.
Refs: https://github.com/rcourtman/Pulse/issues/2121
Change-source: pulse-maintainer
Integrate the reviewed ai-runtime prompt-cache repair (248ada3cc6) with its transport contract (f08b96b968) and registered completion pair (bc3da3ad49). Merge resolved the canonical completion registry against the rehearsal-timeout completion pair already on main by keeping both entries.
Change-source: pulse-maintainer
Register 248ada3cc6 as completed by f08b96b968, which records the
Anthropic stable-system-prefix prompt-cache transport contract, so the reviewed
runtime repair is evaluated with its contract as one completion unit.
Change-source: pulse-maintainer
Add the ai-runtime contract section for the Anthropic stable-system-prefix
prompt-cache reuse and its focused proof. This completes the contract obligation
for the runtime repair in 248ada3cc6 without rewriting that reviewed commit.
Change-source: pulse-maintainer
Dependabot #2099 bumps @types/node 20.19.43 to 26.5.1 in frontend-modern, but the PR is blocked twice: Frontend tsc fails with TS2550 on .at() (26 removed the compatibility polyfill), and Canonical Governance blocks the package.json/lock change for a missing deployment-installability contract update and frontend dependency security proof.
Carry the bump with its required governance artifacts in one commit. tsconfig already declares the ES2022 lib (95db35b6c3), which the source's .at() usage needs; this adds the manifest and lock bump (matching tests/integration, which already pins @types/node ^26.5.1), a Completion Obligations entry, and a dependencySecurity proof that keeps the manifest range, the locked @types/node/undici-types versions and the declared lib in step. Verified offline: the guard passes and the proof test passes.
Change-source: pulse-maintainer
The completion-history validator materialises its completion tree with a shared clone. The proof sandbox strips the maintainer read config and a linked worktree's gitdir sits outside the checkout, so the clone failed with dubious ownership and the preflight reported a history failure instead of validating the registered pair. Give every git subprocess a private config carrying the fixed safe.directory policy, and register the rehearsal backend package-timeout runtime commit together with its deployment-installability contract follow-up as one completion unit. Change-source: pulse-maintainer
Change-source: pulse-maintainer
Record the deployment-installability contract section for the rehearsal backend package timeout and its proof surface. This is the contract follow-up for the runtime change in d0f138cf26. Change-source: pulse-maintainer
Change-source: pulse-maintainer
The accelerated rehearsal profile runs the backend as one serial 'go test -json -p 1 ./...', whose Go default per-package timeout is 10m. internal/api exceeded that under ordinary shared-worker load (606.9s at loadavg 5.55 on 2026-09-19) and the run failed with 'panic: test timed out after 10m0s' despite zero test assertions failing. The release profile already budgets 30m per package via run-release-backend-tests.sh. Add PULSE_RELEASE_PREFLIGHT_REHEARSAL_TIMEOUT (default 30m) and pass it as -timeout, and update the worker contract test that pins the exact rehearsal command. Change-source: pulse-maintainer
Change-source: pulse-maintainer
Anthropic only received a cache breakpoint on the last tool, so the large
frozen system prompt was never cached and multi-turn Patrol investigations
repaid its full input cost every turn (#2118). Serialize the stable base plus
mode text as a system content block with its own ephemeral breakpoint, leaving
the per-turn clock and accumulated knowledge outside the cached prefix.
The system breakpoint covers the tool definitions too, so the redundant tool
breakpoint is dropped when it is present. Providers without prompt caching
ignore the new request field and send the system prompt unchanged. Cache
creation/read counters are logged at Info so effectiveness is visible in
production.
Change-source: pulse-maintainer
The frontend source uses Array.prototype.at()/String.prototype.at() in 83 places, but tsconfig declared only the ES2020 lib. Type-checking passed only because @types/node 20 shipped an .at() compatibility polyfill; @types/node 26 removes it, which is why Dependabot #2099 failed Frontend tsc with TS2550. Declare ES2022 so the compiler knows the runtime methods the code already relies on. Build target stays ES2020.
Change-source: pulse-maintainer
Address the remaining verified findings from the pkg/metrics/store.go review
(#2079 finding 5 and the lower-impact nits):
- writeBatch now retries the whole transaction on a retryable lock error.
BEGIN is deferred, so contention is hit at the first INSERT or COMMIT; the
old loop retried only Begin() and skipped rows. While the one-time startup
maintenance (deferred identity-index rebuild and auto-vacuum VACUUM) is
active, an extended retry budget keeps upgrade-time history instead of
dropping it after the steady-state budget.
- migrateLegacyHostResourceType probes with an indexed EXISTS before opening a
write transaction, so an already-migrated store does not dirty the WAL on
every boot.
- QueryAll caps the per-series MetricPoint preallocation so a fine requested
step over a long range cannot reserve hundreds of thousands of slots.
Regressions: TestStoreStartupMaintenanceSignalsWriteRetryBudget,
TestStoreWriteBatchExtendsRetryDuringStartupMaintenance,
TestEstimateQueryAllBatchSeriesCapacityCapsPreallocation. The
performance-and-scalability contract records the invariants.
Change-source: pulse-maintainer
Distinguish independent customer-owned Community, Relay and Pro installations
from provider-owned MSP entitlements so outside IT support alone does not
trigger an MSP requirement. Preserve per-customer subscriptions and the
prohibition on pooling licences across unrelated customers.
Harden pkg/metrics/store.go rollup checkpoints, SQLite busy/locked retry classification, rollup min/max spread preservation, and one-connection auto-vacuum migration (#2079 findings 2-4, 6). Includes the performance-and-scalability contract sections, the regression proof moved into the registry-accepted store_additional_test.go, and the reviewed completion-pair registration for the split proof commit.
Change-source: pulse-maintainer
The canonical per-commit guard requires pkg/metrics/store.go changes to carry
an accepted proof file in the same commit. The proof for the rollup, retry,
upsert and auto-vacuum repair landed in the follow-up 087bbf8c20
(pkg/metrics/store_additional_test.go). Register the runtime commit e1d97b361e
and its completion commit as one reviewed completion unit so the candidate
preflight validates the pair instead of rewriting history.
Change-source: pulse-maintainer
The canonical completion guard requires the metrics-store hot-path proof in
pkg/metrics/store_additional_test.go. Move the rollup-gap, upsert-spread,
busy-retry and auto-vacuum regressions there and point the
performance-and-scalability contract at that file. The runtime change and
contract section are in the preceding fix(metrics) commit.
Change-source: pulse-maintainer