Commit Graph

4696 Commits

Author SHA1 Message Date
pulse-triage[bot] 1c8fee0119 fix(alerts): bound alert event log snapshot volume
A permanently-offline derived identity flapped a docker-host alert and wrote 4,748 resolved/refired pairs in three days; each lifecycle event stores a full alert-state snapshot averaging ~170 KB, so events.db reached 1.2 GB and filled the host root filesystem (#2113 downstream evidence). The 90-day age retention is not a volume bound: one alert can still write unbounded payload inside the window.

The hourly prune now also enforces a total stored snapshot-payload cap and removes the oldest events first when it is exceeded, raising the same retention revision age pruning uses so the history projection rebuilds from the remaining log. Normal installs stay far below the cap and are unaffected; the bound only triggers on pathological amplification. Focused proof in eventlog_snapshot_test.go; the alerts subsystem contract records the bound.

Change-source: pulse-maintainer
2026-09-20 22:06:17 +01:00
pulse-triage[bot] 0e7ec69c51 fix(monitoring): batch unified metric sync writes into one transaction
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
2026-09-20 16:31:51 +01:00
pulse-triage[bot] 33260be25b docs(monitoring): record physical-disk SMART replay-guard contract
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
2026-09-20 16:04:16 +01:00
pulse-triage[bot] abaca8f9c0 fix(monitoring): anchor and guard unified physical-disk SMART writes
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
2026-09-20 16:02:52 +01:00
pulse-triage[bot] 9ad20f432a test(monitoring): use recent observation times in sync proofs
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
2026-09-20 15:50:30 +01:00
pulse-triage[bot] 23c84ed813 fix(monitoring): anchor unified sync samples to source observation time
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
2026-09-20 15:48:01 +01:00
pulse-triage[bot] 92d6eae77f fix(hostagent): recover Windows host info when MachineGuid is braced
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
2026-09-20 08:29:15 +01:00
pulse-triage[bot] 601c383c50 docs(monitoring): record TrueNAS legacy-REST memory contract
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
2026-09-20 08:10:13 +01:00
pulse-triage[bot] a4c53b511d fix(truenas): read CORE memory from legacy REST reporting
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
2026-09-20 07:24:35 +01:00
pulse-triage[bot] c978cc452c test(vmware): define local JSON response helper for request-shape test
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
2026-09-20 01:49:43 +01:00
pulse-triage[bot] 5da761f968 fix(vmware): send VI JSON _typeName on data-object arguments
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
2026-09-20 01:47:42 +01:00
pulse-triage[bot] 1b7bb40b0e fix(vmware): tolerate absent JSON values and surface API fault detail
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
2026-09-20 00:04:07 +01:00
pulse-triage[bot] 9a1cfa4c40 fix(truenas): reject synthesised CPU temperature aggregate
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
2026-09-19 22:42:13 +01:00
pulse-triage[bot] 248ada3cc6 fix(ai): cache the stable system prompt prefix
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
2026-09-19 21:06:33 +01:00
pulse-triage[bot] 2eedd91d53 Merge reviewed candidate 20260919T162027Z-delivery-trust (pulse 59d3da9768)
Restore the documented local-contention skip for load/SLO latency budgets on the shared release preflight worker: only a real GitHub-hosted run (GITHUB_ACTIONS=true and GITHUB_RUN_ID set) enforces the budgets. Hosted CI enforcement is unchanged; the worker keeps its cross-repo skip. Includes a focused predicate test.

Change-source: pulse-maintainer
2026-09-19 17:49:39 +01:00
pulse-triage[bot] 8bc6aa3c86 chore(monitoring): record agent-lifecycle contract and disk-life proof
Follow-up to the physical-disk endurance precedence fix. Records the
dependent agent-lifecycle contract section and moves the regression into the
accepted physical-disk proof file so later per-commit canonical guards find
both the contract and the verification artifact.

Change-source: pulse-maintainer
2026-09-19 17:27:25 +01:00
pulse-triage[bot] 0910542f0a fix(monitoring): stop host-agent endurance raising disk life
The physical-disk SMART merge let a linked host agent raise a disk's
remaining life above the Proxmox inventory value. An intermittent NVMe
PercentageUsed 0 reading therefore resolved a genuine low-life disk-wearout
alert, which re-fired on the next physical-disk poll and emitted a fresh
resolved notification every poll interval (#2112).

The merge now takes the agent value only when the Proxmox value is unreported
or more pessimistic, never raising a reported remaining-life value, while
still recording the agent SMART attributes. This does not change agent
admission, token binding or removal-block behaviour.

Regression: TestMergeHostAgentSMARTIntoDisks_AgentWearoutDoesNotHideLowPVELife
and TestMergeHostAgentSMARTIntoDisks_AgentWearoutFillsUnreportedPVELife in
internal/monitoring/monitor_integration_test.go. The monitoring contract is
updated in this commit.

Change-source: pulse-maintainer
Contract-Neutral: Behavioral bug fix in the physical-disk SMART merge; no public API or external contract delta. The monitoring contract is updated in this commit and the dependent agent-lifecycle contract and accepted proof file follow in the next commit.
2026-09-19 17:27:01 +01:00
pulse-triage[bot] 59d3da9768 test(slo): only enforce latency budgets on hosted runners
The shared release preflight worker exports GITHUB_ACTIONS=true so isolated single-repository checkouts take their private-sibling skip. That flag also made the load/SLO latency guards hard-fail on a contended shared host, where the tests' own documented local-contention skip is the intended behaviour. Distinguish a real GitHub Actions run by GITHUB_RUN_ID, which only a hosted runner sets, so the worker keeps the cross-repo skip while latency overruns skip instead of failing. Hosted CI enforcement is unchanged.

Change-source: pulse-maintainer
2026-09-19 17:26:25 +01:00
pulse-triage[bot] ee7ecbd928 test(docker): cover multi-RepoDigest update comparison
Restore the remaining focused regressions for the all-local-RepoDigests update comparison carried on the earlier core-runtime candidate: multi-digest resolution in getImageRepoDigests, false-update suppression in CheckImageUpdate, and the DigestsDiffer multi-digest cases. Test-only additions; the runtime change and contract sections are in the preceding fix(docker) commit.

Change-source: pulse-maintainer
2026-09-19 15:23:52 +01:00
pulse-triage[bot] 54f0619e57 fix(monitoring): honour removal block on forked re-enroll
A removed host agent could re-enroll under a derived base-hex identity because identity resolution forked the machine before the removal block was consulted. The block is keyed on the base machine identity, so the forked ID bypassed it and the machine was silently re-admitted (#2113). ApplyHostReport now consults the base-identity removal block when the presenting token had no prior binding, so a fresh install token clears the block and heals to the base identity while an established distinct forked host (#1753) is left alone.

Record the behaviour in the monitoring and agent-lifecycle contracts and add the focused regression to the accepted monitor.go proof file. Change-source: pulse-maintainer

Change-source: pulse-maintainer
2026-09-19 15:16:18 +01:00
pulse-triage[bot] 40fff0636d fix(docker): treat all local RepoDigests as the current image
Docker update check compared a single RepoDigest against the registry tag digest, so a current image that carries two RepoDigests (postgres:16.15-alpine3.24) reported update-available. Compare the whole local RepoDigest set in CheckImageUpdate and in the typed update preflight; the primary digest is still reported for display.

Record the behaviour in the monitoring and agent-lifecycle contracts and add focused regression tests in the accepted docker proof files. Proof: go test ./internal/dockeragent/ passes including TestRegistryChecker_MultipleLocalRepoDigestsSuppressFalseUpdate and TestAgent_getImageRepoDigests_MultipleDigestsForOneImage.

Change-source: pulse-maintainer
2026-09-19 15:16:03 +01:00
pulse-triage[bot] df44238797 fix(monitoring): drop replayed unified metric samples
Read-side registry rebuilds re-run the unified metric sync as often as every two seconds, so one poll observation was re-written many times between polls. The metrics store upserts on (resource, metric, tier, timestamp), so each replay UPDATEs the same row and commits a fresh transaction for no new data, churning the SQLite WAL and driving the disk-write amplification reported in #1966.

Track the last sample handed to the store per series and skip exact timestamp+value repeats before the batch is enqueued. A corrected value at the same observation time is still written, so the guard cannot mask a real change. Record the behaviour in the monitoring and agent-lifecycle contracts and move the focused regression into the accepted monitor.go proof file.

Change-source: pulse-maintainer
2026-09-19 15:15:31 +01:00
rcourtman 39c46011cc test(api): isolate CSRF middleware fixtures
Initialize the persistent CSRF store for middleware tests that construct session-cookie requests, and restore the package test store afterward. This keeps exact release preflight runs from panicking before they can report qualification results.
2026-09-17 12:35:20 +01:00
rcourtman 019852f1f3 chore(portal): patch Vitest security dependency
Update the Pulse Account portal Vitest dependency to 4.1.11, clearing Dependabot security alerts 154 and 155 for Vitest and @vitest/mocker.

Contract-Neutral: Dev-only Vitest security dependency update; no product contract or runtime behavior changed.
2026-09-17 00:32:56 +01:00
rcourtman 8fad031d95 Keep agent credentials consistent across monitor reloads
Reloading configuration replaced the monitor's config pointer while API and
authentication handlers retained the original object. Tokens created afterwards
could authenticate successfully while Agent Doctor reported an unlisted token.

Refresh the canonical runtime configuration in place before constructing the
replacement manager. Cover repeated reloads, live token creation and revocation.
2026-09-15 09:37:01 +01:00
pulse-triage[bot] 5f33ea3a3c Register the dedicated security setup contract regression
The per-commit API guard needs the actual dedicated preservation test declared in its verification registry. Restore that tested artifact and add its exact path to the existing backend API proof list. Retain all existing requirements and reviewed commit identities; no history rewrite, contract-neutral override, or unrelated proof substitution is used.

Change-source: pulse-maintainer
2026-09-15 02:22:04 +01:00
pulse-triage[bot] d7e9e61bc5 Bind setup preference regression to API contract verification
Place the authenticated settings-preservation regression in the established API contract proof surface so the owning contract guard consumes its actual assertions, without waiving verification or changing runtime behavior.

Change-source: pulse-maintainer
2026-09-15 02:13:42 +01:00
pulse-triage[bot] f0f7e51d15 Preserve system preferences when rotating local authentication
Quick security setup previously replaced system.json with defaults even for authenticated force reconfiguration. Initialize only absent settings under the persistence save mutex, preserving existing bytes and read failures. Cover credential rotation, custom and malformed settings, missing settings, and read errors without changing authorization or token scopes.

Change-source: pulse-maintainer
2026-09-15 02:11:52 +01:00
pulse-triage[bot] 646bba571b fix(truenas): accept non-object REST alert arguments
Preserve snapshot refresh and formatted alerts when legacy args are scalar, array or null. Restrict SMART metadata to typed object fields and cover repeated snapshot collection plus error boundaries for #2077.

Change-source: pulse-maintainer
2026-09-13 18:42:50 +01:00
pulse-triage[bot] 01742e2279 fix(monitoring): preserve physical disk source identity on refresh
Skipped disk polls must write the Proxmox source key back into inventory rather than hashing the canonical resource ID again. Add repeated-cycle runtime and JSON projection coverage for serial-less disks, distinct node/controller scopes and removal.

Change-source: pulse-maintainer
2026-09-13 18:25:42 +01:00
pulse-triage[bot] 244af2bafe test(vmware): align API probe expectations
Include the canonical 8.0.3.0 release in the API handler fixtures and expected negotiation sequence. This repairs the exact hosted API-suite failure on the reviewed VMware candidate without changing runtime behavior.

Change-source: pulse-maintainer
2026-09-13 10:59:02 +01:00
pulse-triage[bot] 6f301ee8fb fix(vmware): probe canonical vSphere 8.0.3 JSON release
Probe 8.0.3.0 before the legacy spelling and older API schemas. Issue #2070 demonstrates method routing on the canonical version while Pulse reports 8.0.2.0. Retain legacy fallback and hard authentication/permission failures.

Add canonical negotiation, legacy/older fallback and auth/permission regression controls; update the runtime contract. Five reduced-function race probes fail before and pass after. Full package validation is unavailable with the installed offline dependency cache. This repairs negotiation, not the unresolved metrics/events/folder enrichment report.

Change-source: pulse-maintainer
2026-09-13 09:25:10 +01:00
pulse-triage[bot] 052286db23 fix(docker): reject non-manifest registry fallback responses
Headerless HTTP 200 error pages were hashed into unrelated latest image digests and cached as updates. Require a schema-2 manifest envelope before trusting fallback body metadata, preserving valid indexes, platform comparison and existing error backoff. Retain before/after collector, ingest and resource endpoint qualification; this reproduces a mechanism, not the exact reporter cause in #2048.

Change-source: pulse-maintainer
2026-09-11 10:28:15 +01:00
pulse-triage[bot] 3e920df03d fix(alerts): skip unchanged pending-intent checkpoints
Complete the JSON-only checkpoint fast path: compare sorted, bounded actual pending-state bytes before replacement. Preserve changes, clearing, failed-write retry and unsafe-destination repair. Focused before regression fails; repeated race proof passes. Sixty unchanged synthetic checkpoints fall from 245760 process write bytes to zero; changing alert freshness remains a separate contributor, not aggregate issue #1966 acceptance.

Change-source: pulse-maintainer
2026-09-11 07:05:34 +01:00
rcourtman 63617c97cb Merge pull request #2034 from rcourtman/fix/1913-source-build-updates
Keep diagnostic source builds out of release update flows
2026-09-10 22:17:32 +01:00
rcourtman 3c723569e3 Merge main into source-build update safeguards
Reconcile parallel release-version test fixtures while preserving the
current provider settings changes. Refresh browser verification against
the combined source before landing the diagnostic update safeguards.

Refs #1913
2026-09-10 21:31:38 +01:00
rcourtman a3eab37bcd Pin release identities in update-check tests
Release-update tests must exercise published builds even when the checkout is shallow and has no version tags. Use the existing build-version fixture instead of inferring release eligibility from the test runner checkout. Pin the source-marker case to a release version as well so it proves the marker disables updates.

Refs #1913
2026-09-10 21:10:41 +01:00
pulse-triage[bot] 03dabbcdab fix(monitoring): synchronise snapshots with mock state reset
Mock-mode reset replaces the state pointer while API and mock-alert readers can still be active. Capture the initialized pointer under the monitor lock and preserve its fallback alerts rather than reading the replaceable pointer again.

Reproduce the race without Start workers, verify reset snapshot isolation, and retain live alert-manager precedence. This repairs the beta.3 preparation failure without masking its test cleanup schedule or changing monitoring schemas.

Contract-Neutral: Synchronization-only snapshot repair; resource identity, API fields, alert policy and canonical ownership are unchanged.
Change-source: pulse-maintainer
2026-09-10 21:04:56 +01:00
pulse-triage[bot] b5a9b7aac2 Merge commit 'e8449477ff1098be8975cccee42952e45c73aa74'
Change-source: pulse-maintainer
2026-09-10 18:41:40 +01:00
pulse-triage[bot] 536be38ac4 Merge origin/main before planner fixture publication
Change-source: pulse-maintainer
2026-09-10 18:31:05 +01:00
pulse-triage[bot] e8449477ff fix(settings): restore Ollama Basic Auth configuration
The backend supports authenticated Ollama servers but the provider editor omitted its credential fields. Expose write-only password editing with explicit clearing and preserve unchanged credentials. Verify Settings persistence, authenticated connection tests and the Patrol streaming factory using synthetic endpoints.

Change-source: pulse-maintainer
2026-09-10 18:21:29 +01:00
pulse-triage[bot] c0967d02db test(ai): wire typed planners in control projection fixtures
Repair stale transport-only availability fixtures without weakening runtime planner or policy checks. Exercise planner removal with execute authority, transport-only provider projections, and read-only policy with an installed planner.

Change-source: pulse-maintainer
2026-09-10 18:17:48 +01:00
pulse-triage[bot] 7294e60afd Merge candidate 20260910T164511Z-web-product
Change-source: pulse-maintainer
2026-09-10 17:58:07 +01:00
pulse-triage[bot] 82545520ad test(api): prove journey rate-budget isolation preserves enforcement
Exercise shared-IP org and runtime-capability requests through universal middleware, including production and development saturation and independent login enforcement.

Contract-Neutral: Regression coverage for existing development-only E2E budget isolation; no production behaviour or limit changes.
Change-source: pulse-maintainer
2026-09-10 17:51:49 +01:00
pulse-triage[bot] f0eb444330 test(updates): pin release fixtures independently of source identity
PR #2034 source-build exclusion exposes five tests that implicitly assume a published checkout. Give ordinary-release fixtures an explicit restored version so CI source identity cannot suppress their release discovery. Keep this correction separate from the pending diagnostic implementation and its frontend verification.

Change-source: pulse-maintainer
2026-09-10 17:38:30 +01:00
rcourtman 52d0aeb0cb diagnostic: run hosted lifecycle fixture on DeepSeek V4.1 Flash
Replaces google/gemini-2.5-flash with deepseek/deepseek-v4.1-flash (released 2026-09-10) as the diagnosticModel for the hosted lifecycle diagnostic and its synthetic fixture/wire tests.
2026-09-10 17:35:59 +01:00
rcourtman 7f15acfbad Keep diagnostic source builds out of release update flows
Diagnostic versions must keep their exact identity without advertising a published server or agent update target. Reuse the canonical source-build classification and discard cached release offers when runtime identity changes.

Show source-build status and manual image replacement guidance. Verify release and preview controls remain available.

Refs #1913
2026-09-10 17:06:27 +01:00
pulse-triage[bot] fd2327d3cf fix(ai): advertise lifecycle control from planner availability
The hosted synthetic lifecycle diagnostic offered no control tool despite an installed canonical planner: availability still depended on retired execution transports. Match exposure to the plan-only boundary while preserving read-state and control-level policy. Assert provider and gateway tool offers so scripted calls cannot hide this mismatch, and retain literal-search behaviour as separate evidence.

Change-source: pulse-maintainer
2026-09-10 17:04:01 +01:00
rcourtman dd388decf5 Merge pull request #2031 from rcourtman/fix/1913-agent-continuity
Preserve live agent state over saved enrollment history
2026-09-10 16:41:10 +01:00
rcourtman 751b8dd8c1 Merge pull request #2030 from rcourtman/fix/manual-update-freshness
Fix manual update freshness and unknown release dates
2026-09-10 16:14:11 +01:00