The lifecycle buttons already read resource.actionReadiness and render
disabled with the refusal reason before any click. The update button did
not, so a user with a stale or disconnected agent could click Update,
confirm, and only then get the refusal from POST /api/actions/plan
(GitHub #1564). Wire the update button to the same per-resource
readiness data: extract the readiness-refusal resolver shared with the
lifecycle buttons into utils/actionReadiness.ts, thread actionReadiness
through UpdateButtonProps at both render sites (Docker containers table
and the workloads GuestRow via useWorkloads), and render the button
disabled with the refusal reason as its tooltip. The post-click
details.reason path from b3058d47e stays as the backstop for
websocket-hydrated rows, which carry no readiness data until the REST
revalidation lands.
A refused update plan showed only 'Action execution is unavailable'; the
actionable explanation (agent disconnected, agent too old, stale inventory)
arrives in the API error's details.reason and was dropped. Prefer it in the
failure badge and tooltip. Seen in #1564 where the toast gave the reporter
nothing to act on and Actions showed no record (refusal is pre-audit).
'This agent does not support durable typed-operation receipts' told users
nothing they could act on. Say the agent is on an older version and how to
resolve it. Applies to docker container, host update and host storage
cleanup executors.
The DisableAllDockerContainers and DisableAllDockerServices config sweeps
matched only legacy docker-container-/docker-service- alert ID prefixes.
Canonical stateful alerts (image-update, state, health, replica-gap) are
stored under <resourceID>::<specID> state IDs, so existing alerts survived
the toggle and lingered indefinitely, re-notifying past cooldown.
Match on the docker: resource ID scheme as well as the legacy prefixes.
The active-turn status helpers had 27 uncovered branches its existing suites did
not reach. This covers the tool-label fallback, the retryAfter and startedAt
absent-field fall-throughs, and the skip arms for undefined stream and pending-tool
entries, taking covered branches from 276 to 316.
New test-only file with a distinct branchcov0717 suffix. No source changed.
Verified with vitest and type-check, measured to raise branch coverage over the
pre-existing suite.
aiFindingPresentation had grown a set of badge, tone, label and Patrol
classification helpers its existing suites never called, so this covers 25
previously-uncovered functions plus their fallback and count-edge arms.
workloadsSummaryCache goes from 28 to 76 covered branches across cache
hit/miss/expiry paths, infrastructureSummaryCache picks up its remaining getter
and branch arms, and resourceBadgePresentation covers a further block of edge
branches its two branchcov suites left open.
Four new test-only files with distinct branchcov0717 suffixes alongside the
existing suites. No source changed. Verified with vitest and type-check, each
measured to raise branch or function coverage over the pre-existing suite.
These presentation helpers had partial coverage and had grown functions their
existing tests never reached. alertWebhookPresentation goes from 14 to 23 covered
functions, organizationSettingsPresentation from 34 to 42, alertIncidentPresentation
from 37 to 39 with its remaining branches, and ssoProviderPresentation closes its
last four uncovered branches. The new cases exercise the fallback, boundary,
per-role and error-precedence arms the primary tests omit.
Four new test-only files with distinct branchcov0717 suffixes alongside the
existing suites. No source changed. Verified with vitest and type-check, and each
measured to raise branch or function coverage over the pre-existing suite.
The docker container lifecycle codec in agentexec had a contract test that never
exercised the codec functions at runtime, leaving decode, bind, validate and
identity helpers at zero coverage. This adds a table-driven test taking each to
near or full coverage including every validation error arm. In aicontracts,
CloneActionReference, IsNilAlertPayload and DefaultEngineConfig were uncovered,
so this covers the nil and populated arms and asserts CloneActionReference
produces an independent deep copy.
Both are new test-only files. No source changed. Verified with go test, gofmt
and go vet, with each target function confirmed to move off zero coverage.
containerUpdateBadgeModel gained update icon and button helpers since its prior
branchcov test, so this covers the three previously-uncovered functions and
their state arms (idle, confirming, updating, success, error and the default).
aiProviderPresentation route-label formatting had fourteen uncovered branches,
now exercised through the four exported entry points. dockerIdentityConflict
conflict collection reaches full branch coverage including the hostnames
fallback and the name fallback chain.
All three are new test-only files under existing __tests__ directories. No source
changed. Each was confirmed with vitest and type-check, and measured to raise
branch or function coverage over the pre-existing suite.
Two more newly added *_w0716_coverage_test.go files from the same
branch-coverage wave, touching no source and no existing test.
- internal/models deep-copy clone independence for Docker, Kubernetes,
ZFS and PBS clones, each mutating the original and asserting the clone
stays unchanged
- internal/ai/qualification lab shell-quoting and resource-name
rendering plus report replay predicates and markdown renderers
Cover previously-unexecuted branches in modules that gained behavior
since the last wave. All six are newly added *_w0716_coverage_test.go
files that modify no source and no existing test.
- internal/ai/chat investigation-budget injection plus the agentic
tool-event and string helpers
- internal/ai/qualification manifest Validate error arms and the Patrol
docker-predicate and finding-prerequisite validators
- internal/unifiedresources adapters transforms and ContractResourceType
- internal/config AIConfig nil-receiver default branches
- pkg/aicontracts orchestrator error methods and investigation config
Cloned VMs that keep the same /etc/machine-id collapse into a single
Docker host in Pulse, with each clone's report silently overwriting the
other (#1584). The server now tracks per-identity hostname and machine
ID observations and flags a conflict when a value flaps back to one
already seen inside a 15-minute window, a signature a one-time rename
never produces. The conflict rides the DockerHost model through unified
resources, and the Docker page shows a warning naming the flapping
hostnames with the machine-id remedy. The warning self-clears once one
clone stops reporting for the window.
A vSphere 6.x target fails the connect test at the Automation session
step with a generic "HTTP 500" message, because /api on those releases
routes to the JSON-RPC servlet. When /api/session fails with a non-auth
status, probe the legacy /rest CIS session API with the same
credentials; if that login works the target predates the JSON APIs
Pulse uses, so the test now reports the unsupported-version warning
naming the vCenter 8.0U1 floor instead of pointing at credentials. The
probe deletes the session it creates. Also reword the frontend guidance
for that category in plain terms.
Related to #1585.
Update checks against registries without a hardcoded token endpoint
(lscr.io and other spec-compliant registries) failed with a blanket
"Check failed" because the manifest HEAD went out anonymously and the
401 was terminal. Parse the Bearer challenge on the 401, fetch a pull
token from the advertised realm, and retry once. Token endpoints that
answer with access_token instead of token are now accepted too.
Fixes#1583.
Adds branch-coverage unit tests for previously uncovered pure functions in
internal/monitoring and internal/ai/tools. New test files only, with no source
changes.
Covers existing-cluster IP-override and fingerprint lookup, storage-summary
capacity-trend building, nouveau GPU temperature parsing, resolved-resource
control identity, and available-agent-host formatting. 32 TestBranchCov
functions in 2 files, all vet and gofmt clean.
Adds table-driven branch-coverage unit tests for previously uncovered pure
functions across internal/alerts/config, internal/ai/modelresolution,
internal/monitoring, internal/ai, internal/ai/qualification and pkg/licensing.
New test files only, with no source changes.
Covers per-subsystem alert-default normalization, configured model and provider
resolution, fleet-doctor identity and cluster-endpoint helpers, docker-state and
infrastructure-key mapping, investigation and SMART issue helpers, JSON and
autonomy normalization, and licensing feature-tier resolution. 65 TestBranchCov
functions in 7 files, all vet and gofmt clean.
Adds table-driven branch-coverage unit tests for previously uncovered pure
functions across internal/models, internal/config, pkg/securityutil and
pkg/aicontracts. New test files only, with no source changes.
Covers model collection normalizers, reflect-based metric deep-copy,
removed-host agent bookkeeping, report-schedule and entitlement-billing
normalization, effective AI control and Patrol autonomy resolution,
websocket-origin host normalization, and command-safety classifiers. 61
TestBranchCov functions in 8 files, all vet and gofmt clean.