Commit Graph

7912 Commits

Author SHA1 Message Date
rcourtman c3f7b4d5c9 Keep action completion contract aligned with remediation locks 2026-07-10 01:22:05 +01:00
rcourtman 33d318a29e Delete the unreachable adapter Execute/Rollback update path and the unused UpdateQueue
The only production consumer of the UpdaterRegistry is the plan endpoint
(GET /api/updates/plan); every real apply runs through the in-Go pipeline
in manager.go ApplyUpdate, with concurrency held by updateMu/updateInFlight.
The InstallShAdapter Execute/Rollback path (install.sh piping, rollback
binary download, health wait) and the UpdateQueue were never called outside
tests, so fixes made there silently did nothing. Adapters are now plan
providers only: the Updater interface keeps SupportsApply, PrepareUpdate,
and GetDeploymentType, pinned by the new registry proof in
internal/api/updates_test.go.

The orphaned fetchAndVerifyReleaseSignature helper goes with it; its
fail-closed sidecar tests now exercise the manager's
downloadAndVerifyReleaseSignature directly. The deployment-installability
sshsig invariant now names the manager pipeline as the only surface that
fetches release artifacts, and api-contracts, storage-recovery, and
agent-lifecycle pin the same plan-provider-only shape at their update
transport boundaries. Stale adapter references in build-release.sh,
validate-release.sh, and the installtests comments are updated to match.
2026-07-10 01:14:40 +01:00
rcourtman 26a4a062f6 Unify the update apply flow behind one store action with a post-update toast
Both the update banner and the Settings update panel duplicated the
confirm/apply POST with divergent error handling; the banner's failure
path was a native alert(). updateStore.applyUpdate() now owns the POST,
the shared error toast, and a persisted pending-apply marker recording
the pre-update version. On the next version fetch after the post-update
reload, the store confirms the running version moved and shows a
one-time 'Updated to vX.Y.Z' toast, clearing the marker either way.
2026-07-10 01:12:54 +01:00
rcourtman 0c91799e0f Self-test the new binary before the in-app update swaps it in
Checksum and SSHSIG verification prove the downloaded artifact matches
what was published, not that it can run on this host or is the version
the user approved. The apply pipeline previously swapped the binary and
exited, relying on systemd to restart into an unproven executable; a
wrong-arch fallback asset or unstamped build would take Pulse down with
the backup left unused.

ApplyUpdate now locates the extracted binary and probes it with
--version before the backup and swap stages, failing the update with
zero changes applied when the probe fails or reports a version other
than the apply target. Same pattern the agent updater already uses.
Pinned in the deployment-installability contract with
internal/updates/selftest_test.go as the owned proof surface.
2026-07-10 00:44:01 +01:00
rcourtman 4c37a8c332 reporting: fit and wrap operator-controlled cover title and brand lines
Long custom titles on generate-multi covers overflowed the page edges;
the cover now shrinks to fit, wraps at the minimum size, and flows the
subtitle and scope blocks below a wrapped title. Also drop the stale
frontend-primitives contract and registry references to the
Settings/reportingResourceTypes.ts re-export removed in c862fb0ca; that
frontend-only commit skipped the governance audit, leaving the stale
references blocking every Go commit.
2026-07-10 00:42:06 +01:00
rcourtman f6d9468a84 Lead README with the watching-not-showing story and demote platform-page navigation 2026-07-10 00:38:42 +01:00
rcourtman c862fb0ca0 Remove dead frontend type module and re-export barrel
Dead-code audit batch 5: types/responsive.ts (all 8 exports had zero
non-definition references) and the one-line
components/Settings/reportingResourceTypes.ts barrel (all consumers
import @/utils/reportingResourceTypes directly). Both were referenced
only via ?raw text imports in guardrail tests; those imports and their
assertions are dropped here in the same commit. The TYPE_COLUMN_*
contract remains pinned against the live sources
(utils/typeColumnContract.ts, utils/typeColumnDefinition.ts).
2026-07-10 00:36:30 +01:00
rcourtman 51155a42c9 Remove uncalled test helpers
Dead-code audit batch 3: hasPrefix in internal/ai/service_test.go and
the staticExternalAgentActivityProvider test double in
internal/api/agent_resource_context_test.go have no callers in any
test or production code.

Skipped from the audit list after re-verification:
createTestEncryptionKey in cmd/pulse/test_helpers_test.go (called nine
times by commands_integration_test.go under the integration build tag).
2026-07-10 00:29:10 +01:00
rcourtman f7aa9ee922 Remove unreachable exported functions from pkg/
Dead-code audit batch 1: five functions with zero references from main,
tests, or pulse-enterprise (deadcode -test, grep-verified per symbol,
enterprise compile-checked). Also renames the tlsutil test that
exercised the deleted compat alias's target to name the Unverified
function it actually calls.

Skipped from the audit list after re-verification: IsNilAlertPayload
(live pulse-enterprise consumer in internal/aialertanalysis).
2026-07-10 00:27:35 +01:00
rcourtman 3f4bc295d2 Record general release workflow proof 2026-07-10 00:23:28 +01:00
rcourtman e5faca5035 Fix Docker update copy to recreate the container instead of docker restart
docker restart reuses the image the container was created with, so the
pulled update never takes effect. Point users at docker compose pull &&
docker compose up -d, with pull/stop/rm and re-run for non-compose
installs, matching docs/DOCKER.md.
2026-07-10 00:22:39 +01:00
rcourtman 4ac518a020 Replace reverted unified-nav copy in README with the shipped platform-first navigation 2026-07-10 00:19:48 +01:00
rcourtman ef895abbd5 portal: replace raw white_label token in onboarding template copy 2026-07-10 00:16:40 +01:00
rcourtman f4c2fd0c38 Fail closed on unknown remediation lock state for autonomous dispatches
The AI action broker treated an unreadable operator lock as unlocked:
isResourceRemediationLocked returned (false, nil) with no audit store
wired, and the caller logged store errors then dispatched anyway. An
operator's NeverAutoRemediate=true could be silently ignored whenever
the policy store was missing or erroring, which is unacceptable while
Patrol and Assistant run at assisted or full autonomy.

Posture change at the dispatch decision point:
- isResourceRemediationLocked now reports unknown state (nil store or
  lookup failure) as an ErrRemediationLockStateUnknown-wrapped error
  instead of silently defaulting to unlocked.
- New checkRemediationLockForDispatch gate: dispatches without an
  approved human decision fail CLOSED on unknown lock state and
  surface "remediation lock state unknown; operator approval
  required". Human-approved dispatches keep the historical fail-open
  behavior with a warning log. A confirmed lock still refuses even
  approved dispatches, as before.
- executeNativeActionWithAudit (TrueNAS app start/stop/restart) now
  enforces the lock too; it previously skipped the check entirely.
- Refusals persist Failed audit records with stable
  remediation_lock_state_unknown: / resource_remediation_locked:
  ErrorMessage prefixes.
- ai-runtime subsystem contract updated to pin the new posture.

Tests cover store-error and nil-store at both autonomy postures on
both dispatch paths; routing/control tests now wire an in-memory
audit store since autonomous dispatch without one is refused.
2026-07-10 00:14:01 +01:00
rcourtman dc6b5c3197 Verify AI Kubernetes scale and Docker update actions after execution
Two AI write paths asserted unverified success while the Proxmox guest
and Docker start/stop/restart handlers already do read-after-write
checks. Bring both in line with that idiom:

- pulse_kubernetes scale: re-read the deployment's spec/ready replicas
  via kubectl through the same agent (bounded settle-and-retry window)
  and return a JSON response with a verification block instead of
  "Action complete - no verification needed".
- pulse_docker update: the docker agent already recreates the container,
  health-checks it, rolls back on failure, and acks a terminal command
  status; expose that status through a new Monitor lookup
  (GetDockerCommandStatus) plus UpdatesProvider.GetCommandStatus, and
  poll it within a bounded window. Responses now report verified
  success, verified failure (is_error), or an explicit inconclusive,
  never unverified success.

kubernetes_control_test.go also carries a small in-flight fix from the
parallel remediation-lock work (in-memory ActionAuditStore in the test
helper) that these tests require to run on this tree.
2026-07-10 00:05:22 +01:00
rcourtman 85b2bc4008 Improve platform attention workflows 2026-07-10 00:00:07 +01:00
rcourtman 44da863e1a Remove dead internal/license/subscription alias package
Pure re-export shim over pkg/licensing with zero importers in pulse or
pulse-enterprise (internal/ is unreachable from external modules anyway).
Canonical implementations stay in pkg/licensing.
2026-07-09 23:56:33 +01:00
rcourtman 1c11d0945d Skip deleted directories when deriving golangci-lint targets in pre-commit 2026-07-09 23:52:22 +01:00
rcourtman 1894d2e665 Make native agent tests Windows-safe 2026-07-09 23:51:50 +01:00
rcourtman a3ef1226b7 Fail fast on missing native signing configuration 2026-07-09 23:44:22 +01:00
rcourtman 211b80717d Partition host agent tests by platform 2026-07-09 23:40:34 +01:00
rcourtman 51c60df3a4 Exercise native signing in release rehearsals 2026-07-09 23:36:06 +01:00
rcourtman 8a186e2c58 Reconcile concurrent archive validation commits 2026-07-09 23:34:14 +01:00
rcourtman 453b478ac9 Validate release archives in one pass 2026-07-09 23:33:22 +01:00
rcourtman a27350378e Validate release archives in one pass 2026-07-09 23:28:02 +01:00
rcourtman 20b3102015 Improve monitor-first frontend workflows 2026-07-09 23:26:53 +01:00
rcourtman 255c7c23d4 Modernize Unified Agent lifecycle and platform support 2026-07-09 23:20:35 +01:00
rcourtman a5b8d9a3ee Allow complete release candidate validation 2026-07-09 23:11:38 +01:00
rcourtman 54f700371e Add unit tests for 12 untested and weakly-tested frontend modules
Nightly GLM grunt wave: new Vitest coverage for pure logic that had no
test file or only shallow export coverage. 436 test cases, all green;
tsc and eslint clean. Tests characterize current behavior only; no
source was modified.

Untested modules now covered:
- api/responseUtils (19 coercion/guard fns)
- utils/workloads (8 predicates/builders)
- features/storageBackups/storageSearchQuery, storageMetricsIdentity
- utils/platformSupportManifest (12 manifest lookups)
- stores/sessionCapabilities, content/help registry

Weakly-tested modules strengthened (new *.coverage.test.ts):
- utils/format (5 formatters), features/alerts/helpers (apprise round-trip)
- utils/cloudPlans (parseCloudTier), utils/alerts, utils/agentResources
2026-07-09 23:08:09 +01:00
rcourtman fb75ac6a05 Quiesce discovery backfills during shutdown 2026-07-09 23:03:21 +01:00
rcourtman 02283c5335 Make connected systems task-first 2026-07-09 22:48:52 +01:00
rcourtman cc0952e491 Run signed candidate builds during dispatched rehearsals 2026-07-09 22:32:40 +01:00
rcourtman 949ba7ed31 Reconcile concurrent main updates 2026-07-09 22:32:01 +01:00
rcourtman cce58ceb19 Improve platform frontend coherence 2026-07-09 22:27:35 +01:00
rcourtman f5c427a4e1 Improve platform frontend coherence 2026-07-09 22:23:21 +01:00
rcourtman 8dda0b6efa Build releases once and promote verified candidates 2026-07-09 22:21:34 +01:00
rcourtman b26716b3c9 Add unit tests for localStorage, logger, toast utils 2026-07-09 21:47:27 +01:00
rcourtman 9706c4fade Add unit tests for alert override identity, threshold mutation models, patrol autonomy 2026-07-09 21:46:11 +01:00
rcourtman 70161e0079 Record unattended patch release proof 2026-07-09 21:42:26 +01:00
rcourtman ba49c28878 Add unit tests for platformPage, docker drawer, and backup presentation modules 2026-07-09 21:33:56 +01:00
rcourtman 0fa841f66f Improve monitor-first attention states 2026-07-09 21:29:45 +01:00
rcourtman 01b14733cf Fix Docker and Kubernetes agent clock-skew liveness
Stamp LastSeen and rate-tracker samples with server receipt time instead
of the agent-reported timestamp, matching the host agent fix. A drifted
agent clock could otherwise mark a reporting Docker host or Kubernetes
cluster permanently stale and loop offline/recovery alerts.

Refs #1519
2026-07-09 21:21:03 +01:00
rcourtman 112a2a68e9 Remove weak ?raw contract-test assertions that pin nothing
Delete generic substring pins (toContain('Button') next to
ButtonLink/ActionIconButton siblings, 'import {', 'const {') that can
never fail independently, plus the not.toContain('Pro') booby trap on
DataHandlingPanel that the word Proxmox would spuriously trip. Where
sibling coverage was incomplete, replace with a specific pin instead:
ErrorBoundary 'Button' becomes the shared-Button import line, and the
proxmoxVersion 'unknown' pin becomes the actual sentinel check.
2026-07-09 21:08:21 +01:00
rcourtman 958c6dfc6e Remove dead empty-iterable guardrail loops from contract tests 2026-07-09 21:03:16 +01:00
rcourtman 0d89be1c91 Use canonical audit record API in migration test 2026-07-09 20:58:23 +01:00
rcourtman 33b287f515 Add unit tests for alertThresholdDefaults, storageSources, storageSummaryCache utils 2026-07-09 20:42:58 +01:00
rcourtman a040c7d7a6 Add unit tests for agentVersion, proxmoxVersion, resourceSearchMatch, vmwareDisplay utils 2026-07-09 20:40:37 +01:00
rcourtman 7897a9131e Fix FreeBSD agent update recovery
Refs #1546
2026-07-09 20:36:58 +01:00
rcourtman f8bbae2f34 Expose demo tailnet identity diagnostics 2026-07-09 20:32:43 +01:00
rcourtman dc27927fb8 Merge remote-tracking branch 'origin/main' 2026-07-09 20:31:22 +01:00