Commit Graph

6642 Commits

Author SHA1 Message Date
rcourtman affc1c76ed Add rc.6 operator support pack and prerelease index pointers
Stages the doc-only subset of rc.6 packet prep work on top of
df7934936. Holds VERSION bump and the registry/contract governance
reconciliation back for a focused later pass since the IA revert
created broader subsystem-contract debt than the packet prep can
absorb.

- docs/releases/V6_RC6_OPERATOR_SUPPORT_PACK_DRAFT.md: new 300-line
  operator support brief mirroring the rc.5 pack with rc.6 themes:
  pre-release for testing framing, platform-shaped frontend revert
  explanation, vSphere as a first-class platform, Machines surface,
  TrueNAS native detail UX, FilterBar adoption, Patrol capacity-
  forecast and PDM bridge, free-first self-hosted posture, install.sh
  smoke gate. Carries the rc.5 free-first paid-continuity wording
  through unchanged so the operator-support-pack policy test holds.
- docs/releases/RELEASE_NOTES_v6_RC6_DRAFT.md,
  docs/releases/V6_CHANGELOG_RC6_DRAFT.md: fill in the SHA audit
  numbers (v6.0.0-rc.5..df7934936, 616 commits, 1379 files / 139185
  insertions / 67870 deletions). Add the licensing-continuity
  paragraph carrying the rc.5 Pulse Mobile pairing for handoff
  copy through unchanged so the discovered-packet policy test holds.
- docs/RELEASE_NOTES.md: link the rc.6 draft packet as current, push
  rc.5 to historical.
- docs/UPGRADE_v6.md: round out the prerelease packet pointer block
  with the rc.6 operator support pack path alongside the release
  notes and changelog already pointed at in df7934936.
- docs/releases/V6_PRERELEASE_RUNBOOK.md: add 6.0.0-rc.6 to the
  version-examples list and bump the RC_VERSION export shown in the
  RC release steps to rc.6.

Out of scope for this commit and intentionally held back until
governance reconciliation can land coherently:

- VERSION bump to 6.0.0-rc.6 (triggers deployment-installability
  shape-guard which cascades into registry/contract audits against
  72 dead-file references left over from the rc.6 IA revert).
- docs/release-control/v6/internal/status.json,
  docs/release-control/v6/internal/subsystems/registry.json, and the
  10 subsystem contract .md files that need post-IA-revert cleanup.
- scripts/release_control test fixture refreshes.
- The rc-to-ga-promotion-readiness-blocked record regen (gated on
  VERSION bump landing).

Working copies of the held-back files are preserved at
/tmp/rc6-prep-backup-2026-05-27/ with a MANIFEST.md describing each.
2026-05-27 13:37:24 +01:00
rcourtman ed8a9652b2 Add Machines row actions 2026-05-27 12:09:44 +01:00
rcourtman df79349368 Document rc.6 frontend IA revert in v6 release docs
rc.1-rc.5 shipped a unified /infrastructure /workloads /storage
/recovery top-level layout; rc.6 reverts the frontend to platform-
shaped pages (Proxmox / Docker / Kubernetes / TrueNAS / vSphere /
Standalone) on the same unified resource backend.

Updates the shipped v6 release docs to match:

- RELEASE_NOTES_v6.md and V6_CHANGELOG.md rewritten to describe the
  v6 layout as platform-shaped on a unified backend, with a paragraph
  in each explaining the rc.6 revert and the operator feedback that
  drove it.
- UPGRADE_v6.md prerelease packet pointer bumped from rc.5 to rc.6.
- MIGRATION_UNIFIED_NAV.md gets a top-of-file revert banner that
  redirects bookmarks targeting the unified routes to their platform-
  shaped equivalents; the original content is preserved below as a
  Historical Context section so the 19 tracked references into that
  doc still resolve.

Also adds the rc.6 draft packet:

- docs/releases/RELEASE_NOTES_v6_RC6_DRAFT.md
- docs/releases/V6_CHANGELOG_RC6_DRAFT.md

Validation SHAs in both drafts are left as <populate at packet
finalisation> markers; they fill in when the release-control packet
runs.
2026-05-27 11:50:59 +01:00
rcourtman 53149ab6c2 Add Machines filter reset path 2026-05-27 11:09:33 +01:00
rcourtman 4ae0968fbe Improve Machines search affordances 2026-05-27 11:00:35 +01:00
rcourtman 5692325031 Promote Machines web interface editor 2026-05-27 09:29:51 +01:00
rcourtman c386054172 Surface Machines web interface links 2026-05-27 09:20:05 +01:00
rcourtman f354dab065 Stop stripping workloads runtime/namespace before guest data loads
The cleanup effects in useWorkloadUrlSync removed a URL-set
containerRuntime or kubernetesNamespace whenever the value wasn't in
the options list. Before guests load that list is empty, so the
cleanup wrongly wiped perfectly valid URL values — including those
applied by a saved view or a deep link.

Skip cleanup when the candidates list is empty. Once a non-empty list
arrives, the existence check runs as before and a value not present
in the loaded options is cleared.

The remaining edge case (runtime carried into a view that genuinely
has no runtime options, e.g. Proxmox LXC) leaves a harmless dangling
URL param; filterWorkloads only consults runtime when relevant.
2026-05-27 08:25:02 +01:00
rcourtman 3c850578bb Make SavedViews default-star always visible
The star toggle that sets a view as the default-on-landing was
opacity-0 unless the row was hovered. Users had to discover the
feature by accident.

Show the star at idle on every row: filled amber for the current
default, outline grey otherwise. Hovering a grey star tints it amber
so the intent is clear before clicking. The X (delete) stays
hover-only because it's a destructive action that should be gated by
intent; toggling default is not.
2026-05-27 08:20:28 +01:00
rcourtman 2550d1fc86 Preserve Machines seen context when column hidden 2026-05-27 08:08:25 +01:00
rcourtman 6bd5890b3b Add Machines row expansion affordance 2026-05-27 08:05:25 +01:00
rcourtman 0ecece6925 Convert audit log filter form to FilterBar with SavedViews
Replace the bespoke filter form (FormSelects + free-text user input +
manual chip strip) with the canonical FilterBar. The user filter
becomes the search box, the three category filters become chips, and
the page-size selector moves into the view-options trailing slot.

Wire savedViewsKey='audit' so the Saved menu attaches to this surface.
Filter state has already moved to the URL (preceding commit), so saved
views capture exactly what location.search holds.

Drops the unused clearFilterChip from the panel; FilterBar handles
chip clear inline.
2026-05-27 08:01:48 +01:00
rcourtman 31a9714ebf Move audit filters to URL and live-apply
Replace the staged-then-Apply audit filter form with the live-apply
model the rest of Pulse uses (Workloads, Alerts, Storage). Filter state
moves from localStorage into URL search params so the page is
shareable and ready for SavedViews.

Behavior changes:
- eventFilter, successFilter, verificationFilter, userFilter are URL
  params (?event, ?success, ?verification, ?user). Default values are
  omitted from the URL.
- Server-side filters (event, success) refetch the first page
  immediately when changed.
- userFilter debounces refetch by 300ms so typing 'alice' doesn't
  send five requests.
- verificationFilter is purely client-side and only retriggers the
  filteredEvents memo.
- The Apply button is gone; clearFilters and clearFilterChip drop the
  explicit refetch (the live-apply effects handle it).

Legacy localStorage values for the four filters migrate into the URL
once on first mount; pageSize, pageOffset, and the autoVerify prefs
stay in localStorage because they are page state, not view state.

Update the audit log architecture boundary test to expect the new
shape (useLocation/useNavigate, no createLocalStorageStringSignal).
2026-05-27 07:57:52 +01:00
rcourtman 09119d250e Wire savedViewsKey on the embedded workloads filter
Derive a platform-scoped savedViewsKey from forcedPlatform inside
useWorkloadsState (workloads-<platform-id>, e.g. workloads-proxmox-pve,
workloads-vmware-vsphere) and pipe it through WorkloadsSurface ->
WorkloadsFilter -> FilterBar. Saved views never leak across platforms
because every live consumer locks platform scope.

Only the embedded WorkloadsFilter inside WorkloadsSurface receives the
key. The shared filter toolbar mounted directly by ProxmoxPageSurface /
VmwarePageSurface is a slim scope picker for the hosts table on top of
the page; the bottom embedded filter is the fuller per-table row and
the natural home for the SavedViews menu.
2026-05-27 07:39:15 +01:00
rcourtman 7a9b4062fb Show Machines row identity context 2026-05-27 07:36:54 +01:00
rcourtman f3a236e8ae Drop localStorage backup for workloads viewMode and containerRuntime
Both fields are already URL-mirrored by useWorkloadUrlSync; the
usePersistentSignal wrapping was a redundant second source of truth
that broke SavedViews' default-view auto-apply.

The auto-apply path checks window.location.search === ''. With the
persistent backup, a returning user's last viewMode would seed the URL
through the state -> URL effect before SavedViews onMount ran, so the
default view never landed. Dropping the persistent wrap leaves URL as
the only source.

Legacy localStorage values (workloadsViewMode, workloadsContainerRuntime)
are migrated to URL on first mount when the URL has no matching param;
runtime migration may be dropped by the pre-existing
containerRuntimeOptions cleanup effect when options haven't loaded
yet, matching the prior persistent-signal behavior.
2026-05-27 07:33:30 +01:00
rcourtman 103e46ede1 Render Machines IP detail tooltip 2026-05-27 07:30:26 +01:00
rcourtman 619f9f8997 Migrate workloads search and statusMode to URL params
Move two filter-state fields out of in-memory / localStorage into
URL search params:
- search -> ?q
- statusMode -> ?status (default 'all' omitted)

The remaining filter-shaped state on the workloads surface (viewMode,
containerRuntime, scope: node/platform/context/namespace/agent) was
already URL-mirrored via useWorkloadUrlSync; only these two were
unreachable from a query string. With this commit the workloads filter
state is fully captured by location.search, which is the prerequisite
for wiring savedViewsKey on workload surfaces.

On first mount each surface migrates the legacy scoped
workloadsStatusMode[:<scope>] localStorage value into ?status if URL is
clean. Legacy key left in place; harmless once URL takes over.

Test mocks @solidjs/router so useLocation/useNavigate resolve under
createRoot.
2026-05-27 07:28:41 +01:00
rcourtman cfd048e90c Update stale Patrol ApprovalSection assertions and sync shipped CONFIGURATION docs
ApprovalSection.test.tsx: the assistant briefing was refactored — title
changed from "Operator briefing attached" to "Patrol finding attached",
actionLabel was dropped (now undefined), and detailLines was reduced to
a single concatenated "Existing action artifact" line whose prior
multi-line content moved into handoffContext. Three of the five tests
asserted the old shape and failed. Update each one to assert the new
title, drop the stale detailLines/actionLabel matchers, and reassert
the semantic intent against the new handoffContext / commandSummary /
safetyNote / status string. All safety-critical "no raw command text
leaks into context" assertions are preserved.

CONFIGURATION.md: the repo source was updated with three
PULSE_ENABLE_PROXMOX_GUEST_DOCKER_* env vars and two TrueNAS rows
that never made it into the shipped public/docs copy, so docsLinks
guardrail flagged the divergence. Sync the file.

Pre-existing SECURITY.md sync mismatch (other agent's in-progress
edit) is unchanged.
2026-05-27 07:27:34 +01:00
rcourtman 751457b0b3 Render Machines disk I/O detail tooltip 2026-05-27 07:20:48 +01:00
rcourtman 74d4770d61 Drop last stale interactiveSparklineModel + state ?raw imports
Final tail of the orphan cleanup. The InteractiveSparkline component
and its state hook + model file were deleted in earlier rounds, but
two more `?raw` guardrail imports lingered:
- frontendResourceTypeBoundaries.test.ts (2)
- SharedPrimitives.guardrails.test.ts (2)

Strips them and the assertions that referenced them. Programmatic
orphan + stale-?raw sweep both return clean afterward.
2026-05-26 22:06:31 +01:00
rcourtman 76599b2a90 Restore TableCardHeader title and update stale frontend test assertions
TableCardHeader wrapped its entire body in a Show-when-actions gate, so
every title-only caller silently rendered nothing — Docker Images,
Docker Secrets, TrueNAS Apps/Services/Storage/Virtual Machines/Network
Shares/Health Alerts/Systems, and the Service Infrastructure dual-table
section all lost their section title. Render the title whenever it's
provided and only suppress the actions row when no actions exist. The
header bar still collapses entirely when both title and actions are
absent.

While there, fix three stale test assertions exposed by the same
sweep:
- ResourceDetailDrawer.identity-runtime: expected the host detail
  disclosure to say "Host" / "Show host", but Pulse-agent resources
  now use "Machine" / "Show machine".
- settingsArchitecture: matched the old zero-arg signature for
  buildAvailabilityTargetAddPath, which now takes an optional
  targetKind parameter.
- UnifiedResourceTable.performance.contract: the grouped Profile S
  render reliably brushed the 5s default waitFor timeout; bump to the
  same 15s the neighbouring row-windowing contracts use, plus a 30s
  test-level timeout, so it stops flaking under load.
2026-05-26 22:05:44 +01:00
rcourtman d1a7e018b3 Render Machines RAID detail tooltip 2026-05-26 21:57:44 +01:00
rcourtman 6d2f6e8e28 Update stale test assertions to match canonical column order and shape
Three frontend tests asserted against shapes the runtime no longer
produces:

- proxmoxHostTableModel.test.ts expected uptime before the CPU/Memory/
  Disk bar block on compact layouts. Commit 300af4312 ("Move Uptime
  after the bar block in platform top tables") canonicalized uptime to
  sit after the diagnostic Temp column, but the test wasn't updated.
- platformOverviewLayout.guardrails.test.ts asserted that
  AgentsMachinesTable's source contained literal "Machine"/"CPU"/etc
  next to getPlatformTableHeadClassForKind calls. AgentsMachinesTable
  now uses a column-config pattern where labels live in
  agentMachineTableModel.ts; redirect the assertions to the model file
  so they continue to enforce kind/label alignment.
- useStoragePoolDetailModel.test.ts expected the linkedDisks shape with
  five fields. The model now also exposes errorCount, ioLabel, role,
  sizeLabel, spunDown, and state. Update the expectation to include
  them.
2026-05-26 21:54:22 +01:00
rcourtman 334dd00125 Render Machines network detail tooltip 2026-05-26 21:43:30 +01:00
rcourtman 06f3bc745f Render Machines temperature detail tooltip 2026-05-26 20:55:15 +01:00
rcourtman 330fc042f7 Drop empty guardrail it() bodies left behind by orphan cleanup
After the orphan-source ?raw imports were stripped from these guardrail
tests in earlier cleanups, the it() blocks that exercised those
primitives ended up with no assertions. Removing the husks:

SharedPrimitives.guardrails.test.ts:
- keeps scroll-to-top button on shell, runtime, and model owners
- keeps infrastructure summary table on shell, runtime, and model owners
- keeps infrastructure selector on shell, runtime, and model owners
- keeps density map on shell, runtime, and model owners
- keeps infrastructure details drawer on shell, runtime, and model
  owners
- keeps sticky summary breakpoint behavior on the shared primitive
- keeps collapsible search input on shell, runtime, and model owners

UnifiedResourceTable.performance.contract.test.tsx:
- keeps infrastructure summary fetch runtime out of the render shell
2026-05-26 20:53:00 +01:00
rcourtman ecb533a865 Delete unused timeRange util
Last leaf. utils/timeRange.ts exported `timeRangeToMs` with no live
consumer; only its own test referenced it. Drops the helper + its
direct test + the time-range conversion describe block from
charts.test.ts that exercised it through the API layer.
2026-05-26 20:39:19 +01:00
rcourtman 4926119d0f Delete InteractiveSparkline model + state hook orphaned by Cleanup N
Final leaf — these two files were only consumed by InteractiveSparkline.tsx
which was deleted in Cleanup N. Nothing else imports them.

- components/shared/useInteractiveSparklineState.ts
- components/shared/interactiveSparklineModel.ts

Baseline 10 pre-existing failures unchanged.
2026-05-26 20:30:30 +01:00
rcourtman 89d289461a Delete final cascade orphans (agentDeploy + InteractiveSparkline)
Last leaves after Cleanup L+M:

- api/agentDeploy.ts and types/agentDeploy.ts — agent-deploy API client
  + types, only ever consumed by the deleted deploy wizard hooks/
  components.
- components/shared/InteractiveSparkline.tsx + test — chart primitive
  only rendered by the deleted summary surfaces.

Strips the remaining stale ?raw guardrail imports + assertions from
apiErrorStatus.guardrails.test.ts, SharedPrimitives.guardrails.test.ts,
and frontendResourceTypeBoundaries.test.ts for every file deleted in
the recent rounds (collapsibleSearchInputModel, densityMapModel,
scrollToTopButtonModel, useCollapsibleSearchInputState,
useDensityMapState, useScrollToTopButtonState,
infrastructureDetailsDrawerModel, useInfrastructureDetailsDrawerState,
MonitoredSystemDefinitionDisclosure, InteractiveSparkline,
useDiskLiveMetricModel, useZFSHealthMapModel, MailGateway,
PMGInstancePanel, ServiceHealthBadge, pmgPresentation,
pmgThreatPresentation, pmgQueuePresentation, deployStatusPresentation,
deployFlowPresentation, DeployStatusBadge, diskLiveMetricPresentation,
zfsHealthMapPresentation, recoveryIssuePresentation, hostedSignup).
2026-05-26 20:26:23 +01:00
rcourtman c01f5d467b Improve Machines temperature detail titles 2026-05-26 20:21:17 +01:00
rcourtman d378842afb Preserve SMART temperature fallback for Machines 2026-05-26 20:15:36 +01:00
rcourtman b99c3a2d0d Delete cascade orphans surfaced by Cleanup L
Iterative pass — deleting Cleanup L's parents revealed these as the
new leaves with no consumer. Same verification (static-import grep
+ JSX grep + lazy-import scan) before each removal.

Storage feature utils:
- features/storageBackups/zfsHealthMapPresentation.ts + test
- features/storageBackups/diskLiveMetricPresentation.ts + test

Stores:
- stores/diskMetricsHistory.ts + test (only ever fed the deleted
  metricsCollector)

PMG (sibling of deleted PMGInstancePanel / MailGateway / ServiceHealthBadge):
- utils/pmgPresentation.ts + test
- utils/pmgQueuePresentation.ts + test
- utils/pmgThreatPresentation.ts + test
- components/PMG/ServiceHealthBadge.tsx

Deploy wizard tail:
- utils/deployStatusPresentation.ts + test
- hooks/useDeployStream.ts + test

Hosted-signup tail:
- api/hostedSignup.ts + test

Shared component models orphaned with their parents:
- components/shared/collapsibleSearchInputModel.ts
- components/shared/scrollToTopButtonModel.ts
- components/shared/densityMapModel.ts

Baseline 10 pre-existing test failures still flat.
2026-05-26 20:13:02 +01:00
rcourtman 1307d681bf Preserve richer agent telemetry in Machines table 2026-05-26 20:07:43 +01:00
rcourtman c40455806f Delete dead pages, stores, components, and presentation utils
Twelfth cleanup round. The Explore audit surfaced a further batch of
files with zero non-test consumers. Each was verified by static-import
grep + JSX-usage grep + lazy-import scan before deletion.

Pages (defined but never wired into App.tsx routing):
- pages/HostedSignup.tsx + test
- pages/CloudPricing.tsx + test

Stores (re-export wrapper + dead utility):
- stores/demoMode.ts (re-export shim around sessionPresentationPolicy)
- stores/metricsCollector.ts + test (retired with the live-metrics
  collector decision — App.architecture.test.ts still enforces that
  App.tsx must not re-import it)

Hooks / state:
- hooks/useDeployWizard.ts + test (consumed only by deleted deploy
  wizard steps in Cleanup K)
- components/shared/useInfrastructureDetailsDrawerState.ts and
  infrastructureDetailsDrawerModel.ts (only consumed by the deleted
  InfrastructureDetailsDrawer)
- components/shared/useCollapsibleSearchInputState.ts,
  useDensityMapState.ts, useScrollToTopButtonState.ts (model files
  for shared components deleted in Cleanup K)
- components/Storage/useZFSHealthMapModel.ts + test,
  useDiskLiveMetricModel.ts + test (models for Storage components
  deleted in Cleanup K)

Shared primitives:
- components/shared/PageControls.tsx + test + guardrails test —
  the legacy filter UI fully replaced by FilterBar across every
  surface; no consumer remains
- components/shared/responsive/ResponsiveHeader.tsx and
  useGridTemplate.ts (no consumer)

Other components:
- components/PMG/PMGInstancePanel.tsx and MailGateway.tsx (PMG
  surface superseded by ProxmoxMailGatewayDrawer in the inline-drawer
  unification)
- components/Commercial/MonitoredSystemDefinitionDisclosure.tsx + test
  (only used by the deleted MonitoredSystemLedgerPanel)
- components/Infrastructure/deploy/ErrorDetail.tsx + test and
  DeployStatusBadge.tsx + test (deploy wizard step helpers)

Utils:
- utils/deployFlowPresentation.ts + test (deploy wizard presentation)
- utils/recoveryLocationPresentation.ts + test,
  recoveryIssuePresentation.ts + test (Recovery surface utils)
- utils/snooze.ts (no consumer)

Updates useAppRuntimeState.test.ts to import demo-mode helpers
directly from sessionPresentationPolicy now that the demoMode wrapper
is gone.
2026-05-26 20:06:47 +01:00
rcourtman c26665a63a Delete more orphans: deploy wizard steps, storage diagnostics, recovery hooks
Eleventh round of orphan deletion. The platform-first IA migration
left many UI components and presentation utilities behind whose only
consumers were already-deleted aggregate surfaces, deploy wizard, or
recovery pages.

Storage:
- ZFSHealthMap.tsx — diagnostic indicator only used by the deleted
  Storage standalone summary
- DiskLiveMetric.tsx — live metric bar only used by deleted summary
- storageSourceOptions.ts + test — options helper for deleted controls

Infrastructure:
- resourceBadges.ts + test — badge helpers only used by deleted
  ConfiguredNodeTables / MonitoredSystemLedgerPanel
- deploy/CandidatesStep, ConfirmStep, DeployingStep, PreflightStep,
  ResultsStep + their tests — the deploy wizard retired with
  AgentDeployModal

Shared:
- DensityMap, SparklineSkeleton, InfrastructureDetailsDrawer (and
  tests) — primitives only consumed by deleted summary chrome
- CollapsibleSearchInput.tsx — collapsing search variant with no
  current consumer
- ScrollToTopButton.tsx + test — only used by deleted WorkloadsSurface
  chrome

Utils:
- clusterEndpointPresentation, recoveryTablePresentation,
  configuredNodeCapabilityPresentation, configuredNodeStatusPresentation
  (with tests) — all consumed only by deleted surfaces

Hooks:
- useRecoveryPointsSeries / useRecoveryPointsFacets /
  useRecoveryRollups — recovery hooks for the retired aggregate surface
- useDebouncedValue + test — generic debounce with no consumer

Test files:
- DeployStepComponents.test.tsx — entire file tested deleted wizard
- SearchInput.test.tsx — dropped 3 tests that exercised
  CollapsibleSearchInput plus the now-unused focusActiveTypeToSearch
  import

Strips ?raw guardrail imports + assertions for every deleted file from
SharedPrimitives.guardrails and frontendResourceTypeBoundaries.
2026-05-26 19:58:15 +01:00
rcourtman ae65c5e9a2 Delete remaining orphan Settings panels, Summary primitives, and presentation utils
Final sweep of the post-IA-migration cleanup. These files have zero
non-test consumers in the platform-first codebase:

Settings panels (consumed only by the deleted aggregate Settings shell):
- ConfiguredNodeTables.tsx
- MonitoredSystemLedgerPanel.tsx (+ test)
- SettingsSectionNav.tsx

Shared Summary primitives (only rendered by the deleted aggregate
summary surfaces — InfrastructureSummary, WorkloadsSummary,
StoragePageSummary):
- SummaryJumpToRowButton.tsx
- SummaryMetricCard.tsx
- SummarySynchronizedReadout.tsx

Platform-feature column config (only consumed by deleted
WorkloadsStateCards / WorkloadsSurface chrome):
- features/platformPage/appContainerColumns.ts

Presentation utilities (only consumed by the deleted Recovery surface,
problem-resource summary, throughput card, approval section, chart
series card, proxmox settings panel — every consumer of these utils
was deleted in earlier cleanups):
- utils/recoveryStatusPresentation.ts (+ test)
- utils/recoveryFilterChipPresentation.ts (+ test)
- utils/recoveryRecordPresentation.ts (+ test)
- utils/recoveryActionPresentation.ts (+ test)
- utils/recoveryEmptyStatePresentation.ts (+ test)
- utils/throughputPresentation.ts (+ test)
- utils/approvalPresentation.ts (+ test)
- utils/chartSeriesPresentation.ts (+ test)
- utils/problemResourcePresentation.ts (+ test)
- utils/proxmoxSettingsPresentation.ts (+ test)

Strips ?raw guardrail imports + assertions for all deleted sources
from SharedPrimitives.guardrails / frontendResourceTypeBoundaries /
UnifiedResourceTable.performance.contract. Drops the dead
configuredNodeTablesSource entry from a structural assertion array
and the stale shouldShowCephSummaryCard / getStoragePageBannerMessage
/ STORAGE_BANNER_ACTION_BUTTON_CLASS / getStoragePageBannerKind
expectations that were checking exports already removed in Cleanup H.

Baseline 10 pre-existing test failures unchanged.
2026-05-26 19:47:27 +01:00
rcourtman 579b7c1e62 Delete orphaned Summary primitive components
Final tail of the platform-first IA cleanup. These shared summary
primitives were rendered by the deleted aggregate summary surfaces
(InfrastructureSummary, WorkloadsSummary, StoragePageSummary) and have
no remaining consumers post-cleanup:

- components/shared/SummaryJumpToRowButton.tsx — the "jump to active
  row" affordance that surfaced in the dead summary chrome
- components/shared/SummaryMetricCard.tsx — metric-card primitive used
  by the deleted summary chrome
- components/shared/SummarySynchronizedReadout.tsx — chart/value
  readout used by the deleted summary chart cards

Strips the remaining `?raw` guardrail imports + assertions for these
sources from SharedPrimitives.guardrails.test.ts.
2026-05-26 19:26:51 +01:00
rcourtman cc07c1e580 Delete orphaned Ceph summary card and storage banner machinery
Tail of the post-IA-migration cleanup. The Ceph summary card stack and
the storage status-banner helpers were only ever rendered by the
deleted Storage standalone summary section + banners surface.

Deletes:
- components/Storage/StorageCephSummaryCard.tsx (+ model + test)
- components/Storage/useStorageCephSummaryCardModel.ts
- features/storageBackups/cephSummaryCardPresentation.ts (+ test)

Drops the now-dead exports from features/storageBackups/storagePagePresentation.ts:
- StoragePageBannerKind type
- STORAGE_BANNER_ACTION_BUTTON_CLASS / STORAGE_PAGE_BANNER_ROW_CLASS /
  STORAGE_PAGE_BANNER_TEXT_CLASS
- shouldShowCephSummaryCard / getCephSummaryClusterCountLabel /
  getCephSummaryHeading / getCephSummaryTotalLabel /
  getCephSummaryUsageLabel / getCephClusterCardTitle
- getStoragePageBannerMessage / getStoragePageBannerActionLabel
- Unused imports of formatBytes/formatPercent/StorageRecord/CephSummaryStats

Drops getStoragePageBannerKind + StoragePageBannerStateInput from
features/storageBackups/storagePageStatus.ts; isStoragePoolLoading
remains for the live loading indicator.

Tightens useStoragePageStatus to just return isLoadingPools (drops
hasFetchError + activeBannerKind + their inputs). useStoragePageModel
no longer destructures activeBannerKind and stops passing reconnecting,
error, connected, initialDataReceived through.

Tightens the StoragePageControls prop comment (was still referencing
WorkloadsFilter contract by name and "standalone /storage" which no
longer exists).

Rewrites storagePagePresentation / storagePageStatus / useStoragePageStatus
tests to cover just the surviving behavior. Strips remaining stale ?raw
imports of the deleted SummaryPanel / MigrationNoticeBanner / AgentDeployModal
/ storageSummaryTrendCache / StorageCephSummaryCard /
useStorageCephSummaryCardModel / cephSummaryCardPresentation sources
from frontendResourceTypeBoundaries + SharedPrimitives guardrails.
2026-05-26 19:19:46 +01:00
rcourtman 886c605533 Add aggregate disk summary to machine details 2026-05-26 19:16:59 +01:00
rcourtman b91dc8dd4c Delete remaining orphans surfaced by final cleanup sweep
Final tail of the post-IA-migration cleanup. None of these files have
non-test consumers; most were last touched by the retired aggregate
chrome:

- components/shared/SummaryPanel.tsx — old summary panel primitive,
  superseded by the per-platform table cards that replaced the
  Infrastructure/Workloads aggregate summaries.
- components/shared/MigrationNoticeBanner.tsx — one-shot upgrade
  banner with no live consumer.
- components/Infrastructure/AgentDeployModal.tsx — replaced by the
  per-platform deploy flows in features/standalone (Machines). Drops
  its unit test and the AgentDeployWizardE2E test that exercised it.
- utils/storageSummaryTrendCache.ts — small in-memory cache only
  consumed by the deleted Storage summary chart pipeline.

Also drops the leftover dead STORAGE_KEYS entries: STORAGE_SHOW_FILTERS,
STORAGE_VIEW_MODE, STORAGE_SOURCE_FILTER, RECOVERY_SHOW_FILTERS,
RECOVERY_USE_RELATIVE_TIME, WORKLOADS_SHOW_FILTERS, WORKLOADS_CARD_VIEW,
WORKLOADS_AUTO_REFRESH. Persisted user-side values under those key
strings will simply stop being read; Pulse never read them back after
the standalone surfaces went away. WORKLOADS_SEARCH_HISTORY,
AGENTS_SEARCH_HISTORY, etc. remain — they back live filter-bar search
history.

Baseline test failures (10) unchanged.
2026-05-26 17:06:21 +01:00
rcourtman 7b924bcc73 Strip vestigial summary state from Workloads + Storage state hooks
Continuation of the platform-first IA cleanup. Earlier commits deleted
the standalone-mode chrome and its subcomponents; this pass removes the
state machinery that was only ever consumed by that dead chrome.

useStoragePageModel:
- Drops the persistent signals for STORAGE_SUMMARY_RANGE and
  STORAGE_SUMMARY_COLLAPSED. summaryTimeRange collapses to a constant
  '24h' since useStorageSummaryCharts still needs a range argument for
  the live growth-column pipeline that feeds StorageContentCard.
- Drops storageSummaryData / storageSummaryLoaded / storageSummaryFetchFailed
  / cephSummaryStats / chartHoverSync / setChartHoverSync /
  focusedStorageResourceId / shouldShowJumpToActiveStorageRow /
  jumpToActiveStorageRow / activeSummaryScopeState from the return.
  All consumed only by the deleted summary surfaces.

useWorkloadsControlsState:
- Drops the persistent signals for WORKLOADS_SUMMARY_RANGE and
  WORKLOADS_SUMMARY_COLLAPSED plus their setters from the return.

useWorkloadSelectionState:
- Drops chartHoverSync / setChartHoverSync / jumpToActiveWorkloadRow /
  shouldShowJumpToActiveWorkloadRow / activeSummaryScopeState from the
  return. hoveredWorkloadId stays since the cross-row hover effect that
  clears stale IDs on filter change still has a meaningful test, even
  though no live consumer reads it post-cleanup.

useWorkloadsDerivedState:
- Drops the workloadsSummaryVisibleIds / workloadsSummaryFallbackCounts /
  workloadsSummaryFallbackSnapshots memos entirely, along with the
  WorkloadSummarySnapshot type and the workloadMetricPercent /
  getDiskUsagePercent helpers that only fed the fallback snapshot memo.

useWorkloadsState: removes the now-orphaned destructure entries and
return entries that flowed through from the cleaned-up sub-hooks.

utils/localStorage.ts: drops the dead STORAGE_KEYS entries
(STORAGE_SUMMARY_RANGE / COLLAPSED, WORKLOADS_SUMMARY_RANGE / COLLAPSED,
INFRASTRUCTURE_SUMMARY_RANGE / COLLAPSED, AGENTS_SUMMARY_RANGE /
COLLAPSED). Pulse instances may have leftover entries under these key
strings; they will just be ignored from here on.

Deletes the "shows a deliberate jump affordance" test in
useWorkloadSelectionState that exercised the dead jump-to-active-row
affordance.
2026-05-26 16:59:43 +01:00
rcourtman 07b75109d3 Delete orphaned summary subcomponents from shared and Storage
Continuing the cleanup sweep after the platform-first IA migration.
These shared/summary primitives were only consumed by the standalone
chrome that previous cleanups already retired:

- components/Storage/StorageSummary.tsx — the storage chart card
  rendered inside the deleted Storage standalone summary section.
- components/shared/StickySummarySection.tsx — sticky container for
  the deleted Workloads/Storage summary sections.
- components/shared/SummaryTableCardHeader.tsx — header primitive used
  only by deleted summary surfaces.
- components/shared/InfrastructureSummaryTable.tsx and
  InfrastructureSummaryTableRow.tsx — the dedicated infrastructure
  summary table rendered by the deleted InfrastructureSummary; not the
  same as the live UnifiedResourceTable.
- components/shared/useInfrastructureSummaryTableState.ts and
  infrastructureSummaryTableModel.ts — hook and model that only ever
  fed the table above.

Drops the dead "shows compact synchronized readouts" test in
Storage.test.tsx that rendered <StorageSummary> directly. Strips the
?raw guardrail imports and assertions from
SharedPrimitives.guardrails.test.ts and
frontendResourceTypeBoundaries.test.ts.

Pre-existing failures (10 tests, 8 files) stayed unchanged across this
cleanup; no new failures introduced.
2026-05-26 16:43:59 +01:00
rcourtman d8a8709b56 Delete orphaned InfrastructureSummary and infrastructureSummaryModel
InfrastructureSummary.tsx (and useInfrastructureSummaryState.ts behind it,
and infrastructureSummaryModel.ts under both) was the standalone
infrastructure summary surface — sibling to the WorkloadsSummary,
StoragePageSummary, etc. that the platform-first IA retired. No live
JSX consumer remains; every grep for `<InfrastructureSummary` returns
only the file's own tests.

Deletes the source files, their tests, and the guardrail assertions
in frontendResourceTypeBoundaries / SharedPrimitives /
UnifiedResourceTable.performance.contract that referenced them via
?raw. Same for the dead InfrastructureSelector chain whose source files
were already removed in Cleanup B but whose ?raw guardrails were
still around.

The shared InfrastructureSummaryTable (a different component used by
UnifiedResourceTable) stays — it is the live host-table primitive.
2026-05-26 16:30:27 +01:00
rcourtman 38077c81cb Drop dead WorkloadsSurface standalone chrome and orphaned subcomponents
Platform-first IA retired the /workloads aggregate route. Every live
consumer of WorkloadsSurface is now a platform-embedded mount
(Proxmox overview, VMware overview) that previously passed
embedded=true and tableOnly=true to suppress the standalone-mode
chrome. The standalone chrome JSX branches in WorkloadsSurface.tsx
never execute and the subcomponents behind them have no live consumer.

Deletes the orphans:
- components/Workloads/WorkloadsSummary.tsx (+ test)
- components/Workloads/WorkloadsStateCards.tsx (+ test)
- components/Workloads/WorkloadsStatsStrip.tsx
- components/shared/InfrastructureSelector.tsx (+ test)
- components/shared/useInfrastructureSelectorState.ts
- components/shared/infrastructureSelectorModel.ts

Drops the dead Show branches in WorkloadsSurface.tsx (PageHeader,
StickySummarySection, WorkloadsSummary, WorkloadsStateCards,
WorkloadsStatsStrip, ScrollToTopButton) and the dead props
embedded/tableOnly/showFilterToolbar/allowEmbeddedScopeFilters from
WorkloadsSurfaceProps. Simplifies useWorkloadRouteState's
routeStateEnabled and useWorkloadFilterOptions's
allowEmbeddedScopeFilters checks to always-true since every live
consumer now passes neither flag.

Updates ProxmoxPageSurface and VmwarePageSurface to stop passing the
dead props. Inlines WorkloadSummarySnapshot into useWorkloadsDerivedState
so the type doesn't import from the deleted WorkloadsSummary.

Deletes the perf-contract test assertions that exercised the dead
subcomponent pipeline and the embed-contract test that exposed the
dead props. Adds kioskMode to two k8s test mocks now that the filter
toolbar Show evaluates state.kioskMode() unconditionally.
2026-05-26 16:12:41 +01:00
rcourtman 23227ef20f Drop dead Storage standalone chrome and orphaned subcomponent pipeline
Platform-first IA retired the /storage aggregate route on 2026-05-25
but left the Storage standalone-mode JSX, props, and subcomponent
pipeline in the tree. Every live Storage consumer is now a
platform-embedded tab passing embedded=true and tableOnly=true, so the
<Show when={!props.embedded}> and <Show when={!props.tableOnly}>
branches in Storage.tsx never execute.

Deletes the orphan files (StoragePageSummary, useStoragePageSummary,
StorageCephSection, useStorageCephSectionModel, StoragePageBanners,
StoragePageBanner, useStoragePageBannersModel, useStoragePageBannerModel)
and their test files. useStorageSummaryCharts remains — it still feeds
the storageGrowthBySeriesId pipeline consumed by StorageContentCard.

Drops the dead JSX branches, dead props (embedded, tableOnly,
showFilterToolbar), and dead destructure entries from Storage.tsx.
Collapses the savedViewsKey computation to drop the unreachable bare
'storage' branch. Removes the chartsCollapsed / onChartsToggle wiring
from StoragePageControls now that the summary section is gone.

Updates the single live consumer ProxmoxPageSurface to stop passing the
dead props. Deletes 9 Storage tests that exercised the dead standalone
chrome and updates 3 guardrail tests to drop their dead-source
references.
2026-05-26 15:44:10 +01:00
rcourtman 66fb198cc6 Delete orphaned Recovery aggregate surface
The platform-first IA migration retired /recovery on 2026-05-25
(commit 8b0b1b0c6) but left the Recovery surface components and their
guardrail tests in the tree, where they read like live code to anyone
grepping the codebase. Recovery.tsx, RecoveryActivitySection,
RecoveryHistorySection, RecoveryProtectedInventorySection,
RecoveryHistoryTable, RecoveryHistoryItemFilter, RecoveryPointDetails,
useRecoveryHistorySectionState, and features/recovery/useRecoverySurfaceState
have no live consumer post-migration — each was only reachable through
the retired /recovery route.

Drops the orphan files, their test files, and the guardrail assertions
in frontendResourceTypeBoundaries / PageControls / SharedPrimitives /
TypeColumn that exercised the dead surface. Recovery-related utility
modules (recoveryRecordPresentation, recoveryArtifactModePresentation,
recoveryTablePresentation, etc.) remain — they are still consumed by
the per-platform recovery integrations (Proxmox backups, etc.) and are
not part of the dead aggregate surface.

Updates a separate PageControls guardrail array to add the
AgentsMachinesTable ColumnPicker consumer that landed in the Standalone
rename series but wasn't reflected in the test's allowlist.
2026-05-26 15:27:50 +01:00
rcourtman 94757c7539 Convert Alerts history to FilterBar with URL-backed filter state
Replaces the legacy PageControls + LabeledFilterSelect surface in
AlertHistoryFiltersCard with the canonical FilterBar. Moves timeFilter,
severityFilter, and searchTerm from usePersistentSignal/createSignal to
URL query params (period, severity, q), so SavedViews can capture and
restore the full filter shape via savedViewsKey="alerts-history". Default
values (period=7d, severity=all, q=empty) drop from the URL to keep
links clean.

On first mount, useAlertHistoryState migrates any legacy
alertHistoryTimeFilter / alertHistorySeverityFilter localStorage values
into the URL once, then defers to the URL going forward. The dead
localStorage keys remain in place; harmless and avoids a custom eviction
migration. Drops filtersOpen / setFiltersOpen from the public API now
that FilterBar owns its own mobile expand state.
2026-05-26 14:10:23 +01:00
rcourtman e6e235a25a Wire SavedViews into Storage with platform-scoped key
StoragePageControls now accepts a savedViewsKey prop that toggles the
SavedViews menu in its FilterBar. Storage.tsx computes the key from the
platform context: standalone /storage uses the bare "storage" key, while
a platform-embedded storage tab (forcedSourceFilter set) gets its own
scope (storage-<platform>) so saved queries from one surface do not
leak into another. All Storage filter, sort, group, and node state is
already URL-backed via useStorageRouteState, so adding the menu picks up
the full view shape without further state migration.
2026-05-26 14:00:19 +01:00
rcourtman 47e0564ca1 Add version, default-view, and isDefault to saved view schema
Extends the SavedView primitive ahead of rolling SavedViews into pages
beyond Recovery. version pins forward compatibility so future changes to
filter URL encoding can migrate or reject old entries; reads tolerate
missing version by treating entries as v1. isDefault lets the user mark
one view per savedViewsKey as the default, with a star toggle in
SavedViewsMenu. useSavedViews auto-applies the default on mount when the
URL carries no query, using history replace to avoid bouncing against
the empty-query state.
2026-05-26 13:51:00 +01:00