This is an automated email from the ASF dual-hosted git repository.

zqr10159 pushed a commit to branch 2.0.0
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git

commit cddb70aa561ceffca58652b8cb467a43a49d6235
Author: Logic <[email protected]>
AuthorDate: Fri May 29 01:51:04 2026 +0800

    feat(web-next): close dashboard route catalog parity
---
 .../app/compatibility-entrypoints.chrome.test.ts   |  48 ++++++---
 web-next/app/dashboard/page.test.ts                |  66 +++++++-----
 web-next/app/dashboard/page.tsx                    |  13 ++-
 web-next/app/entity-detail-family.chrome.test.ts   |   4 +-
 web-next/app/entity-editor-family.chrome.test.ts   |  36 +++++--
 .../app/milestone4-auth-settings.chrome.test.ts    |  38 ++++---
 .../milestone5-shared-route-owners.chrome.test.ts  |  45 ++++----
 web-next/app/monitor-family.chrome.test.ts         |  63 ++++++-----
 web-next/app/monitor-route-ownership.test.ts       |  37 ++++---
 web-next/app/operator-family.chrome.test.ts        |  34 +++---
 web-next/app/page.test.ts                          |  40 ++++++-
 web-next/app/page.tsx                              |  12 ++-
 web-next/app/settings-family.chrome.test.ts        |  11 +-
 web-next/app/three-signal-family.chrome.test.ts    |  21 ++--
 web-next/lib/dashboard/navigation.test.ts          |   6 +-
 web-next/lib/dashboard/navigation.ts               |   6 +-
 web-next/lib/nav.test.ts                           |   4 +-
 web-next/lib/nav.ts                                |  32 +++---
 web-next/lib/parity/route-manifest.json            | 115 +++++++++++---------
 web-next/lib/parity/route-manifest.test.ts         | 116 +++++++++++++--------
 web-next/lib/workspace-navigation.test.ts          |   6 +-
 21 files changed, 465 insertions(+), 288 deletions(-)

diff --git a/web-next/app/compatibility-entrypoints.chrome.test.ts 
b/web-next/app/compatibility-entrypoints.chrome.test.ts
index f0c73988a3..f8bfc7a0ad 100644
--- a/web-next/app/compatibility-entrypoints.chrome.test.ts
+++ b/web-next/app/compatibility-entrypoints.chrome.test.ts
@@ -16,37 +16,51 @@ describe('compatibility entrypoint posture', () => {
     const logIntegrationSource = readFileSync(resolve(process.cwd(), 
'app/log/integration/page.tsx'), 'utf8');
     const logIntegrationSourceAlias = readFileSync(resolve(process.cwd(), 
'app/log/integration/[source]/page.tsx'), 'utf8');
 
-    expect(dashboardSource).toContain("from '../overview/page'");
-    expect(dashboardSource).not.toContain('buildDashboardCompatRouteUrl');
-    expect(dashboardSource).not.toContain('redirect(');
-    expect(alertsSource).toContain('AlertCenterPage');
-    expect(alertCenterSource).toContain("from 
'../../../lib/compat/search-params'");
-    expect(eventsSource).toContain("from '../log/manage/log-manage-page'");
-    expect(eventsSource).toContain('forcedView="explorer"');
-    expect(loginSource).toContain("from '../../lib/compat/search-params'");
-    expect(statusPublicSource).toContain("from 
'../../../lib/compat/search-params'");
-    expect(settingSource).toContain("from '../../lib/compat/search-params'");
-    expect(settingSettingsSource).toContain("from 
'../../../lib/compat/search-params'");
+    expect(dashboardSource).toContain('buildDashboardCompatRouteUrl');
+    expect(dashboardSource).toContain('redirect(');
+    expect(dashboardSource).not.toContain("from '../overview/page'");
+    expect(alertsSource).toContain('buildAlertCompatRouteUrlFromSearchParams');
+    expect(alertsSource).not.toContain('createCompatSearchParamReader');
+    expect(alertsSource).toContain('redirect(');
+    
expect(alertCenterSource).toContain('buildAlertCompatRouteUrlFromSearchParams');
+    expect(alertCenterSource).not.toContain("from 
'../../../lib/compat/search-params'");
+    expect(eventsSource).toContain('buildLogCompatRouteUrlFromSearchParams');
+    expect(eventsSource).not.toContain('createCompatSearchParamReader');
+    expect(eventsSource).toContain("view: 'list'");
+    expect(eventsSource).toContain('redirect(');
+    expect(loginSource).toContain('buildLoginCompatRouteUrl');
+    expect(loginSource).not.toContain("from '../../lib/compat/search-params'");
+    expect(statusPublicSource).toContain('buildPublicStatusCompatRouteUrl');
+    expect(statusPublicSource).not.toContain("from 
'../../../lib/compat/search-params'");
+    expect(settingSource).toContain('buildSettingsCompatRouteUrl');
+    expect(settingSource).not.toContain("from 
'../../lib/compat/search-params'");
+    expect(settingSettingsSource).toContain('buildSettingsCompatRouteUrl');
+    expect(settingSettingsSource).not.toContain("from 
'../../../lib/compat/search-params'");
     expect(alertsSource).not.toContain('function createSearchParamReader');
-    expect(alertsSource).not.toContain('redirect(');
+    expect(alertsSource).not.toContain("from '../alert/page'");
     expect(eventsSource).not.toContain('function createSearchParamReader');
-    expect(eventsSource).not.toContain('redirect(');
+    expect(eventsSource).not.toContain("from '../log/manage/log-manage-page'");
+    expect(eventsSource).not.toContain('forcedView="explorer"');
     expect(loginSource).not.toContain('function buildSearchParams');
     expect(alertCenterSource).not.toContain("redirect('/alert')");
     expect(statusPublicSource).not.toContain("redirect('/status')");
     expect(settingSource).not.toContain("redirect('/setting/settings')");
     
expect(settingSettingsSource).not.toContain("redirect('/setting/settings/config')");
-    
expect(logStreamSource).toContain('data-log-stream-surface="angular-log-stream"');
-    
expect(logStreamSource).toContain('data-log-stream-toolbar="angular-actions"');
+    
expect(logStreamSource).toContain('data-log-stream-canonical-live-route="log-manage-stream"');
+    expect(logStreamSource).toContain('forcedView="stream"');
+    expect(logStreamSource).toContain('showViewToggle={false}');
+    
expect(logStreamSource).not.toContain('data-log-stream-surface="angular-log-stream"');
+    
expect(logStreamSource).not.toContain('data-log-stream-toolbar="angular-actions"');
     expect(logStreamSource).not.toContain('buildLogCompatRouteUrl');
     expect(logStreamSource).not.toContain('redirect(');
-    expect(logStreamSource).not.toContain('LogManagePage');
+    expect(logStreamSource).toContain('LogManagePage');
     expect(logIntegrationSource).toContain('buildLogIntegrationIngestionHref');
     expect(logIntegrationSource).toContain('createSearchParamReader');
     expect(logIntegrationSource).toContain('redirect(');
     expect(logIntegrationSource).not.toContain('LogIntegrationRedirectShell');
     
expect(logIntegrationSourceAlias).toContain('buildLogIntegrationIngestionHref');
-    
expect(logIntegrationSourceAlias).toContain('createSearchParamReader(resolvedSearchParams,
 resolved.source)');
+    
expect(logIntegrationSourceAlias).toContain('createSearchParamReader(resolvedSearchParams)');
+    expect(logIntegrationSourceAlias).not.toContain('resolved.source');
     expect(logIntegrationSourceAlias).toContain('redirect(');
   });
 });
diff --git a/web-next/app/dashboard/page.test.ts 
b/web-next/app/dashboard/page.test.ts
index 0b6750d3b9..5953ebb831 100644
--- a/web-next/app/dashboard/page.test.ts
+++ b/web-next/app/dashboard/page.test.ts
@@ -1,34 +1,48 @@
-import React from 'react';
-import { readFileSync } from 'node:fs';
-import { resolve } from 'node:path';
-import { renderToStaticMarkup } from 'react-dom/server';
 import { describe, expect, it, vi } from 'vitest';
 
-vi.mock('../overview/page', () => ({
-  default: () =>
-    React.createElement(
-      'main',
-      { 'data-workspace-shell': 'true' },
-      React.createElement('aside', null, '总览 rail'),
-      React.createElement('section', { 'data-overview-status-grid': 'true' }, 
'工作区状态'),
-      React.createElement('section', { 'data-overview-guidance': 'true' }, 
'下一步:先接入一条可用信号链路'),
-      React.createElement('button', null, '刷新')
-    )
+const redirect = vi.fn();
+
+vi.mock('next/navigation', () => ({
+  redirect
 }));
 
 describe('dashboard alias route', () => {
-  it('renders the overview workspace directly instead of a redirect-only 
shell', async () => {
-    const source = readFileSync(resolve(process.cwd(), 
'app/dashboard/page.tsx'), 'utf8');
+  it('redirects dashboard compatibility traffic to the overview workbench', 
async () => {
+    redirect.mockImplementation((target: string) => {
+      throw new Error(`redirect:${target}`);
+    });
+
+    const { default: DashboardAliasPage } = await import('./page');
+
+    await expect(DashboardAliasPage({ searchParams: Promise.resolve({}) 
})).rejects.toThrow('redirect:/overview');
+    expect(redirect).toHaveBeenCalledWith('/overview');
+  });
+
+  it('preserves machine route context and strips display labels when 
redirecting dashboard aliases', async () => {
+    redirect.mockImplementation((target: string) => {
+      throw new Error(`redirect:${target}`);
+    });
+
     const { default: DashboardAliasPage } = await import('./page');
-    const html = renderToStaticMarkup(React.createElement(DashboardAliasPage));
-
-    expect(html).toContain('data-workspace-shell="true"');
-    expect(html).toContain('data-overview-status-grid="true"');
-    expect(html).toContain('data-overview-guidance="true"');
-    expect(html).toContain('下一步:先接入一条可用信号链路');
-    expect(html).toContain('刷新');
-    expect(source).toContain("from '../overview/page'");
-    expect(source).not.toContain('redirect(');
-    expect(source).not.toContain('buildDashboardCompatRouteUrl');
+
+    await expect(
+      DashboardAliasPage({
+        searchParams: Promise.resolve({
+          start: '10',
+          end: '20',
+          entityId: '7',
+          entityName: 'checkout',
+          returnTo: '/monitors?returnLabel=Monitors',
+          returnLabel: 'Monitors',
+          serviceName: 'checkout',
+          environment: ['prod', 'staging']
+        })
+      })
+    ).rejects.toThrow(
+      
'redirect:/overview?start=10&end=20&entityId=7&entityName=checkout&returnTo=%2Fmonitors&serviceName=checkout&environment=prod'
+    );
+    expect(redirect).toHaveBeenLastCalledWith(
+      
'/overview?start=10&end=20&entityId=7&entityName=checkout&returnTo=%2Fmonitors&serviceName=checkout&environment=prod'
+    );
   });
 });
diff --git a/web-next/app/dashboard/page.tsx b/web-next/app/dashboard/page.tsx
index 9ac6b44075..52b18c7da2 100644
--- a/web-next/app/dashboard/page.tsx
+++ b/web-next/app/dashboard/page.tsx
@@ -1,6 +1,11 @@
-import React from 'react';
-import OverviewPage from '../overview/page';
+import { redirect } from 'next/navigation';
+import { buildDashboardCompatRouteUrl, type SearchParamsRecord } from 
'../../lib/dashboard/navigation';
 
-export default function DashboardAliasPage() {
-  return <OverviewPage />;
+export default async function DashboardAliasPage({
+  searchParams
+}: {
+  searchParams?: Promise<SearchParamsRecord>;
+}) {
+  const resolvedSearchParams = await searchParams;
+  redirect(buildDashboardCompatRouteUrl(resolvedSearchParams));
 }
diff --git a/web-next/app/entity-detail-family.chrome.test.ts 
b/web-next/app/entity-detail-family.chrome.test.ts
index b81c4ed180..f0de789536 100644
--- a/web-next/app/entity-detail-family.chrome.test.ts
+++ b/web-next/app/entity-detail-family.chrome.test.ts
@@ -4,7 +4,7 @@ import { describe, expect, it } from 'vitest';
 
 describe('entity detail family cold-workbench chrome', () => {
   it('removes the remaining legacy white-on-black chrome from the current 
entity slice', () => {
-    const detailSource = readFileSync(resolve(process.cwd(), 
'app/entities/[entityId]/page.tsx'), 'utf8');
+    const detailSource = readFileSync(resolve(process.cwd(), 
'app/entities/[entityId]/entity-detail-page.tsx'), 'utf8');
     const definitionSource = readFileSync(resolve(process.cwd(), 
'components/pages/entity-definition-workspace-surface.tsx'), 'utf8');
 
     expect(detailSource).not.toContain('text-white/55');
@@ -21,7 +21,7 @@ describe('entity detail family cold-workbench chrome', () => {
   });
 
   it('adopts shared ops tokens across the current entity slice', () => {
-    const detailSource = readFileSync(resolve(process.cwd(), 
'app/entities/[entityId]/page.tsx'), 'utf8');
+    const detailSource = readFileSync(resolve(process.cwd(), 
'app/entities/[entityId]/entity-detail-page.tsx'), 'utf8');
     const detailSurfaceSource = readFileSync(resolve(process.cwd(), 
'components/pages/entity-detail-surface.tsx'), 'utf8');
     const definitionSource = readFileSync(resolve(process.cwd(), 
'components/pages/entity-definition-workspace-surface.tsx'), 'utf8');
 
diff --git a/web-next/app/entity-editor-family.chrome.test.ts 
b/web-next/app/entity-editor-family.chrome.test.ts
index 8dd0167710..1bb39b245c 100644
--- a/web-next/app/entity-editor-family.chrome.test.ts
+++ b/web-next/app/entity-editor-family.chrome.test.ts
@@ -7,7 +7,7 @@ describe('entity editor family cold-workbench chrome', () => {
     const editorRowsSource = readFileSync(resolve(process.cwd(), 
'components/observability/editor-rows.tsx'), 'utf8');
     const monitorEditorSource = readFileSync(resolve(process.cwd(), 
'components/pages/monitor-editor-surface.tsx'), 'utf8');
     const entityEditorSource = readFileSync(resolve(process.cwd(), 
'components/pages/entity-editor-surface.tsx'), 'utf8');
-    const entitiesSource = readFileSync(resolve(process.cwd(), 
'app/entities/page.tsx'), 'utf8');
+    const entitiesSource = readFileSync(resolve(process.cwd(), 
'app/entities/entity-list-page.tsx'), 'utf8');
 
     expect(editorRowsSource).not.toContain('border-white/10');
     expect(editorRowsSource).not.toContain('bg-black/20');
@@ -56,9 +56,11 @@ describe('entity editor family cold-workbench chrome', () => 
{
 
   it('adopts shared ops tokens across the shared editor slice', () => {
     const editorRowsSource = readFileSync(resolve(process.cwd(), 
'components/observability/editor-rows.tsx'), 'utf8');
+    const workbenchPrimitivesSource = readFileSync(resolve(process.cwd(), 
'components/workbench/primitives.tsx'), 'utf8');
+    const workbenchPageSource = readFileSync(resolve(process.cwd(), 
'components/workbench/workbench-page.tsx'), 'utf8');
     const monitorEditorSource = readFileSync(resolve(process.cwd(), 
'components/pages/monitor-editor-surface.tsx'), 'utf8');
     const entityEditorSource = readFileSync(resolve(process.cwd(), 
'components/pages/entity-editor-surface.tsx'), 'utf8');
-    const entitiesSource = readFileSync(resolve(process.cwd(), 
'app/entities/page.tsx'), 'utf8');
+    const entitiesSource = readFileSync(resolve(process.cwd(), 
'app/entities/entity-list-page.tsx'), 'utf8');
 
     expect(editorRowsSource).toContain('border-[var(--ops-border-color)]');
     expect(editorRowsSource).toContain('bg-[var(--ops-surface-panel)]');
@@ -66,11 +68,19 @@ describe('entity editor family cold-workbench chrome', () 
=> {
     expect(editorRowsSource).toContain('text-[var(--ops-text-secondary)]');
     expect(editorRowsSource).toContain('hover:bg-[var(--ops-surface-hover)]');
 
-    expect(monitorEditorSource).toContain('border-[var(--ops-border-color)]');
-    expect(monitorEditorSource).toContain('bg-[var(--ops-surface-panel)]');
-    expect(monitorEditorSource).toContain('text-[var(--ops-text-primary)]');
-    expect(monitorEditorSource).toContain('text-[var(--ops-text-secondary)]');
-    expect(monitorEditorSource).toContain('text-[var(--ops-text-tertiary)]');
+    expect(monitorEditorSource).toContain('HzMonitorEditorForm');
+    expect(monitorEditorSource).toContain('HzMonitorEditorHeader');
+    expect(monitorEditorSource).toContain('HzMonitorEditorSection');
+    
expect(monitorEditorSource).toContain('data-monitor-editor-form-owner="hertzbeat-ui-monitor-editor-form"');
+    expect(monitorEditorSource).not.toContain('WorkbenchPage');
+    expect(monitorEditorSource).not.toContain('SurfaceSection');
+    
expect(workbenchPrimitivesSource).toContain('border-[var(--ops-border-color)]');
+    
expect(workbenchPrimitivesSource).toContain('bg-[var(--ops-surface-panel)]');
+    
expect(workbenchPrimitivesSource).toContain('text-[var(--ops-text-primary)]');
+    
expect(workbenchPrimitivesSource).toContain('text-[var(--ops-text-secondary)]');
+    expect(workbenchPageSource).toContain('divide-[var(--ops-border-color)]');
+    expect(workbenchPageSource).toContain('text-[var(--ops-text-primary)]');
+    expect(workbenchPageSource).toContain('text-[var(--ops-text-secondary)]');
 
     
expect(entityEditorSource).toContain('data-entity-editor-shell="otlp-cold-entity-composer"');
     
expect(entityEditorSource).toContain('data-entity-editor-style-baseline="hertzbeat-cold-matte"');
@@ -87,12 +97,18 @@ describe('entity editor family cold-workbench chrome', () 
=> {
   });
 
   it('keeps the active monitor/entity edit routes composed from the shared 
editor owners', () => {
-    const monitorEditSource = readFileSync(resolve(process.cwd(), 
'app/monitors/[monitorId]/edit/page.tsx'), 'utf8');
-    const entityNewSource = readFileSync(resolve(process.cwd(), 
'app/entities/new/page.tsx'), 'utf8');
-    const entityEditSource = readFileSync(resolve(process.cwd(), 
'app/entities/[entityId]/edit/page.tsx'), 'utf8');
+    const monitorEditRouteSource = readFileSync(resolve(process.cwd(), 
'app/monitors/[monitorId]/edit/page.tsx'), 'utf8');
+    const monitorEditSource = readFileSync(resolve(process.cwd(), 
'app/monitors/[monitorId]/edit/monitor-edit-page.tsx'), 'utf8');
+    const entityNewRouteSource = readFileSync(resolve(process.cwd(), 
'app/entities/new/page.tsx'), 'utf8');
+    const entityNewSource = readFileSync(resolve(process.cwd(), 
'app/entities/new/entity-new-page.tsx'), 'utf8');
+    const entityEditRouteSource = readFileSync(resolve(process.cwd(), 
'app/entities/[entityId]/edit/page.tsx'), 'utf8');
+    const entityEditSource = readFileSync(resolve(process.cwd(), 
'app/entities/[entityId]/edit/entity-edit-page.tsx'), 'utf8');
 
+    expect(monitorEditRouteSource).toContain("import MonitorEditPage from 
'./monitor-edit-page'");
     expect(monitorEditSource).toContain('MonitorEditorSurface');
+    expect(entityNewRouteSource).toContain("import EntityNewPage from 
'./entity-new-page'");
     expect(entityNewSource).toContain('EntityEditorSurface');
+    expect(entityEditRouteSource).toContain("import EntityEditPage from 
'./entity-edit-page'");
     expect(entityEditSource).toContain('EntityEditorSurface');
   });
 });
diff --git a/web-next/app/milestone4-auth-settings.chrome.test.ts 
b/web-next/app/milestone4-auth-settings.chrome.test.ts
index b28798181d..2d709b6a75 100644
--- a/web-next/app/milestone4-auth-settings.chrome.test.ts
+++ b/web-next/app/milestone4-auth-settings.chrome.test.ts
@@ -4,8 +4,8 @@ import { describe, expect, it } from 'vitest';
 
 describe('milestone 4 auth/public and settings cold-workbench chrome', () => {
   it('removes the remaining bright-shell residue from the current 
auth/settings slice', () => {
-    const passportLockSource = readFileSync(resolve(process.cwd(), 
'app/passport/lock/page.tsx'), 'utf8');
-    const settingTokenSource = readFileSync(resolve(process.cwd(), 
'app/setting/settings/token/page.tsx'), 'utf8');
+    const passportLockSource = readFileSync(resolve(process.cwd(), 
'app/passport/lock/passport-lock-page.tsx'), 'utf8');
+    const settingTokenSource = readFileSync(resolve(process.cwd(), 
'app/setting/settings/token/setting-token-page.tsx'), 'utf8');
     const combinedSource = [passportLockSource, settingTokenSource].join('\n');
 
     expect(combinedSource).not.toContain('border-white/35');
@@ -23,24 +23,30 @@ describe('milestone 4 auth/public and settings 
cold-workbench chrome', () => {
   });
 
   it('adopts shared ops owners and danger states across the current 
auth/settings slice', () => {
-    const passportLockSource = readFileSync(resolve(process.cwd(), 
'app/passport/lock/page.tsx'), 'utf8');
-    const settingTokenSource = readFileSync(resolve(process.cwd(), 
'app/setting/settings/token/page.tsx'), 'utf8');
+    const passportLockRouteSource = readFileSync(resolve(process.cwd(), 
'app/passport/lock/page.tsx'), 'utf8');
+    const passportLockSource = readFileSync(resolve(process.cwd(), 
'app/passport/lock/passport-lock-page.tsx'), 'utf8');
+    const settingTokenSource = readFileSync(resolve(process.cwd(), 
'app/setting/settings/token/setting-token-page.tsx'), 'utf8');
 
-    expect(passportLockSource).toContain('components/observability');
-    expect(passportLockSource).toContain('ObservabilityStatusState');
+    expect(passportLockRouteSource).not.toMatch(/^['"]use client['"]/);
+    expect(passportLockRouteSource).toContain("import PassportLockPage from 
'./passport-lock-page'");
+    expect(passportLockSource).toContain('HzPassportLockSurface');
+    expect(passportLockSource).toContain('PassportPanel');
     
expect(passportLockSource).not.toContain('components/workbench/primitives');
     expect(passportLockSource).toContain('border-[var(--ops-border-color)]');
-    expect(passportLockSource).toContain('bg-[var(--ops-surface-panel)]');
-    expect(passportLockSource).toContain('bg-[var(--ops-surface-raised)]');
-    expect(passportLockSource).toContain('text-[var(--ops-text-primary)]');
-    expect(passportLockSource).toContain('text-[var(--ops-text-tertiary)]');
-    expect(passportLockSource).toContain('text-[var(--ops-primary)]');
+    expect(passportLockSource).toContain('bg-[#101217]');
+    
expect(passportLockSource).toContain('data-passport-lock-panel="angular-wide"');
+    
expect(passportLockSource).toContain('data-passport-lock-panel-owner="hertzbeat-ui-passport-lock"');
 
-    expect(settingTokenSource).toContain('ObservabilityStatusState');
-    expect(settingTokenSource).toContain('StageSection');
-    expect(settingTokenSource).toContain('tone="danger"');
-    expect(settingTokenSource).toContain('DrawerCodePreview');
-    expect(settingTokenSource).toContain('SummaryMetricGrid');
+    expect(settingTokenSource).toContain('SettingsConsoleTitle');
+    expect(settingTokenSource).toContain('coldOpsCatalogVisual');
+    
expect(settingTokenSource).toContain('data-setting-token-table-panel="cold-dense-table"');
+    
expect(settingTokenSource).toContain('data-setting-token-strip-style="cold-inline-counts"');
+    
expect(settingTokenSource).toContain('data-setting-token-row-action="cold-row-action"');
+    expect(settingTokenSource).toContain('text-[#fca5a5]');
+    expect(settingTokenSource).not.toContain('ObservabilityStatusState');
+    expect(settingTokenSource).not.toContain('StageSection');
+    expect(settingTokenSource).not.toContain('DrawerCodePreview');
+    expect(settingTokenSource).not.toContain('SummaryMetricGrid');
     expect(settingTokenSource).not.toContain('PayloadPreview density="compact" 
className="mt-3"');
   });
 });
diff --git a/web-next/app/milestone5-shared-route-owners.chrome.test.ts 
b/web-next/app/milestone5-shared-route-owners.chrome.test.ts
index 4499341847..ffe0d47d20 100644
--- a/web-next/app/milestone5-shared-route-owners.chrome.test.ts
+++ b/web-next/app/milestone5-shared-route-owners.chrome.test.ts
@@ -38,42 +38,47 @@ function collectNonTestAppFiles(dir: string): string[] {
 
 describe('Milestone 5 shared route owners', () => {
   it('keeps representative route entrypoints pinned to shared observability 
owners', () => {
-    const overviewSource = readFileSync(resolve(process.cwd(), 
'app/overview/page.tsx'), 'utf8');
-    const monitorsSource = readFileSync(resolve(process.cwd(), 
'app/monitors/page.tsx'), 'utf8');
+    const overviewSource = readFileSync(resolve(process.cwd(), 
'app/overview/overview-page.tsx'), 'utf8');
+    const monitorsSource = readFileSync(resolve(process.cwd(), 
'app/monitors/monitor-manage-page.tsx'), 'utf8');
     const logSource = readFileSync(resolve(process.cwd(), 
'app/log/manage/log-manage-page.tsx'), 'utf8');
-    const traceSource = readFileSync(resolve(process.cwd(), 
'app/trace/manage/page.tsx'), 'utf8');
+    const traceSource = readFileSync(resolve(process.cwd(), 
'app/trace/manage/trace-manage-page.tsx'), 'utf8');
     const alertIntegrationSource = readFileSync(resolve(process.cwd(), 
'app/alert/integration/[source]/page.tsx'), 'utf8');
-    const alertNoticeSource = readFileSync(resolve(process.cwd(), 
'app/alert/notice/page.tsx'), 'utf8');
-    const statusSource = readFileSync(resolve(process.cwd(), 
'app/status/page.tsx'), 'utf8');
+    const alertNoticeSource = readFileSync(resolve(process.cwd(), 
'app/alert/notice/alert-notice-page.tsx'), 'utf8');
+    const statusSource = readFileSync(resolve(process.cwd(), 
'app/status/status-page.tsx'), 'utf8');
     const passportSource = readFileSync(resolve(process.cwd(), 
'app/passport/login/page.tsx'), 'utf8');
 
     expect(overviewSource).toContain('StageSection');
     expect(overviewSource).toContain('SupportPanel');
     expect(overviewSource).not.toContain('components/workbench/primitives');
 
-    expect(monitorsSource).toContain('StageSection');
-    expect(monitorsSource).toContain('SummaryMetricGrid');
-    expect(monitorsSource).toContain('DrawerSection');
+    expect(monitorsSource).toContain('HzExplorerFrame');
+    expect(monitorsSource).toContain('HzDataTable');
+    
expect(monitorsSource).toContain('data-monitor-manage-shell-owner="hertzbeat-ui-explorer-frame"');
+    expect(monitorsSource).not.toContain('StageSection');
+    expect(monitorsSource).not.toContain('SummaryMetricGrid');
+    expect(monitorsSource).not.toContain('DrawerSection');
     expect(monitorsSource).not.toContain('components/workbench/primitives');
 
-    expect(logSource).toContain('FactsStrip');
-    expect(logSource).toContain('StageSection');
-    expect(logSource).toContain('DrawerSection');
-    expect(logSource).toContain('DrawerCodePreview');
+    expect(logSource).toContain('ClientWorkbench');
+    expect(logSource).toContain('TimeRangeControl');
+    
expect(logSource).toContain('data-log-manage-time-control="shared-time-context-control"');
     expect(logSource).not.toContain('components/workbench/primitives');
 
-    expect(traceSource).toContain('FactsStrip');
-    expect(traceSource).toContain('StageSection');
-    expect(traceSource).toContain('DrawerSection');
-    expect(traceSource).toContain('DrawerCodePreview');
+    expect(traceSource).toContain('ClientWorkbench');
+    expect(traceSource).toContain('TimeRangeControl');
+    expect(traceSource).toContain('ObservabilityWaterfall');
+    
expect(traceSource).toContain('data-trace-manage-time-control="shared-time-context-control"');
     expect(traceSource).not.toContain('components/workbench/primitives');
 
-    expect(alertIntegrationSource).toContain('StageSection');
-    expect(alertIntegrationSource).toContain('DrawerSection');
-    expect(alertIntegrationSource).toContain('DrawerCodePreview');
+    expect(alertIntegrationSource).toContain('AlertIntegrationMarkdown');
+    expect(alertIntegrationSource).toContain('coldOpsCatalogVisual');
+    
expect(alertIntegrationSource).toContain('data-alert-integration-surface="otlp-cold-source-doc"');
     
expect(alertIntegrationSource).not.toContain('components/workbench/primitives');
 
-    expect(alertNoticeSource).toContain('StageSection');
+    expect(alertNoticeSource).toContain('AlertNoticeConsoleShell');
+    expect(alertNoticeSource).toContain('ClientWorkbench');
+    expect(alertNoticeSource).toContain('HzConfirmDialog');
+    
expect(alertNoticeSource).toContain('data-alert-notice-surface="otlp-cold-notice-console"');
     expect(alertNoticeSource).not.toContain('components/workbench/primitives');
 
     expect(statusSource).toContain('PublicStatusShell');
diff --git a/web-next/app/monitor-family.chrome.test.ts 
b/web-next/app/monitor-family.chrome.test.ts
index 6274be92f6..78ab561df1 100644
--- a/web-next/app/monitor-family.chrome.test.ts
+++ b/web-next/app/monitor-family.chrome.test.ts
@@ -4,7 +4,7 @@ import { describe, expect, it } from 'vitest';
 
 describe('monitor family cold-workbench chrome', () => {
   it('removes the remaining legacy white-on-black chrome from the current 
monitor slice', () => {
-    const monitorsSource = readFileSync(resolve(process.cwd(), 
'app/monitors/page.tsx'), 'utf8');
+    const monitorsSource = readFileSync(resolve(process.cwd(), 
'app/monitors/monitor-manage-page.tsx'), 'utf8');
     const consoleSource = readFileSync(resolve(process.cwd(), 
'components/monitor-detail/monitor-detail-console.tsx'), 'utf8');
     const sectionsSource = readFileSync(resolve(process.cwd(), 
'components/monitor-detail/monitor-detail-sections.tsx'), 'utf8');
     const realtimeSource = readFileSync(resolve(process.cwd(), 
'components/monitor-detail/monitor-realtime-panel.tsx'), 'utf8');
@@ -40,24 +40,26 @@ describe('monitor family cold-workbench chrome', () => {
   });
 
   it('adopts shared ops tokens across the current monitor slice', () => {
-    const monitorsSource = readFileSync(resolve(process.cwd(), 
'app/monitors/page.tsx'), 'utf8');
-    const detailRouteSource = readFileSync(resolve(process.cwd(), 
'app/monitors/[monitorId]/page.tsx'), 'utf8');
+    const monitorsSource = readFileSync(resolve(process.cwd(), 
'app/monitors/monitor-manage-page.tsx'), 'utf8');
+    const detailRouteSource = readFileSync(resolve(process.cwd(), 
'app/monitors/[monitorId]/monitor-detail-page.tsx'), 'utf8');
     const consoleSource = readFileSync(resolve(process.cwd(), 
'components/monitor-detail/monitor-detail-console.tsx'), 'utf8');
     const sectionsSource = readFileSync(resolve(process.cwd(), 
'components/monitor-detail/monitor-detail-sections.tsx'), 'utf8');
     const realtimeSource = readFileSync(resolve(process.cwd(), 
'components/monitor-detail/monitor-realtime-panel.tsx'), 'utf8');
     const historySource = readFileSync(resolve(process.cwd(), 
'components/monitor-detail/monitor-history-panel.tsx'), 'utf8');
 
-    expect(monitorsSource).toContain('border-[var(--ops-border-color)]');
-    expect(monitorsSource).toContain('text-[var(--ops-text-secondary)]');
-    expect(monitorsSource).toContain('text-[var(--ops-text-tertiary)]');
-    expect(monitorsSource).toContain('SummaryMetricGrid');
-    expect(monitorsSource).toContain('StageSection');
-    
expect(monitorsSource).toContain("title={t('monitors.section.list.title')}");
-    expect(monitorsSource).toContain("DrawerSection 
title={t('monitors.rail.selected')}");
-    expect(monitorsSource).toContain("DrawerSection 
title={t('monitors.rail.labels')}");
-    expect(monitorsSource).toContain("DrawerSection 
title={t('monitors.rail.controls')}");
-    expect(monitorsSource).toContain('DrawerCodePreview');
-    expect(monitorsSource).toContain('ObservabilityStatusState');
+    expect(monitorsSource).toContain('HzExplorerFrame');
+    expect(monitorsSource).toContain('HzDataTable');
+    expect(monitorsSource).toContain('HzBatchToolbar');
+    expect(monitorsSource).toContain('HzMonitorFilterBar');
+    
expect(monitorsSource).toContain('data-monitor-manage-filter-owner="hertzbeat-ui-monitor-filter-bar"');
+    
expect(monitorsSource).toContain('data-monitor-manage-shell-owner="hertzbeat-ui-explorer-frame"');
+    expect(monitorsSource).toContain('HzStatusBadge');
+    expect(monitorsSource).not.toContain('HzWorkbenchSurface');
+    expect(monitorsSource).not.toContain('data-monitor-manage-detail-rail');
+    expect(monitorsSource).not.toContain('SummaryMetricGrid');
+    expect(monitorsSource).not.toContain('StageSection');
+    expect(monitorsSource).not.toContain('DrawerSection');
+    expect(monitorsSource).not.toContain('DrawerCodePreview');
     expect(monitorsSource).not.toContain('PayloadPreview density="compact" 
className="mt-2"');
     expect(monitorsSource).not.toContain('components/workbench/primitives');
     expect(monitorsSource).not.toContain('components/workbench/toolbar');
@@ -65,29 +67,26 @@ describe('monitor family cold-workbench chrome', () => {
     expect(detailRouteSource).toContain('MonitorDetailConsole');
     expect(detailRouteSource).toContain('MonitorDetailSections');
 
-    expect(consoleSource).toContain('border-[var(--ops-border-color)]');
-    expect(consoleSource).toContain('text-[var(--ops-text-primary)]');
-    expect(consoleSource).toContain('text-[var(--ops-text-secondary)]');
-    expect(consoleSource).toContain('text-[var(--ops-text-tertiary)]');
-    expect(consoleSource).toContain('ObservabilityControlChip');
-    expect(consoleSource).toContain('ObservabilityPillButton');
-    expect(consoleSource).toContain('ObservabilityBadge');
+    expect(consoleSource).toContain('HzMonitorDetailConsoleShell');
+    expect(consoleSource).toContain('HzMonitorDetailWorkbenchFrame');
+    
expect(consoleSource).toContain('data-monitor-detail-console-shell-owner="hertzbeat-ui-detail-console-shell"');
+    
expect(consoleSource).toContain('data-monitor-workbench-stage-owner="hertzbeat-ui-detail-workbench-frame"');
     expect(consoleSource).not.toContain("from '../workbench/primitives'");
 
-    expect(sectionsSource).toContain('border-[var(--ops-border-color)]');
-    expect(sectionsSource).toContain('bg-[var(--ops-surface-panel)]');
-    expect(sectionsSource).toContain('text-[var(--ops-text-secondary)]');
-    expect(sectionsSource).toContain('ObservabilityControlChip');
-    expect(sectionsSource).toContain('ObservabilityBadge');
+    expect(sectionsSource).toContain('HzMonitorDetailStage');
+    expect(sectionsSource).toContain('HzMonitorDetailSignalList');
+    
expect(sectionsSource).toContain('data-monitor-detail-stage-owner="hertzbeat-ui-detail-stage"');
+    
expect(sectionsSource).toContain('data-monitor-detail-signal-list-owner="hertzbeat-ui-signal-list"');
     expect(sectionsSource).not.toContain('ObservabilityInsetPanel');
     expect(sectionsSource).not.toContain("from '../workbench/primitives'");
 
-    expect(realtimeSource).toContain('border-[var(--ops-border-color)]');
-    expect(realtimeSource).toContain('bg-[var(--ops-surface-panel)]');
-    expect(realtimeSource).toContain('text-[var(--ops-text-secondary)]');
+    expect(realtimeSource).toContain('HzMonitorDetailStage');
+    expect(realtimeSource).toContain('HzMonitorRealtimeToolbar');
+    
expect(realtimeSource).toContain('data-monitor-realtime-toolbar-owner="hertzbeat-ui-realtime-toolbar"');
 
-    expect(historySource).toContain('border-[var(--ops-border-color)]');
-    expect(historySource).toContain('bg-[var(--ops-surface-panel)]');
-    expect(historySource).toContain('text-[var(--ops-text-secondary)]');
+    expect(historySource).toContain('HzMonitorDetailStage');
+    expect(historySource).toContain('HzMonitorEvidenceFrame');
+    
expect(historySource).toContain('data-monitor-history-stage-owner="hertzbeat-ui-detail-stage"');
+    
expect(historySource).toContain('data-monitor-history-chart-owner="hertzbeat-ui-echarts-panel"');
   });
 });
diff --git a/web-next/app/monitor-route-ownership.test.ts 
b/web-next/app/monitor-route-ownership.test.ts
index 3528100aaf..84909ed0ba 100644
--- a/web-next/app/monitor-route-ownership.test.ts
+++ b/web-next/app/monitor-route-ownership.test.ts
@@ -4,12 +4,16 @@ import { describe, expect, it } from 'vitest';
 
 describe('monitor route ownership posture', () => {
   it('keeps monitor list/detail/create/edit handoffs on shared navigation 
owners', () => {
-    const listSource = readFileSync(resolve(process.cwd(), 
'app/monitors/page.tsx'), 'utf8');
-    const detailSource = readFileSync(resolve(process.cwd(), 
'app/monitors/[monitorId]/page.tsx'), 'utf8');
-    const newSource = readFileSync(resolve(process.cwd(), 
'app/monitors/new/page.tsx'), 'utf8');
-    const editSource = readFileSync(resolve(process.cwd(), 
'app/monitors/[monitorId]/edit/page.tsx'), 'utf8');
+    const listRouteSource = readFileSync(resolve(process.cwd(), 
'app/monitors/page.tsx'), 'utf8');
+    const listSource = readFileSync(resolve(process.cwd(), 
'app/monitors/monitor-manage-page.tsx'), 'utf8');
+    const detailSource = readFileSync(resolve(process.cwd(), 
'app/monitors/[monitorId]/monitor-detail-page.tsx'), 'utf8');
+    const newRouteSource = readFileSync(resolve(process.cwd(), 
'app/monitors/new/page.tsx'), 'utf8');
+    const newSource = readFileSync(resolve(process.cwd(), 
'app/monitors/new/monitor-new-page.tsx'), 'utf8');
+    const editRouteSource = readFileSync(resolve(process.cwd(), 
'app/monitors/[monitorId]/edit/page.tsx'), 'utf8');
+    const editSource = readFileSync(resolve(process.cwd(), 
'app/monitors/[monitorId]/edit/monitor-edit-page.tsx'), 'utf8');
     const editorSurfaceSource = readFileSync(resolve(process.cwd(), 
'components/pages/monitor-editor-surface.tsx'), 'utf8');
 
+    expect(listRouteSource).toContain("import MonitorManagePage from 
'./monitor-manage-page'");
     expect(listSource).toContain('buildMonitorDetailHref');
     expect(listSource).toContain('buildMonitorEditHref');
     expect(listSource).toContain('buildMonitorNewHref');
@@ -20,20 +24,21 @@ describe('monitor route ownership posture', () => {
     expect(detailSource).not.toContain("from 
'@/lib/monitor-editor/navigation'");
     expect(detailSource).not.toContain('buildMonitorEditorReturnUrl');
 
-    expect(newSource).toContain('returnContext={{');
-    expect(newSource).toContain("labels: searchParams.get('labels')");
-    expect(newSource).toContain("pageIndex: searchParams.get('pageIndex')");
-    expect(newSource).toContain("pageSize: searchParams.get('pageSize')");
-    expect(newSource).toContain("entityId: searchParams.get('entityId')");
-    expect(newSource).toContain("entityName: searchParams.get('entityName')");
+    expect(newRouteSource).toContain("import MonitorNewPage from 
'./monitor-new-page'");
+    expect(newSource).toContain('returnContext={returnContext}');
+    
expect(newRouteSource).toContain('readMonitorNewRouteState(resolvedSearchParams)');
     expect(newSource).not.toContain("returnLabel: 
searchParams.get('returnLabel')");
-    expect(editSource).toContain('returnContext={{');
-    expect(editSource).toContain("labels: searchParams.get('labels')");
-    expect(editSource).toContain("pageIndex: searchParams.get('pageIndex')");
-    expect(editSource).toContain("pageSize: searchParams.get('pageSize')");
-    expect(editSource).toContain("entityId: searchParams.get('entityId')");
-    expect(editSource).toContain("entityName: searchParams.get('entityName')");
+    expect(editRouteSource).toContain("import MonitorEditPage from 
'./monitor-edit-page'");
+    expect(editSource).toContain('returnContext={returnContext}');
+    
expect(editRouteSource).toContain('readMonitorEditRouteState(resolvedSearchParams)');
     expect(editSource).not.toContain("returnLabel: 
searchParams.get('returnLabel')");
+    const queryStateSource = readFileSync(resolve(process.cwd(), 
'lib/monitor-editor/query-state.ts'), 'utf8');
+    expect(queryStateSource).toContain("labels: reader.get('labels')");
+    expect(queryStateSource).toContain("pageIndex: reader.get('pageIndex')");
+    expect(queryStateSource).toContain("pageSize: reader.get('pageSize')");
+    expect(queryStateSource).toContain("entityId: reader.get('entityId')");
+    expect(queryStateSource).toContain("entityName: reader.get('entityName')");
+    expect(queryStateSource).not.toContain("returnLabel: 
reader.get('returnLabel')");
 
     expect(editorSurfaceSource).toContain('returnContext?:');
     expect(editorSurfaceSource).toContain('...returnContext');
diff --git a/web-next/app/operator-family.chrome.test.ts 
b/web-next/app/operator-family.chrome.test.ts
index 1f272df894..6fbe9765f5 100644
--- a/web-next/app/operator-family.chrome.test.ts
+++ b/web-next/app/operator-family.chrome.test.ts
@@ -4,8 +4,8 @@ import { describe, expect, it } from 'vitest';
 
 describe('operator family cold-workbench chrome', () => {
   it('removes the remaining route-local rounded panel recipes from the OTLP 
operator slice', () => {
-    const otlpSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/page.tsx'), 'utf8');
-    const metricsSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/metrics/page.tsx'), 'utf8');
+    const otlpSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/otlp-page.tsx'), 'utf8');
+    const metricsSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/metrics/otlp-metrics-page.tsx'), 'utf8');
     const combinedSource = [otlpSource, metricsSource].join('\n');
 
     expect(combinedSource).not.toContain('rounded-[10px] 
border-[var(--ops-border-color)] bg-[var(--ops-surface-panel)] px-4 py-3 
shadow-none');
@@ -13,24 +13,26 @@ describe('operator family cold-workbench chrome', () => {
     expect(combinedSource).not.toContain('rounded-[10px] border 
border-[var(--ops-border-color)] bg-[var(--ops-surface-panel)]');
   });
 
-  it('moves the OTLP pilot route onto the new observability owner layer', () 
=> {
-    const otlpSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/page.tsx'), 'utf8');
-    const metricsSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/metrics/page.tsx'), 'utf8');
+  it('keeps the OTLP pilot route on the cold-ops catalog owner layer', () => {
+    const otlpSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/otlp-page.tsx'), 'utf8');
+    const metricsSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/metrics/otlp-metrics-page.tsx'), 'utf8');
 
-    expect(otlpSource).toContain('components/observability');
-    expect(otlpSource).toContain('FactsStrip');
-    expect(otlpSource).toContain('StageSection');
-    expect(otlpSource).toContain('SummaryMetricGrid');
-    expect(otlpSource).toContain('DrawerSection');
-    expect(otlpSource).toContain('SupportActionBar');
+    expect(otlpSource).toContain('coldOpsCatalogVisual');
+    expect(otlpSource).toContain('SearchRow');
+    expect(otlpSource).toContain('ClientWorkbench');
+    expect(otlpSource).toContain('buildReadinessRows');
+    expect(otlpSource).toContain('buildSelfCheckRows');
+    
expect(otlpSource).toContain('data-otlp-center-source-grid="hertzbeat-source-catalog"');
+    
expect(otlpSource).toContain('data-otlp-center-filter-rail="hertzbeat-prism-filters"');
     expect(otlpSource).not.toContain('components/workbench/primitives');
 
     expect(metricsSource).toContain('components/observability');
-    expect(metricsSource).toContain('FactsStrip');
-    expect(metricsSource).toContain('StageSection');
-    expect(metricsSource).toContain('SummaryMetricGrid');
-    expect(metricsSource).toContain('DrawerSection');
-    expect(metricsSource).toContain('DrawerCodePreview');
+    
expect(metricsSource).toContain('components/observability/time-range-control');
+    expect(metricsSource).toContain('EChartsPanel');
+    expect(metricsSource).toContain('ClientWorkbench');
+    expect(metricsSource).toContain('buildConsoleFacts');
+    expect(metricsSource).toContain('buildMetricsHandoffLinks');
+    
expect(metricsSource).toContain('data-otlp-metrics-route="otlp-cold-metrics-workbench"');
     expect(metricsSource).not.toContain('components/workbench/primitives');
   });
 });
diff --git a/web-next/app/page.test.ts b/web-next/app/page.test.ts
index 00fb5ab761..25f41bb891 100644
--- a/web-next/app/page.test.ts
+++ b/web-next/app/page.test.ts
@@ -1,4 +1,4 @@
-import { describe, expect, it, vi } from 'vitest';
+import { beforeEach, describe, expect, it, vi } from 'vitest';
 
 const redirect = vi.fn();
 
@@ -7,6 +7,10 @@ vi.mock('next/navigation', () => ({
 }));
 
 describe('root alias route', () => {
+  beforeEach(() => {
+    redirect.mockReset();
+  });
+
   it('redirects the shell entry point to the overview workbench', async () => {
     redirect.mockImplementation((target: string) => {
       throw new Error(`redirect:${target}`);
@@ -14,7 +18,39 @@ describe('root alias route', () => {
 
     const { default: HomePage } = await import('./page');
 
-    expect(() => HomePage()).toThrow('redirect:/overview');
+    await expect(HomePage({})).rejects.toThrow('redirect:/overview');
     expect(redirect).toHaveBeenCalledWith('/overview');
   });
+
+  it('preserves machine query context when redirecting to overview', async () 
=> {
+    redirect.mockImplementation((target: string) => {
+      throw new Error(`redirect:${target}`);
+    });
+
+    const { default: HomePage } = await import('./page');
+
+    await expect(
+      HomePage({
+        searchParams: Promise.resolve({
+          source: 'shell',
+          serviceName: 'checkout',
+          returnTo: '/monitors?returnLabel=Legacy',
+          returnLabel: 'Overview',
+          start: '1700000000000',
+          environment: ['prod', 'ignored']
+        })
+      })
+    ).rejects.toThrow('redirect:/overview?');
+
+    const target = redirect.mock.calls[0]?.[0] as string;
+    const url = new URL(target, 'http://127.0.0.1');
+
+    expect(url.pathname).toBe('/overview');
+    expect(url.searchParams.get('source')).toBe('shell');
+    expect(url.searchParams.get('serviceName')).toBe('checkout');
+    expect(url.searchParams.get('environment')).toBe('prod');
+    expect(url.searchParams.get('returnTo')).toBe('/monitors');
+    expect(url.searchParams.get('returnLabel')).toBeNull();
+    expect(url.searchParams.get('start')).toBe('1700000000000');
+  });
 });
diff --git a/web-next/app/page.tsx b/web-next/app/page.tsx
index db5e41d241..a868bb1d37 100644
--- a/web-next/app/page.tsx
+++ b/web-next/app/page.tsx
@@ -1,5 +1,13 @@
 import { redirect } from 'next/navigation';
 
-export default function HomePage() {
-  redirect('/overview');
+import { buildOverviewCompatRouteUrl, type SearchParamsRecord } from 
'../lib/overview/navigation';
+
+interface HomePageProps {
+  searchParams?: Promise<SearchParamsRecord>;
+}
+
+export default async function HomePage({ searchParams }: HomePageProps) {
+  const resolvedSearchParams = await searchParams;
+
+  redirect(buildOverviewCompatRouteUrl(resolvedSearchParams));
 }
diff --git a/web-next/app/settings-family.chrome.test.ts 
b/web-next/app/settings-family.chrome.test.ts
index a55b707919..2e7372c2be 100644
--- a/web-next/app/settings-family.chrome.test.ts
+++ b/web-next/app/settings-family.chrome.test.ts
@@ -36,7 +36,7 @@ describe('settings family cold-matte chrome', () => {
     const labelSource = readFileSync(resolve(process.cwd(), 
'components/pages/label-manage-surface.tsx'), 'utf8');
     const defineSource = readFileSync(resolve(process.cwd(), 
'components/pages/setting-define-surface.tsx'), 'utf8');
     const statusSource = readFileSync(resolve(process.cwd(), 
'components/pages/status-setting-surface.tsx'), 'utf8');
-    const tokenSource = readFileSync(resolve(process.cwd(), 
'app/setting/settings/token/page.tsx'), 'utf8');
+    const tokenSource = readFileSync(resolve(process.cwd(), 
'app/setting/settings/token/setting-token-page.tsx'), 'utf8');
 
     expect(settingsSurfaceSource).toContain('variant="flat"');
 
@@ -53,11 +53,14 @@ describe('settings family cold-matte chrome', () => {
     expect(pluginSource).not.toContain('WorkbenchTableFrame');
 
     
expect(labelSource).toContain('data-label-manage-style-baseline={coldLabelVisual.canvasName}');
-    expect(labelSource).toContain('data-label-table-shell="cold-dense-table"');
+    
expect(labelSource).toContain('data-label-card-grid-contract="angular-card-grid"');
+    
expect(labelSource).toContain('data-label-card-grid-owner="hertzbeat-ui-label-tag"');
+    
expect(labelSource).not.toContain('data-label-table-shell="cold-dense-table"');
     
expect(defineSource).toContain('data-setting-define-style-baseline={coldDefineVisual.canvasName}');
     
expect(defineSource).toContain('data-setting-define-workspace="cold-define-workspace"');
-    expect(defineSource).toContain("from '../ui/search-row'");
-    
expect(defineSource).toContain('data-setting-define-search-owner="shared-search-row"');
+    expect(defineSource).toContain('HzYamlWorkspace');
+    expect(defineSource).not.toContain("from '../ui/search-row'");
+    
expect(defineSource).not.toContain('data-setting-define-search-owner="shared-search-row"');
     expect(defineSource).not.toContain('coldDefineVisual.search.row');
     expect(defineSource).not.toContain('coldDefineVisual.search.input');
     
expect(statusSource).toContain('data-status-setting-style-baseline={coldStatusVisual.canvasName}');
diff --git a/web-next/app/three-signal-family.chrome.test.ts 
b/web-next/app/three-signal-family.chrome.test.ts
index 0238a3ab53..1504880614 100644
--- a/web-next/app/three-signal-family.chrome.test.ts
+++ b/web-next/app/three-signal-family.chrome.test.ts
@@ -6,10 +6,11 @@ const sourceFiles = [
   'components/pages/three-signal-desk-shell.tsx',
   'components/overview/overview-console.tsx',
   'components/workbench/primitives.tsx',
+  'app/overview/overview-page.tsx',
   'app/log/manage/log-manage-page.tsx',
-  'app/trace/manage/page.tsx',
-  'app/ingestion/otlp/page.tsx',
-  'app/ingestion/otlp/metrics/page.tsx'
+  'app/trace/manage/trace-manage-page.tsx',
+  'app/ingestion/otlp/otlp-page.tsx',
+  'app/ingestion/otlp/metrics/otlp-metrics-page.tsx'
 ];
 
 describe('three-signal family cold-workbench chrome', () => {
@@ -24,10 +25,10 @@ describe('three-signal family cold-workbench chrome', () => 
{
 
   it('adopts shared workbench owners across the exactness-sensitive 
three-signal family', () => {
     const shellSource = readFileSync(resolve(process.cwd(), 
'components/pages/three-signal-desk-shell.tsx'), 'utf8');
-    const overviewSource = readFileSync(resolve(process.cwd(), 
'app/overview/page.tsx'), 'utf8');
+    const overviewSource = readFileSync(resolve(process.cwd(), 
'app/overview/overview-page.tsx'), 'utf8');
     const logSource = readFileSync(resolve(process.cwd(), 
'app/log/manage/log-manage-page.tsx'), 'utf8');
-    const traceSource = readFileSync(resolve(process.cwd(), 
'app/trace/manage/page.tsx'), 'utf8');
-    const metricsSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/metrics/page.tsx'), 'utf8');
+    const traceSource = readFileSync(resolve(process.cwd(), 
'app/trace/manage/trace-manage-page.tsx'), 'utf8');
+    const metricsSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/metrics/otlp-metrics-page.tsx'), 'utf8');
 
     expect(shellSource).toContain("../observability/workspace-shell");
     expect(shellSource).not.toContain("../workbench/workspace-shell");
@@ -74,11 +75,11 @@ describe('three-signal family cold-workbench chrome', () => 
{
   });
 
   it('removes the remaining legacy white-on-black chrome from the three-signal 
family', () => {
-    const overviewSource = readFileSync(resolve(process.cwd(), 
'app/overview/page.tsx'), 'utf8');
+    const overviewSource = readFileSync(resolve(process.cwd(), 
'app/overview/overview-page.tsx'), 'utf8');
     const logSource = readFileSync(resolve(process.cwd(), 
'app/log/manage/log-manage-page.tsx'), 'utf8');
-    const traceSource = readFileSync(resolve(process.cwd(), 
'app/trace/manage/page.tsx'), 'utf8');
-    const otlpSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/page.tsx'), 'utf8');
-    const metricsSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/metrics/page.tsx'), 'utf8');
+    const traceSource = readFileSync(resolve(process.cwd(), 
'app/trace/manage/trace-manage-page.tsx'), 'utf8');
+    const otlpSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/otlp-page.tsx'), 'utf8');
+    const metricsSource = readFileSync(resolve(process.cwd(), 
'app/ingestion/otlp/metrics/otlp-metrics-page.tsx'), 'utf8');
 
     expect(overviewSource).not.toContain('text-white/44');
     expect(overviewSource).not.toContain('#f3eee6');
diff --git a/web-next/lib/dashboard/navigation.test.ts 
b/web-next/lib/dashboard/navigation.test.ts
index 6692b59427..d650d9df0c 100644
--- a/web-next/lib/dashboard/navigation.test.ts
+++ b/web-next/lib/dashboard/navigation.test.ts
@@ -31,6 +31,10 @@ describe('dashboard navigation', () => {
     expect(source).not.toContain('sanitizeDashboardSearchParams');
     expect(source).not.toContain('delete next.returnLabel');
     expect(source).not.toContain('stripReturnLabelFromHref');
-    expect(source).toContain("buildCompatRedirectTarget('/overview', 
searchParams)");
+    expect(source).toContain("import { buildOverviewCompatRouteUrl, type 
SearchParamsRecord } from '../overview/navigation'");
+    expect(source).toContain('export type { SearchParamsRecord }');
+    expect(source).toContain('return 
buildOverviewCompatRouteUrl(searchParams)');
+    expect(source).not.toContain("buildCompatRedirectTarget('/overview'");
+    expect(source).not.toContain("'/overview'");
   });
 });
diff --git a/web-next/lib/dashboard/navigation.ts 
b/web-next/lib/dashboard/navigation.ts
index a443d93859..a227a352f4 100644
--- a/web-next/lib/dashboard/navigation.ts
+++ b/web-next/lib/dashboard/navigation.ts
@@ -1,5 +1,7 @@
-import { buildCompatRedirectTarget, type SearchParamsRecord } from 
'../compat/search-params';
+import { buildOverviewCompatRouteUrl, type SearchParamsRecord } from 
'../overview/navigation';
+
+export type { SearchParamsRecord };
 
 export function buildDashboardCompatRouteUrl(searchParams?: 
SearchParamsRecord) {
-  return buildCompatRedirectTarget('/overview', searchParams);
+  return buildOverviewCompatRouteUrl(searchParams);
 }
diff --git a/web-next/lib/nav.test.ts b/web-next/lib/nav.test.ts
index 175e952ba9..3944b47f7b 100644
--- a/web-next/lib/nav.test.ts
+++ b/web-next/lib/nav.test.ts
@@ -89,7 +89,9 @@ describe('navigation information architecture', () => {
     expect(cutoverCandidateRoutes.some(route => route.href === 
'/topology')).toBe(true);
     expect(cutoverHoldRoutes.some(route => route.href === 
'/log/manage')).toBe(true);
     expect(cutoverHoldRoutes.some(route => route.href === 
'/trace/manage')).toBe(true);
-    expect(placeholderRoutes.map(route => route.href)).toEqual(['/incidents', 
'/actions', '/explorer']);
+    expect(cutoverCandidateRoutes.some(route => route.href === 
'/incidents')).toBe(true);
+    expect(cutoverCandidateRoutes.some(route => route.href === 
'/explorer')).toBe(true);
+    expect(placeholderRoutes.map(route => route.href)).toEqual(['/actions']);
   });
 
   it('keeps legacy aliases and route-matrix targets in the route contract', () 
=> {
diff --git a/web-next/lib/nav.ts b/web-next/lib/nav.ts
index 63315350e4..eaac230991 100644
--- a/web-next/lib/nav.ts
+++ b/web-next/lib/nav.ts
@@ -74,7 +74,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.entity.discovery',
     label: 'Discovery',
     href: '/entities/discovery',
-    icon: 'entities',
+    icon: 'entity-discovery',
     navSectionKey: 'objects',
     routeKind: 'primary',
     cutoverStatus: 'candidate',
@@ -86,7 +86,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.entity.definition',
     label: 'Definitions',
     href: '/entities/import',
-    icon: 'entities',
+    icon: 'entity-definition',
     navSectionKey: 'objects',
     routeKind: 'primary',
     cutoverStatus: 'candidate',
@@ -163,7 +163,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.alert.integration',
     label: 'Integrations',
     href: '/alert/integration/[source]',
-    icon: 'alert',
+    icon: 'alert-integration',
     navSectionKey: 'alerting',
     routeKind: 'primary',
     cutoverStatus: 'candidate',
@@ -175,7 +175,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.alert.group',
     label: 'Grouping',
     href: '/alert/group',
-    icon: 'alert',
+    icon: 'alert-group',
     navSectionKey: 'alerting',
     routeKind: 'primary',
     cutoverStatus: 'candidate',
@@ -187,7 +187,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.alert.inhibit',
     label: 'Inhibit rules',
     href: '/alert/inhibit',
-    icon: 'alert',
+    icon: 'alert-inhibit',
     navSectionKey: 'alerting',
     routeKind: 'primary',
     cutoverStatus: 'candidate',
@@ -199,7 +199,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.alert.silence',
     label: 'Silence rules',
     href: '/alert/silence',
-    icon: 'alert',
+    icon: 'alert-silence',
     navSectionKey: 'alerting',
     routeKind: 'primary',
     cutoverStatus: 'candidate',
@@ -213,7 +213,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     href: '/incidents',
     icon: 'incidents',
     routeKind: 'primary',
-    cutoverStatus: 'placeholder',
+    cutoverStatus: 'candidate',
     smokePath: '/incidents',
     includeInRouteMatrix: false
   },
@@ -233,7 +233,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.alert.dispatch',
     label: 'Notifications',
     href: '/alert/notice',
-    icon: 'alert',
+    icon: 'alert-notice',
     navSectionKey: 'alerting',
     routeKind: 'primary',
     cutoverStatus: 'candidate',
@@ -319,7 +319,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     label: 'Explorer',
     href: '/explorer',
     routeKind: 'primary',
-    cutoverStatus: 'placeholder',
+    cutoverStatus: 'candidate',
     smokePath: '/explorer',
     includeInRouteMatrix: false
   },
@@ -381,7 +381,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.monitor.collector',
     label: 'Collector',
     href: '/setting/collector',
-    icon: 'monitor',
+    icon: 'collector',
     navSectionKey: 'ingestion',
     routeKind: 'primary',
     cutoverStatus: 'candidate',
@@ -393,7 +393,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.monitor.template',
     label: 'Definitions',
     href: '/setting/define',
-    icon: 'monitor',
+    icon: 'monitor-template',
     navSectionKey: 'ingestion',
     routeKind: 'primary',
     cutoverStatus: 'candidate',
@@ -405,7 +405,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.monitor.bulletin',
     label: 'Bulletin',
     href: '/bulletin',
-    icon: 'bulletin',
+    icon: 'alert-bulletin',
     navSectionKey: 'alerting',
     routeKind: 'primary',
     cutoverStatus: 'candidate',
@@ -431,7 +431,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.advanced.mcp-server',
     label: 'MCP Server',
     href: '/setting/settings/mcp-server',
-    icon: 'settings',
+    icon: 'mcp-server',
     navSectionKey: 'settings',
     includeInNavigation: true,
     routeKind: 'legacy-alias',
@@ -468,7 +468,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.advanced.labels',
     label: 'Labels',
     href: '/setting/labels',
-    icon: 'settings',
+    icon: 'token',
     navSectionKey: 'settings',
     routeKind: 'primary',
     cutoverStatus: 'candidate',
@@ -480,7 +480,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.advanced.plugins',
     label: 'Plugins',
     href: '/setting/plugins',
-    icon: 'settings',
+    icon: 'plugins',
     navSectionKey: 'settings',
     routeKind: 'primary',
     cutoverStatus: 'candidate',
@@ -492,7 +492,7 @@ export const routeCatalog: RouteCatalogEntry[] = [
     labelKey: 'menu.extras.help',
     label: 'Help center',
     href: 'https://hertzbeat.apache.org/docs/',
-    icon: 'settings',
+    icon: 'help',
     navSectionKey: 'settings',
     includeInNavigation: true,
     routeKind: 'primary',
diff --git a/web-next/lib/parity/route-manifest.json 
b/web-next/lib/parity/route-manifest.json
index e89f3bf5bf..87baa4905d 100644
--- a/web-next/lib/parity/route-manifest.json
+++ b/web-next/lib/parity/route-manifest.json
@@ -853,7 +853,7 @@
           "[data-entity-list-table-shell=\"cold-dense-table\"]",
           "[data-entity-list-table=\"cold-entity-table\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button",
           "input",
@@ -897,25 +897,25 @@
           "[data-entity-detail-drilldown-panel=\"cold-drilldown-panel\"]",
           "[data-entity-detail-error=\"cold-inline-error\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "a",
           "button"
         ],
         "textSnippets": [
-          "实体详情",
-          "对象优先调查",
-          "上下文",
-          "相关信号",
-          "下一步",
-          "高级入口"
+          "Entity detail",
+          "Entity-first investigation",
+          "Context",
+          "Related signals",
+          "Next step",
+          "Advanced entries"
         ],
         "actionLabels": [
-          "全部实体",
-          "刷新",
-          "编辑定义",
-          "删除",
-          "编辑"
+          "All entities",
+          "Refresh",
+          "Edit definition",
+          "Delete",
+          "Edit"
         ],
         "minimumVerificationCommand": "npm exec vitest run 
'app/entities/[entityId]/page.test.tsx' 
components/pages/entity-detail-surface.test.tsx 
app/entity-detail-family.chrome.test.ts lib/entity-detail/view-model.test.ts 
lib/parity/route-manifest.test.ts"
       },
@@ -948,7 +948,7 @@
           "[data-entity-type-icon=\"service\"]",
           "[data-entity-type-icon=\"database\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "form",
           "input",
           "button"
@@ -1000,7 +1000,7 @@
           "[data-entity-type-icon=\"service\"]",
           "[data-entity-type-icon=\"database\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "form",
           "input",
           "button"
@@ -1042,7 +1042,7 @@
           "[data-entity-definition-template-panel=\"true\"]",
           "[data-entity-definition-batch-panel=\"true\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "textarea",
           "button"
@@ -1084,7 +1084,7 @@
           "[data-entity-discovery-table=\"cold-discovery-table\"]",
           "[data-entity-discovery-row-actions=\"cold-inline-actions\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button",
           "input",
@@ -1133,7 +1133,7 @@
           "[data-entity-definition-load-error=\"cold-inline\"]",
           "[data-entity-definition-error-placement=\"cold-context-panel\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "textarea",
           "button",
@@ -1185,7 +1185,7 @@
           "[data-alert-center-empty-state=\"cold-table-empty\"]",
           "[data-alert-center-empty-icon=\"cold-empty-box\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "input",
           "select",
@@ -1287,7 +1287,7 @@
           "[data-alert-group-empty-state=\"cold-table-empty\"]",
           "[data-alert-group-empty-icon=\"cold-empty-box\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button",
           "input"
@@ -1325,7 +1325,7 @@
           "[data-alert-silence-empty-state=\"cold-table-empty\"]",
           "[data-alert-silence-empty-icon=\"cold-empty-box\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button",
           "input"
@@ -1364,7 +1364,7 @@
           "[data-alert-inhibit-empty-state=\"cold-table-empty\"]",
           "[data-alert-inhibit-empty-icon=\"cold-empty-box\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button",
           "input"
@@ -1403,7 +1403,7 @@
           "[data-alert-notice-receiver-toolbar=\"cold-query-toolbar\"]",
           "[data-alert-notice-receiver-table-shell=\"cold-dense-table\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "[data-tab=\"receiver\"]",
           "main",
           "button",
@@ -1456,7 +1456,7 @@
           "[data-alert-notice-rule-toolbar=\"cold-query-toolbar\"]",
           "[data-alert-notice-rule-table-shell=\"cold-dense-table\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button",
           "input"
@@ -1510,7 +1510,7 @@
           "[data-alert-notice-template-table-shell=\"cold-dense-table\"]",
           "[data-alert-notice-pagination=\"cold-dense-pagination\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button",
           "input",
@@ -1553,7 +1553,7 @@
           "[data-alert-setting-empty-state=\"cold-table-empty\"]",
           "[data-alert-setting-empty-icon=\"cold-empty-box\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button",
           "input"
@@ -1594,7 +1594,7 @@
           "[data-alert-integration-code-block=\"json\"]",
           "[data-alert-integration-mermaid]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button"
         ],
@@ -1642,7 +1642,7 @@
           "[data-setting-config-form=\"cold-settings-form\"]",
           "[data-setting-config-actions=\"standard-equal-buttons\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "form",
           "select",
           "button"
@@ -1748,7 +1748,7 @@
           "[data-setting-config-form=\"cold-settings-form\"]",
           "[data-setting-config-actions=\"standard-equal-buttons\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "form",
           "select",
           "button"
@@ -1787,7 +1787,7 @@
           "[data-setting-object-store-provider=\"cold-provider-select\"]",
           "[data-setting-object-store-actions=\"standard-equal-buttons\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "form",
           "select",
           "button"
@@ -1830,7 +1830,7 @@
           "[data-settings-summary-action=\"email\"]",
           "[data-settings-summary-action=\"sms\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button"
         ],
@@ -1874,7 +1874,7 @@
           "[data-setting-token-table-panel=\"cold-dense-table\"]",
           "[data-setting-token-table=\"cold-token-table\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button",
           "table"
@@ -1958,15 +1958,14 @@
           "[data-setting-define-menu-shell=\"cold-dense-list\"]",
           "[data-setting-define-editor=\"cold-settings-form\"]",
           "[data-setting-define-editor-shell=\"cold-yaml-editor\"]",
-          "[data-setting-define-editor-field=\"cold-code-textarea\"]",
+          "[data-setting-define-editor-field=\"cold-code-editor\"]",
+          "[data-setting-define-code-editor=\"monitor-template-yaml\"]",
           "button",
-          "input",
-          "textarea"
+          "input"
         ],
         "textSnippets": [
           "定义",
-          "管理监控类型定义",
-          "数据源状态"
+          "管理监控模板 YAML"
         ],
         "actionLabels": [
           "新增类型",
@@ -1974,7 +1973,8 @@
           "取消",
           "保存并应用",
           "搜索",
-          "预览查询"
+          "隐藏",
+          "显示"
         ],
         "minimumVerificationCommand": "npm exec vitest run 
app/setting/define/page.test.tsx 
components/pages/setting-define-surface.test.tsx 
lib/setting-define/controller.test.ts lib/setting-define/query-state.test.ts 
lib/setting-define/view-model.test.ts lib/parity/route-manifest.test.ts"
       },
@@ -1997,7 +1997,7 @@
           "[data-label-table=\"cold-label-table\"]",
           "[data-label-empty-state=\"cold-table-empty\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button",
           "input",
@@ -2037,7 +2037,7 @@
           "[data-plugin-manage-table=\"cold-plugin-table\"]",
           "[data-plugin-manage-empty-state=\"cold-table-empty\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button",
           "input",
@@ -2077,7 +2077,7 @@
           "[data-status-component-table-shell=\"cold-dense-table\"]",
           "[data-status-component-table=\"cold-component-table\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "button",
           "input",
@@ -2294,8 +2294,8 @@
     "key": "compatibility-placeholder-family",
     "milestone": 5,
     "legacyArea": "compatibility-and-placeholder",
-    "summary": "Close compatibility aliases plus placeholder twins in the 
final parity sweep.",
-    "familyVerificationCommand": "npm exec vitest run 
app/dashboard/page.test.ts app/overview/page.test.tsx 
lib/overview/navigation.test.ts lib/overview/view-model.test.ts 
app/events/page.test.ts app/log/manage/page.test.tsx 
lib/log-manage/query-state.test.ts lib/log-manage/view-model.test.ts 
app/alerts/page.test.ts app/alert/page.test.tsx 
components/pages/alert-center-surface.test.tsx 
lib/alert-manage/query-state.test.ts lib/alert-manage/controller.test.ts 
lib/alert-manage/view-model.te [...]
+    "summary": "Close compatibility aliases plus placeholder twins and the 
unified Explorer workbench in the final parity sweep.",
+    "familyVerificationCommand": "npm exec vitest run 
app/dashboard/page.test.ts app/overview/page.test.tsx 
lib/overview/navigation.test.ts lib/overview/view-model.test.ts 
app/events/page.test.ts app/log/manage/page.test.tsx 
lib/log-manage/query-state.test.ts lib/log-manage/view-model.test.ts 
app/alerts/page.test.ts app/alert/page.test.tsx 
components/pages/alert-center-surface.test.tsx 
lib/alert-manage/query-state.test.ts lib/alert-manage/controller.test.ts 
lib/alert-manage/view-model.te [...]
     "referenceBaseUrl": "http://127.0.0.1:4301";,
     "nextBaseUrl": "http://127.0.0.1:4200";,
     "routePairs": [
@@ -2383,7 +2383,7 @@
           "[data-alert-center-empty-state=\"cold-table-empty\"]",
           "[data-alert-center-empty-icon=\"cold-empty-box\"]",
           "[data-platform-footer=\"angular-footer\"]",
-          "[data-shell-help-launcher=\"angular-help\"]",
+          "[data-shell-ai-chat-launcher=\"angular-ai-chat\"]",
           "main",
           "input",
           "select",
@@ -2446,8 +2446,22 @@
         "primarySelectors": [
           "[data-actions-route=\"otlp-cold-ops-entry\"]",
           "[data-actions-style-baseline=\"hertzbeat-cold-matte\"]",
+          "[data-actions-shared-workbench=\"hertzbeat-ui\"]",
+          "[data-hz-action-workbench-owner=\"hertzbeat-ui-action-workbench\"]",
           "[data-actions-shell-panel=\"cold-ops-shell-panel\"]",
           "[data-actions-launch-checklist=\"cold-ops-static-rail\"]",
+          "[data-actions-catalog=\"manual-action-catalog-api\"]",
+          "[data-actions-catalog-owner=\"next-actions-catalog-bff\"]",
+          "[data-actions-catalog-execution-allowed=\"false\"]",
+          "[data-actions-approval-draft=\"manual-approval-draft-api\"]",
+          
"[data-actions-approval-draft-owner=\"next-actions-approval-draft-bff\"]",
+          "[data-actions-approval-draft-execution-allowed=\"false\"]",
+          
"[data-actions-approval-draft-queue=\"manual-approval-draft-read-api\"]",
+          
"[data-actions-approval-draft-queue-owner=\"next-actions-approval-draft-bff\"]",
+          "[data-actions-approval-draft-queue-execution-allowed=\"false\"]",
+          "[data-actions-approval-decision=\"manual-approval-decision-api\"]",
+          
"[data-actions-approval-decision-owner=\"next-actions-approval-decision-bff\"]",
+          "[data-actions-approval-decision-execution-allowed=\"false\"]",
           "[data-actions-empty-state=\"cold-ops-domain-adapter\"]",
           "main",
           "section",
@@ -2465,7 +2479,7 @@
           "打开概览",
           "查看对象"
         ],
-        "minimumVerificationCommand": "npm exec vitest run 
app/actions/page.test.tsx lib/actions-surface/view-model.test.ts 
lib/actions-surface/model.test.ts lib/parity/route-manifest.test.ts"
+        "minimumVerificationCommand": "npm exec vitest run 
app/actions/page.test.tsx app/api/actions/approval-drafts/route.test.ts 
app/api/actions/approval-drafts/[draftId]/decision/route.test.ts 
app/api/actions/catalog/route.test.ts lib/actions-surface/view-model.test.ts 
lib/actions-surface/model.test.ts lib/parity/route-manifest.test.ts"
       },
       {
         "key": "topology-placeholder",
@@ -2500,7 +2514,7 @@
         "minimumVerificationCommand": "npm exec vitest run 
app/topology/page.test.tsx lib/topology-surface/view-model.test.ts 
lib/parity/route-manifest.test.ts"
       },
       {
-        "key": "explorer-placeholder",
+        "key": "explorer-workbench",
         "nextRoute": "/explorer",
         "referenceRoute": "/explorer",
         "nextPagePath": "web-next/app/explorer/page.tsx",
@@ -2511,9 +2525,16 @@
         "primarySelectors": [
           "[data-explorer-route=\"otlp-cold-workbench\"]",
           "[data-explorer-style-baseline=\"hertzbeat-cold-matte\"]",
+          "[data-explorer-api-owner=\"trace-log-bff-query-api\"]",
+          "[data-explorer-query-state]",
+          "[data-explorer-signal-filter]",
+          "[data-explorer-api-source]",
+          "[data-explorer-shared-frame=\"hertzbeat-ui\"]",
+          "[data-hz-ui=\"explorer-frame\"]",
           "[data-explorer-query-bar=\"cold-query-row\"]",
           "[data-explorer-chart-band=\"cold-chart-band\"]",
           "[data-explorer-result-table=\"cold-dense-table\"]",
+          "[data-explorer-result-table-owner=\"hertzbeat-ui-data-table\"]",
           "[data-explorer-detail-panel=\"cold-detail-panel\"]",
           "main",
           "button",
@@ -2532,7 +2553,7 @@
           "创建告警",
           "加入仪表盘"
         ],
-        "minimumVerificationCommand": "npm exec vitest run 
app/explorer/page.test.tsx lib/explorer-surface/view-model.test.ts 
lib/parity/route-manifest.test.ts"
+        "minimumVerificationCommand": "npm exec vitest run 
app/explorer/page.test.tsx lib/explorer-surface/controller.test.ts 
lib/explorer-surface/view-model.test.ts lib/otlp-metrics/controller.test.ts 
lib/otlp-metrics/view-model.test.ts lib/parity/route-manifest.test.ts"
       }
     ]
   }
diff --git a/web-next/lib/parity/route-manifest.test.ts 
b/web-next/lib/parity/route-manifest.test.ts
index 92a2fee26a..a8909d7f32 100644
--- a/web-next/lib/parity/route-manifest.test.ts
+++ b/web-next/lib/parity/route-manifest.test.ts
@@ -139,7 +139,7 @@ describe('parity route manifest', () => {
         '[data-alert-center-empty-state="cold-table-empty"]',
         '[data-alert-center-empty-icon="cold-empty-box"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'input',
         'select',
@@ -187,8 +187,22 @@ describe('parity route manifest', () => {
       primarySelectors: expect.arrayContaining([
         '[data-actions-route="otlp-cold-ops-entry"]',
         '[data-actions-style-baseline="hertzbeat-cold-matte"]',
+        '[data-actions-shared-workbench="hertzbeat-ui"]',
+        '[data-hz-action-workbench-owner="hertzbeat-ui-action-workbench"]',
         '[data-actions-shell-panel="cold-ops-shell-panel"]',
         '[data-actions-launch-checklist="cold-ops-static-rail"]',
+        '[data-actions-catalog="manual-action-catalog-api"]',
+        '[data-actions-catalog-owner="next-actions-catalog-bff"]',
+        '[data-actions-catalog-execution-allowed="false"]',
+        '[data-actions-approval-draft="manual-approval-draft-api"]',
+        
'[data-actions-approval-draft-owner="next-actions-approval-draft-bff"]',
+        '[data-actions-approval-draft-execution-allowed="false"]',
+        '[data-actions-approval-draft-queue="manual-approval-draft-read-api"]',
+        
'[data-actions-approval-draft-queue-owner="next-actions-approval-draft-bff"]',
+        '[data-actions-approval-draft-queue-execution-allowed="false"]',
+        '[data-actions-approval-decision="manual-approval-decision-api"]',
+        
'[data-actions-approval-decision-owner="next-actions-approval-decision-bff"]',
+        '[data-actions-approval-decision-execution-allowed="false"]',
         '[data-actions-empty-state="cold-ops-domain-adapter"]',
         'main',
         'section',
@@ -198,7 +212,7 @@ describe('parity route manifest', () => {
       textSnippets: expect.arrayContaining(['自动化处置', '按 OTLP 工作台的冷色基线', 
'冷色入口已接入', '等待接入执行适配器', '你已完成 83% 的平台配置']),
       actionLabels: ['打开概览', '查看对象'],
       minimumVerificationCommand:
-        'npm exec vitest run app/actions/page.test.tsx 
lib/actions-surface/view-model.test.ts lib/actions-surface/model.test.ts 
lib/parity/route-manifest.test.ts'
+        'npm exec vitest run app/actions/page.test.tsx 
app/api/actions/approval-drafts/route.test.ts 
app/api/actions/approval-drafts/[draftId]/decision/route.test.ts 
app/api/actions/catalog/route.test.ts lib/actions-surface/view-model.test.ts 
lib/actions-surface/model.test.ts lib/parity/route-manifest.test.ts'
     });
   });
 
@@ -223,15 +237,22 @@ describe('parity route manifest', () => {
     });
   });
 
-  it('tracks the OTLP cold unified explorer instead of the old 
external-product-first surface', () => {
-    expect(getParityRoutePair('compatibility-placeholder-family', 
'explorer-placeholder')).toMatchObject({
+  it('tracks the OTLP cold unified explorer as an API/query-backed workbench 
instead of the old external-product-first surface', () => {
+    expect(getParityRoutePair('compatibility-placeholder-family', 
'explorer-workbench')).toMatchObject({
       screenshotMode: 'viewport',
       primarySelectors: expect.arrayContaining([
         '[data-explorer-route="otlp-cold-workbench"]',
         '[data-explorer-style-baseline="hertzbeat-cold-matte"]',
+        '[data-explorer-api-owner="trace-log-bff-query-api"]',
+        '[data-explorer-query-state]',
+        '[data-explorer-signal-filter]',
+        '[data-explorer-api-source]',
+        '[data-explorer-shared-frame="hertzbeat-ui"]',
+        '[data-hz-ui="explorer-frame"]',
         '[data-explorer-query-bar="cold-query-row"]',
         '[data-explorer-chart-band="cold-chart-band"]',
         '[data-explorer-result-table="cold-dense-table"]',
+        '[data-explorer-result-table-owner="hertzbeat-ui-data-table"]',
         '[data-explorer-detail-panel="cold-detail-panel"]',
         'main',
         'button',
@@ -241,9 +262,9 @@ describe('parity route manifest', () => {
       textSnippets: expect.arrayContaining(['查询工作台', '信号类型', '运行查询', 
'checkout']),
       actionLabels: ['运行查询', '保存视图', '创建告警', '加入仪表盘'],
       minimumVerificationCommand:
-        'npm exec vitest run app/explorer/page.test.tsx 
lib/explorer-surface/view-model.test.ts lib/parity/route-manifest.test.ts'
+        'npm exec vitest run app/explorer/page.test.tsx 
lib/explorer-surface/controller.test.ts lib/explorer-surface/view-model.test.ts 
lib/otlp-metrics/controller.test.ts lib/otlp-metrics/view-model.test.ts 
lib/parity/route-manifest.test.ts'
     });
-    expect(getParityRoutePair('compatibility-placeholder-family', 
'explorer-placeholder').primarySelectors.join(' ')).not.toContain('signoz-');
+    expect(getParityRoutePair('compatibility-placeholder-family', 
'explorer-workbench').primarySelectors.join(' ')).not.toContain('signoz-');
   });
 
   it('declares explicit parity owners for the milestone 2 families', () => {
@@ -290,9 +311,9 @@ describe('parity route manifest', () => {
     );
   });
 
-  it('declares a family-closeout verification command for the compatibility 
aliases and placeholder twins', () => {
+  it('declares a family-closeout verification command for compatibility 
aliases, placeholder twins, and Explorer', () => {
     expect((getParityFamily('compatibility-placeholder-family') as 
Record<string, unknown>).familyVerificationCommand).toBe(
-      'npm exec vitest run app/dashboard/page.test.ts 
app/overview/page.test.tsx lib/overview/navigation.test.ts 
lib/overview/view-model.test.ts app/events/page.test.ts 
app/log/manage/page.test.tsx lib/log-manage/query-state.test.ts 
lib/log-manage/view-model.test.ts app/alerts/page.test.ts 
app/alert/page.test.tsx components/pages/alert-center-surface.test.tsx 
lib/alert-manage/query-state.test.ts lib/alert-manage/controller.test.ts 
lib/alert-manage/view-model.test.ts app/incidents/page.te [...]
+      'npm exec vitest run app/dashboard/page.test.ts 
app/overview/page.test.tsx lib/overview/navigation.test.ts 
lib/overview/view-model.test.ts app/events/page.test.ts 
app/log/manage/page.test.tsx lib/log-manage/query-state.test.ts 
lib/log-manage/view-model.test.ts app/alerts/page.test.ts 
app/alert/page.test.tsx components/pages/alert-center-surface.test.tsx 
lib/alert-manage/query-state.test.ts lib/alert-manage/controller.test.ts 
lib/alert-manage/view-model.test.ts app/incidents/page.te [...]
     );
   });
 
@@ -741,7 +762,7 @@ describe('parity route manifest', () => {
         '[data-entity-list-table-shell="cold-dense-table"]',
         '[data-entity-list-table="cold-entity-table"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button',
         'input',
@@ -788,7 +809,7 @@ describe('parity route manifest', () => {
         '[data-entity-type-icon="service"]',
         '[data-entity-type-icon="database"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]'
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]'
       ]),
       textSnippets: expect.arrayContaining(['新建实体', '全部实体', '实体元数据', '页面录入', 
'基本信息', '你已完成 83% 的平台配置']),
       actionLabels: ['创建实体']
@@ -826,7 +847,7 @@ describe('parity route manifest', () => {
         '[data-entity-type-icon="service"]',
         '[data-entity-type-icon="database"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]'
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]'
       ]),
       textSnippets: expect.arrayContaining(['编辑实体', '全部实体', '实体元数据', '基本信息', 
'你已完成 0% 的平台配置']),
       actionLabels: ['保存']
@@ -859,7 +880,7 @@ describe('parity route manifest', () => {
         '[data-entity-definition-template-panel="true"]',
         '[data-entity-definition-batch-panel="true"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'textarea',
         'button'
@@ -898,7 +919,7 @@ describe('parity route manifest', () => {
         '[data-entity-definition-load-error="cold-inline"]',
         '[data-entity-definition-error-placement="cold-context-panel"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'textarea',
         'button',
@@ -945,7 +966,7 @@ describe('parity route manifest', () => {
         '[data-entity-discovery-table="cold-discovery-table"]',
         '[data-entity-discovery-row-actions="cold-inline-actions"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button',
         'input',
@@ -987,21 +1008,28 @@ describe('parity route manifest', () => {
         '[data-entity-detail-drilldown-panel="cold-drilldown-panel"]',
         '[data-entity-detail-error="cold-inline-error"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'a',
         'button'
       ]),
-      textSnippets: expect.arrayContaining(['实体详情', '对象优先调查', '上下文', '相关信号', 
'下一步', '高级入口']),
-      actionLabels: ['全部实体', '刷新', '编辑定义', '删除', '编辑'],
+      textSnippets: expect.arrayContaining([
+        'Entity detail',
+        'Entity-first investigation',
+        'Context',
+        'Related signals',
+        'Next step',
+        'Advanced entries'
+      ]),
+      actionLabels: ['All entities', 'Refresh', 'Edit definition', 'Delete', 
'Edit'],
       minimumVerificationCommand:
         "npm exec vitest run 'app/entities/[entityId]/page.test.tsx' 
components/pages/entity-detail-surface.test.tsx 
app/entity-detail-family.chrome.test.ts lib/entity-detail/view-model.test.ts 
lib/parity/route-manifest.test.ts"
     });
     expect(getParityRoutePair('entity-family', 
'entity-detail').primarySelectors).not.toContain('aside');
-    expect(getParityRoutePair('entity-family', 
'entity-detail').textSnippets).not.toContain('Entity');
-    expect(getParityRoutePair('entity-family', 
'entity-detail').textSnippets).not.toContain('Next steps');
-    expect(getParityRoutePair('entity-family', 
'entity-detail').actionLabels).not.toContain('Refresh');
-    expect(getParityRoutePair('entity-family', 
'entity-detail').actionLabels).not.toContain('Edit definition');
+    expect(getParityRoutePair('entity-family', 
'entity-detail').textSnippets).not.toContain('实体详情');
+    expect(getParityRoutePair('entity-family', 
'entity-detail').textSnippets).not.toContain('对象优先调查');
+    expect(getParityRoutePair('entity-family', 
'entity-detail').actionLabels).not.toContain('刷新');
+    expect(getParityRoutePair('entity-family', 
'entity-detail').actionLabels).not.toContain('编辑定义');
   });
 
   it('tracks the alert center through targeted route, shared-surface, and 
filter contracts', () => {
@@ -1019,7 +1047,7 @@ describe('parity route manifest', () => {
         '[data-alert-center-empty-state="cold-table-empty"]',
         '[data-alert-center-empty-icon="cold-empty-box"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'input',
         'select',
@@ -1053,7 +1081,7 @@ describe('parity route manifest', () => {
         '[data-alert-group-empty-state="cold-table-empty"]',
         '[data-alert-group-empty-icon="cold-empty-box"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button',
         'input'
@@ -1115,7 +1143,7 @@ describe('parity route manifest', () => {
         '[data-alert-notice-receiver-toolbar="cold-query-toolbar"]',
         '[data-alert-notice-receiver-table-shell="cold-dense-table"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         '[data-tab="receiver"]',
         'main',
         'button',
@@ -1148,7 +1176,7 @@ describe('parity route manifest', () => {
         '[data-alert-notice-rule-toolbar="cold-query-toolbar"]',
         '[data-alert-notice-rule-table-shell="cold-dense-table"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button',
         'input'
@@ -1179,7 +1207,7 @@ describe('parity route manifest', () => {
         '[data-alert-notice-template-table-shell="cold-dense-table"]',
         '[data-alert-notice-pagination="cold-dense-pagination"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button',
         'input',
@@ -1217,7 +1245,7 @@ describe('parity route manifest', () => {
         '[data-alert-setting-empty-state="cold-table-empty"]',
         '[data-alert-setting-empty-icon="cold-empty-box"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button',
         'input'
@@ -1252,7 +1280,7 @@ describe('parity route manifest', () => {
         '[data-alert-integration-code-block="json"]',
         '[data-alert-integration-mermaid]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button'
       ]),
@@ -1282,7 +1310,7 @@ describe('parity route manifest', () => {
         '[data-alert-silence-empty-state="cold-table-empty"]',
         '[data-alert-silence-empty-icon="cold-empty-box"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button',
         'input'
@@ -1314,7 +1342,7 @@ describe('parity route manifest', () => {
         '[data-alert-inhibit-empty-state="cold-table-empty"]',
         '[data-alert-inhibit-empty-icon="cold-empty-box"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button',
         'input'
@@ -1346,7 +1374,7 @@ describe('parity route manifest', () => {
         '[data-setting-config-form="cold-settings-form"]',
         '[data-setting-config-actions="standard-equal-buttons"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'form',
         'select',
         'button'
@@ -1378,7 +1406,7 @@ describe('parity route manifest', () => {
         '[data-setting-config-form="cold-settings-form"]',
         '[data-setting-config-actions="standard-equal-buttons"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'form',
         'select',
         'button'
@@ -1418,7 +1446,7 @@ describe('parity route manifest', () => {
         '[data-setting-object-store-provider="cold-provider-select"]',
         '[data-setting-object-store-actions="standard-equal-buttons"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'form',
         'select',
         'button'
@@ -1464,7 +1492,7 @@ describe('parity route manifest', () => {
         '[data-settings-summary-action="email"]',
         '[data-settings-summary-action="sms"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button'
       ]),
@@ -1510,7 +1538,7 @@ describe('parity route manifest', () => {
         '[data-setting-token-table-panel="cold-dense-table"]',
         '[data-setting-token-table="cold-token-table"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button',
         'table'
@@ -1586,14 +1614,14 @@ describe('parity route manifest', () => {
         '[data-setting-define-menu-shell="cold-dense-list"]',
         '[data-setting-define-editor="cold-settings-form"]',
         '[data-setting-define-editor-shell="cold-yaml-editor"]',
-        '[data-setting-define-editor-field="cold-code-textarea"]',
+        '[data-setting-define-editor-field="cold-code-editor"]',
+        '[data-setting-define-code-editor="monitor-template-yaml"]',
         'main',
         'button',
-        'input',
-        'textarea'
+        'input'
       ]),
-      textSnippets: expect.arrayContaining(['定义', '管理监控类型定义', '数据源状态']),
-      actionLabels: ['新增类型', '编辑', '取消', '保存并应用', '搜索', '预览查询'],
+      textSnippets: expect.arrayContaining(['定义', '管理监控模板 YAML']),
+      actionLabels: ['新增类型', '编辑', '取消', '保存并应用', '搜索', '隐藏', '显示'],
       minimumVerificationCommand:
         'npm exec vitest run app/setting/define/page.test.tsx 
components/pages/setting-define-surface.test.tsx 
lib/setting-define/controller.test.ts lib/setting-define/query-state.test.ts 
lib/setting-define/view-model.test.ts lib/parity/route-manifest.test.ts'
     });
@@ -1601,6 +1629,8 @@ describe('parity route manifest', () => {
     expect(getParityRoutePair('setting-family', 
'setting-define').primarySelectors).not.toContain('[data-setting-define-summary-rail="cold-static-rail"]');
     expect(getParityRoutePair('setting-family', 
'setting-define').textSnippets).not.toContain('Define');
     expect(getParityRoutePair('setting-family', 
'setting-define').actionLabels).not.toContain('New Monitor Type');
+    expect(getParityRoutePair('setting-family', 
'setting-define').textSnippets).not.toContain('数据源状态');
+    expect(getParityRoutePair('setting-family', 
'setting-define').actionLabels).not.toContain('预览查询');
   });
 
   it('pins label management to the OTLP cold-matte dense admin/list contract', 
() => {
@@ -1618,7 +1648,7 @@ describe('parity route manifest', () => {
         '[data-label-table="cold-label-table"]',
         '[data-label-empty-state="cold-table-empty"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button',
         'input',
@@ -1654,7 +1684,7 @@ describe('parity route manifest', () => {
         '[data-plugin-manage-table="cold-plugin-table"]',
         '[data-plugin-manage-empty-state="cold-table-empty"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button',
         'input',
@@ -1689,7 +1719,7 @@ describe('parity route manifest', () => {
         '[data-status-component-table-shell="cold-dense-table"]',
         '[data-status-component-table="cold-component-table"]',
         '[data-platform-footer="angular-footer"]',
-        '[data-shell-help-launcher="angular-help"]',
+        '[data-shell-ai-chat-launcher="angular-ai-chat"]',
         'main',
         'button',
         'input',
diff --git a/web-next/lib/workspace-navigation.test.ts 
b/web-next/lib/workspace-navigation.test.ts
index 6832203d50..3932cbd8ab 100644
--- a/web-next/lib/workspace-navigation.test.ts
+++ b/web-next/lib/workspace-navigation.test.ts
@@ -1,4 +1,5 @@
 import { describe, expect, it } from 'vitest';
+import { createTranslatorMock } from '../test/i18n-test-helper';
 import {
   buildEntityEditorWorkspaceTabs,
   buildEntitySignalRouteContext,
@@ -7,7 +8,7 @@ import {
   buildSignalWorkspaceTabs
 } from './workspace-navigation';
 
-const t = (key: string) => key;
+const t = createTranslatorMock({ locale: 'zh-CN' });
 
 describe('workspace navigation', () => {
   it('prefers the explicit return path for entity workspace navigation', () => 
{
@@ -61,6 +62,7 @@ describe('workspace navigation', () => {
     const ingestionTab = tabs.find(tab => tab.key === 'ingestion');
     const monitorsTab = tabs.find(tab => tab.key === 'monitors');
 
+    expect(tabs.map(tab => tab.label)).toEqual(['实体详情', '可观测接入', '指标工作台', 
'日志工作台', '链路工作台', '监控中心']);
     expect(logsTab?.href).toContain('/log/manage?');
     expect(logsTab?.href).toContain('traceId=trace-123');
     expect(logsTab?.href).toContain('severityText=ERROR');
@@ -139,6 +141,7 @@ describe('workspace navigation', () => {
     });
 
     expect(tabs.map(tab => tab.key)).toEqual(['entity', 'metrics', 'monitors', 
'logs', 'traces']);
+    expect(tabs.map(tab => tab.label)).toEqual(['实体详情', '指标工作台', '监控中心', 
'日志工作台', '链路工作台']);
     expect(tabs[2]?.href).toContain('/monitors?');
     expect(tabs[2]?.href).toContain('entityId=7');
     expect(tabs[3]?.href).toContain('/log/manage?');
@@ -153,6 +156,7 @@ describe('workspace navigation', () => {
     });
 
     expect(tabs.map(tab => tab.key)).toEqual(['entity', 'monitors', 'logs', 
'traces']);
+    expect(tabs.map(tab => tab.label)).toEqual(['实体详情', '监控中心', '日志工作台', 
'链路工作台']);
     expect(tabs.find(tab => tab.key === 'entity')?.active).toBe(true);
     expect(tabs.find(tab => tab.key === 'monitors')?.disabled).toBe(true);
     expect(tabs.find(tab => tab.key === 'logs')?.disabled).toBe(true);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to