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.
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.
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
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.
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.
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.
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).
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.
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.
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.
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.
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
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.
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.
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
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.
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.