Commit graph

4963 commits

Author SHA1 Message Date
rcourtman
00da144dd8 Remove v6 RC banner from app shell 2026-04-17 20:06:57 +01:00
rcourtman
4e4fcb5dbe Move operations tools into settings support 2026-04-17 20:03:54 +01:00
rcourtman
3a5f36da19 Retain tab data across recovery and patrol revisits 2026-04-17 19:38:43 +01:00
rcourtman
deb701e340 Align patrol page shell with utility header stack 2026-04-17 19:11:53 +01:00
rcourtman
2d0784ca61 Stabilize recovery and patrol tab loading shells 2026-04-17 19:10:06 +01:00
rcourtman
df06fe84b2 Normalize alerts and patrol page headers 2026-04-17 18:47:02 +01:00
rcourtman
50a7d73293 Add workloads column layout regression 2026-04-17 18:35:34 +01:00
rcourtman
2f8a91d7a6 Rebalance runtime table columns 2026-04-17 18:10:00 +01:00
rcourtman
14b092ce9e frontend: drop PageHeader from Dashboard/Infrastructure/Storage/Ceph
The title-only header still cost vertical space without adding signal.
These surfaces already identify themselves via the left nav tab state,
so the in-page heading was pure chrome. Remove the PageHeader import
and element on each of the four pages that still carried it.

Patrol retains its header because it hosts active controls; Alerts
retains SectionHeader because it orients between sibling tabs.
2026-04-17 18:03:14 +01:00
rcourtman
393521f5eb Strip explanatory subtitles from Ceph, Patrol, and Alerts headers
Follow-up to fc019780c. Ceph and the Patrol intelligence header carried
the same "let me narrate what this page does" blurbs under their titles;
Alerts routed five tab-specific descriptions through
getAlertsPageHeaderMeta().

Removed the Ceph and Patrol description props, dropped the description
field from each entry in getAlertsPageHeaderMeta() (and the six unused
ALERTS_PAGE_*_DESCRIPTION constants), and pared the Alerts SectionHeader
usage to title-only. Test updated to match.
2026-04-17 17:57:32 +01:00
rcourtman
fc019780ce Strip explanatory subtitles from primary page headers
Dashboard, Infrastructure, and Storage carried descriptive blurbs under
their titles ("Monitor fleet health...", "Inspect discovered systems...",
"Track capacity..."). They read like onboarding copy, not header text on
a working monitoring tool. Removed.

PageHeader.description is already optional; the three surfaces now render
with just the title.

Refs #1429 RC2 feedback tone
2026-04-17 17:54:46 +01:00
rcourtman
865fa45ff2 Resolve patrol-product-language-ai-boundary decision
Audit of customer-facing Patrol surfaces against the patrol-intelligence
contract (obligation #5) confirms the migration boundary:

- Customer chrome (page titles, nav, route labels, summary copy, actions,
  empty states) leads with Patrol/Pulse Patrol/Pulse Assistant
- Internal identifiers (file names, stores, types, transport fields,
  log tags) stay under the shared AI-runtime carve-out
- `/settings/system-ai` is the provider/configuration carve-out where
  AI terminology is reserved; its chrome is already product-first
  ("Assistant & Patrol")
- The AgentProfilesPanel "Ideas" tooltip was the last customer-facing
  surface outside those carve-outs and was neutralized in the prior
  commit

With the boundary documented, the only release-ready blocker is RA8
(rc-to-ga-promotion-readiness), which is held intentionally for the
governed RC-to-GA rehearsal.
2026-04-17 16:39:49 +01:00
rcourtman
bece20e7b4 Neutralize AI-branded tooltip on agent profile suggestions
The AgentProfilesPanel "Ideas" button was the last customer-facing
surface outside the `/settings/system-ai` provider panel still leading
with generic "AI" branding. Swap the tooltip to describe what the
button does ("Suggest profiles for your estate"), matching the visible
"Ideas" label and the patrol-intelligence contract rule that
customer-facing chrome leads with Patrol / Pulse Assistant language
rather than generic AI copy. Internal identifiers (`aiAvailable`,
`handleSuggest`, store keys) stay under the shared AI-runtime carve-out.

Pin the new tooltip copy with a source-raw guardrail test.
2026-04-17 16:37:39 +01:00
rcourtman
ade98642a9 Align root TERMS.md with shipped docs copy
The root TERMS.md still described Pulse Pro as an "infrastructure
monitoring and AI-powered automation tool". frontend-modern/public/docs/
TERMS.md (the copy users actually see) was updated in 80d9588d4 to
"infrastructure monitoring tool with AI-assisted operations". Bring the
root file in line so the two stay in lockstep.
2026-04-17 15:47:15 +01:00
rcourtman
12b6d93a2a Realign vitest suites with canonical frontend sources
Sweep of stale assertions that hadn't caught up with intentional source
narrowing across recent Pulse v6 commits:

- InfrastructureSummary: ChartsAPI now takes a 3rd metrics arg and
  agentResources reads from props; update call-expectation args and pass
  linked agents via resources.
- useStoragePageFilters: navigate() now uses the shared
  ROUTE_STATE_REPLACE_OPTIONS ({ replace: true, scroll: false }).
- useStoragePageControlsModel: 'type' is a valid StorageSortKey.
- storagePageStatus / storagePagePresentation: banner gate requires
  !connected; table columns dropped to 8 labels.
- infrastructurePageModel: status vocabulary maps 'degraded' -> 'Degraded'.
- dashboardWorkloadUrlSyncModel: parsed params now include summaryGroup.
- UnifiedResourceTable workloads-link: k8s hrefs include
  platform=kubernetes.
- RecoverySummary: match locale-independent 'Mar 9' / '9 Mar'.
- recoveryCanonicalVocabulary: selectedHistoryItemLabel memo moved to
  useRecoverySurfaceState; prop lives on RecoveryHistorySection.
- TypeColumn.guardrails: recovery now uses createVisibleCanonicalTypeColumn.
- WebInterfaceUrlField: canonical fallback title is 'No suggested URL
  available' (from getDiscoverySuggestedURLFallback).
- DeployingStep: DeployStatusBadge no longer carries role=status; assert
  badge label text instead.
- PreflightStep: empty-targets case deliberately shows 'Checking 0 of 0
  nodes...' rather than declaring complete.
- licensePresentation: self-hosted billing copy updated upstream.

No source changes; full suite green (5489 tests, 578 files).
2026-04-17 15:46:45 +01:00
rcourtman
29d0e87dc7 Fix FindingsPanel.links test drift on remediation-plan store surface
The aiIntelligenceStore mock was missing the remediationPlans getter and
loadRemediationPlans function that FindingsPanel.tsx added since the
test was last touched, so the only case in this suite was throwing
'aiIntelligenceStore.remediationPlans is not iterable' on mount and
failing before any assertion ran.
2026-04-17 14:58:18 +01:00
rcourtman
a2bd85d806 Bump dompurify 3.3.3 -> 3.4.0 to clear GHSA-39q2-94rc-95cp
The advisory covers an ADD_TAGS form bypass of FORBID_TAGS. Pulse uses
an ALLOWED_TAGS allowlist in frontend-modern/src/components/AI/aiChatUtils.ts
and never combines ADD_TAGS with FORBID_TAGS, so we were not actually
exposed, but staying on the patched line keeps the Dependabot surface
clean.
2026-04-17 14:55:58 +01:00
rcourtman
85191a9051 Remove blanket Community-visible upgrade marketing surfaces
Cut three surfaces that nagged Community users without explicit feature
engagement: the Dashboard RelayOnboardingCard paywall, the app-wide
ActiveUseTrialNudge (already dead code with no render sites), and the
SetupCompletionPanel "Monitor from Anywhere" Relay trial block.

Feature-gated discovery that fires only when a user clicks a locked
feature (alert investigate, history ranges, Patrol AI modes, Settings
panels) is intentionally left alone — those are user-initiated, not
blanket funnels.

Governance cascade: cloud-paid.md extends the Settings no-funnel rule
to Dashboard and setup completion; registry.json, status.json readiness
assertions RA5/RA18, frontend-primitives/storage-recovery/
performance-and-scalability contracts, the high-risk verification
matrix, the relay registration proof script, the subsystem lookup
tests, and the obsolete integration spec are all scrubbed of
references to the removed files. Blocked-record regenerated against
current VERSION=6.0.0-rc.2 so the promotion-policy test no longer
diffs on a stale rc.1 artifact.
2026-04-17 14:49:28 +01:00
rcourtman
d35762b029 Remove Community-user upgrade CTAs from Settings plan page
Settings -> Plan was funneling Community users through marketing:
the monitored-system upgrade arrival banner (which triggered
license-server portal handoffs that emsofo hit as "Pulse Account
unavailable"), the trial-start CTA, the inactive-Pro upsell, and
the capacity-section Upgrade button all rendered unsolicited for
users without paid features.

Plan page now shows factual license state only for Community
users. Trial starting is still reachable from other entry points
(dashboard onboarding, patrol). Contract updated to forbid
regression. Dashboard-level nags remain; inventory pending.
2026-04-17 14:18:06 +01:00
rcourtman
943389827f Scrub stale monitored-system caps on self-hosted uncapped tiers
v5-migrated installations can persist a legacy max_monitored_systems value
(e.g. Community=1) in the license claims. After 5914a4127 made all
self-hosted tiers uncapped, EffectiveLimits() only scrubbed Lifetime and
v5-grandfathered Pro, so migrated Community / Pro / Relay installs kept
emitting the old cap and the "Over plan" banner still rendered on rc.2.

Extend the scrub to every self-hosted tier whose TierMonitoredSystemLimits
entry is 0, and stop monitoredSystemContinuityStatusLocked() from falling
back to the grant's plan limit when the license says uncapped. 0 is now
a first-class "unlimited" signal, not a missing-data sentinel.

The grandfather-floor continuity is still captured for audit, but no
longer enforces on self-hosted tiers. Cloud and MSP limit resolution is
untouched.

Refs #1429
2026-04-17 13:52:02 +01:00
rcourtman
6fced072d3 Clarify trend empty-state copy on Infrastructure summary
Swap the Infrastructure summary's placeholder strings so users see that
Pulse is actively accumulating data rather than a static empty/waiting
state:

- 'Waiting for first sample' -> 'Gathering first sample…'
- 'No history yet' -> 'Building trend history…'

Both strings are rendered in tight slots (56px sparkline card, 11px
pill) — the new copy is the same length class but signals ongoing
progress. No behavior change; Storage and Workloads summaries keep
their own wording.
2026-04-17 12:49:25 +01:00
rcourtman
675c47d971 Add contract-neutral bypass to staged shape guard
Introduce PULSE_ALLOW_CONTRACT_NEUTRAL_COMMIT as a narrow escape
hatch for the canonical-shape block in staged_commit_shape_guard
and canonical_completion_guard. A non-empty reason logs to stderr
for audit and suppresses only the canonical-shape requirements;
lane-progress, promotion-proof, sensitivity, gitleaks,
governance-stage, control-plane, status, registry, and contract
audits still run. Previously a behavioral bug fix on a canonical
runtime path demanded full contract + verification ceremony even
when no public-contract delta existed, forcing --no-verify.
2026-04-17 12:24:01 +01:00
rcourtman
f2d5892aa5 Skip onboarding overflow bonus on uncapped plans
The free-tier onboarding overflow adds +1 to MaxMonitoredSystems for 14
days after initial setup. Once rc.2 made self-hosted core monitoring
uncapped (MaxMonitoredSystems = 0 on Free), the bonus math silently
converted "unlimited" into a hard cap of 1 — the UI then surfaced
"Over plan by N. N monitored, 1 included." on healthy installs.

Guard the addition on limit > 0 at all three call sites (ledger path,
commercial entitlement payload, runtime capabilities payload) so the
bonus only extends plans that actually have a cap.

Refs #1429
2026-04-17 12:16:03 +01:00
rcourtman
80d9588d49 Remove unimplemented white-label claims and fix TOS product description
White-label branding was advertised as a Cloud Enterprise feature in
docs/CLOUD.md and docs/PULSE_PRO.md while the underlying capability is
still marked "not implemented" in features.go. Pulled from the customer-
facing matrix and prose so we are not selling a vapor feature.

TERMS.md described Pulse Pro as "infrastructure monitoring and AI-powered
automation" — narrowed to "infrastructure monitoring tool with AI-assisted
operations" so the legal document matches the product's actual posture.

Also trimmed the Pro row subtitle in the self-hosted pricing table to
drop "automation" since the AI autonomy surface is framed as assistance
with approval, not automated operations.
2026-04-17 10:50:00 +01:00
rcourtman
6ec64c55ed Fix stale v6-rc-cut active-target reference in control-plane doc
The `Current State` section of `docs/release-control/internal/CONTROL_PLANE.md`
still described `v6-rc-cut` as the active engineering target and listed
`v6-rc-stabilization` as planned. The active target has been
`v6-rc-stabilization` since the first governed RC shipped, and
`documentation_currentness_test` now fails on that drift. Update items 2, 4,
and 5 to match the current governed state.
2026-04-16 22:57:37 +01:00
rcourtman
b19991f4ae Fix published release body rendering 2026-04-16 22:20:17 +01:00
rcourtman
6fcdcf8b8e Add pre-release Helm chart smoke gate 2026-04-16 21:48:35 +01:00
rcourtman
f2746960d6 Relax mounted storage-root hardening semantics 2026-04-16 21:37:11 +01:00
rcourtman
96822b20f7 Auto-update Helm chart documentation 2026-04-16 20:26:48 +00:00
rcourtman
9855973e5b Fix non-root storage hardening for Helm startup 2026-04-16 21:26:02 +01:00
rcourtman
0db5d2e4c3 Auto-update Helm chart version to 6.0.0-rc.2 2026-04-16 20:06:24 +00:00
rcourtman
450de1835e Auto-update Helm chart documentation 2026-04-16 20:06:22 +00:00
rcourtman
d1a807e9c5 Fix Helm release-line branch fidelity and smoke diagnostics 2026-04-16 21:05:11 +01:00
rcourtman
447280a0ce Fix release-line demo workflow dispatch and verification 2026-04-16 20:54:01 +01:00
rcourtman
2868b44cf9 chore(release): bump version to 6.0.0-rc.2 2026-04-16 16:22:27 +01:00
rcourtman
596bcfb5e8 Make release candidate banner rc-version agnostic 2026-04-16 16:15:31 +01:00
rcourtman
7c1c5d396a Own mock runtime fixtures under monitoring 2026-04-16 16:00:23 +01:00
rcourtman
16d86ac094 Own VERSION under deployment-installability 2026-04-16 15:31:42 +01:00
rcourtman
d1600d5ef1 Own prerelease feedback intake under deployment-installability 2026-04-16 15:18:46 +01:00
rcourtman
92d1b22fb1 Own upgrade guide under deployment-installability 2026-04-16 15:06:54 +01:00
rcourtman
954a7c06c7 Tighten rc release packet runbook 2026-04-16 14:57:07 +01:00
rcourtman
78c5107b47 Own release packet docs under deployment-installability 2026-04-16 14:52:30 +01:00
rcourtman
f29104d693 Draft rc2 changelog packet 2026-04-16 14:45:14 +01:00
rcourtman
02194a237e Draft rc2 release notes packet 2026-04-16 12:22:03 +01:00
rcourtman
76bbf16105 Lock self-hosted paid extras packaging 2026-04-16 12:15:06 +01:00
rcourtman
59d320d1d4 Fix Proxmox settings route selection
Refs #1423
2026-04-16 12:03:31 +01:00
rcourtman
d0a60e1a92 Fix pulse-agent version exit handling
Refs #1424
2026-04-16 11:54:47 +01:00
rcourtman
df34b1715b Update migration proof for uncapped self-hosted plans
Refs #1409
2026-04-16 11:23:52 +01:00
rcourtman
36cb1d34d7 Mark capped self-hosted lock as historical
Refs #1409
2026-04-16 11:20:50 +01:00
rcourtman
4e34fab7ae Remove stale cap framing from uncapped self-hosted plans
Refs #1409
2026-04-16 11:17:07 +01:00