diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json
index 73a44afa0..272cbcc7c 100644
--- a/apps/web/messages/en.json
+++ b/apps/web/messages/en.json
@@ -1991,12 +1991,12 @@
"actionGoObservability": "前往可觀測性",
"actionGoAutomation": "前往自動化",
"actionGoOperations": "前往營運",
- "actionGoSecurity": "前往安全合規",
+ "actionGoSecurity": "前往 IwoooS 安全主控台",
"actionGoKnowledge": "前往知識殿堂",
"actionGoSettings": "前往設定",
"actionGoTerminal": "前往終端頁面",
"actionGoApprovals": "前往授權中心",
- "actionGoIwooos": "前往 IwoooS"
+ "actionGoIwooos": "前往 IwoooS 資安主控台"
},
"aiopsTimeline": {
"title": "AIOps 全景時序",
diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json
index 73a44afa0..272cbcc7c 100644
--- a/apps/web/messages/zh-TW.json
+++ b/apps/web/messages/zh-TW.json
@@ -1991,12 +1991,12 @@
"actionGoObservability": "前往可觀測性",
"actionGoAutomation": "前往自動化",
"actionGoOperations": "前往營運",
- "actionGoSecurity": "前往安全合規",
+ "actionGoSecurity": "前往 IwoooS 安全主控台",
"actionGoKnowledge": "前往知識殿堂",
"actionGoSettings": "前往設定",
"actionGoTerminal": "前往終端頁面",
"actionGoApprovals": "前往授權中心",
- "actionGoIwooos": "前往 IwoooS"
+ "actionGoIwooos": "前往 IwoooS 資安主控台"
},
"aiopsTimeline": {
"title": "AIOps 全景時序",
diff --git a/apps/web/src/components/command-palette/CommandPalette.tsx b/apps/web/src/components/command-palette/CommandPalette.tsx
index af8545d69..d87f0de36 100644
--- a/apps/web/src/components/command-palette/CommandPalette.tsx
+++ b/apps/web/src/components/command-palette/CommandPalette.tsx
@@ -17,7 +17,7 @@ import React, { useEffect, useRef, useState, useCallback } from 'react'
import { useTranslations } from 'next-intl'
import { useRouter, usePathname } from 'next/navigation'
import { useLocale } from 'next-intl'
-import { Search, Terminal, Home, Activity, Wrench, Shield, BookOpen, Settings, Zap, GitBranch, Radar } from 'lucide-react'
+import { Search, Terminal, Home, Activity, Wrench, BookOpen, Settings, Zap, GitBranch, Radar } from 'lucide-react'
import { useTerminalStore } from '@/stores/terminal.store'
import { Z_INDEX } from '@/lib/constants/z-index'
@@ -99,21 +99,23 @@ export function CommandPalette() {
action: () => nav('/operations'),
keywords: ['operations', '營運', 'ops'],
},
- {
- id: 'security',
- label: t('actionGoSecurity'),
- group: t('groupNav'),
- icon: ,
- action: () => nav('/security-compliance'),
- keywords: ['security', '安全', 'compliance', '合規'],
- },
{
id: 'iwooos',
label: t('actionGoIwooos'),
group: t('groupNav'),
icon: ,
action: () => nav('/iwooos'),
- keywords: ['iwooos', 'information security', '資安網', '資安態勢'],
+ keywords: [
+ 'iwooos',
+ 'information security',
+ 'security',
+ '安全',
+ '安全合規',
+ 'compliance',
+ '合規',
+ '資安網',
+ '資安態勢',
+ ],
},
{
id: 'knowledge',
diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md
index 7575d606c..88310da3f 100644
--- a/docs/LOGBOOK.md
+++ b/docs/LOGBOOK.md
@@ -1,3 +1,28 @@
+## 2026-06-01|IwoooS 命令面板資安入口收斂
+
+**背景**:
+
+- 使用者指出「安全合規」與 `IwoooS` 兩個入口容易被理解成兩套資安系統。
+- 主線 sidebar 已收斂成單一 `IwoooS` 資安入口,`/security-compliance` 只保留相容與既有使用者熟悉頁面;本輪補齊命令面板,避免搜尋「安全合規 / compliance」時又回到舊獨立入口。
+
+**本次調整**:
+
+- `apps/web/src/components/command-palette/CommandPalette.tsx`:
+ - 移除命令面板中的獨立 `security` 項目。
+ - 將 `security`、`安全`、`安全合規`、`compliance`、`合規` 等搜尋詞全部收斂到 `IwoooS`,導向 `/iwooos`。
+- `apps/web/messages/zh-TW.json` / `apps/web/messages/en.json`:
+ - 將命令面板顯示文字調整為「前往 IwoooS 資安主控台」;`en.json` 維持繁中鏡像。
+- `docs/security/iwooos-posture-projection.snapshot.json` / `security-mirror-status-rollup.snapshot.json`:
+ - 補上 `command_palette_security_action_unified_to_iwooos=true`、`command_palette_security_compliance_direct_action_allowed=false`、`command_palette_security_keywords_route_to_iwooos=true`。
+ - 新增 `S2.144` 進度 ledger;headline 仍不增加,因為這是入口收斂與理解成本降低,不是 runtime 授權。
+- `scripts/security/security-mirror-progress-guard.py`:
+ - 新增 guard,禁止命令面板重新出現 `nav('/security-compliance')` 或獨立 `security` 項目。
+
+**進度邊界**:
+
+- 整體維持 `61%`。
+- 本輪屬於 framework / UX / evidence 可理解度推進;runtime gate、Kali / SSH、掃描、修復、部署按鈕、GitHub primary 切換、Gitea 停用仍維持 `false / 0`。
+
## 2026-05-31|Alerts 焦點告警補上處理狀態卡
**背景**:
diff --git a/docs/security/iwooos-posture-projection.snapshot.json b/docs/security/iwooos-posture-projection.snapshot.json
index bd5eff732..3539f8bf6 100644
--- a/docs/security/iwooos-posture-projection.snapshot.json
+++ b/docs/security/iwooos-posture-projection.snapshot.json
@@ -21,12 +21,16 @@
"apps/web/src/app/[locale]/governance/page.tsx",
"apps/web/src/app/[locale]/alert-operation-logs/page.tsx",
"apps/web/src/app/[locale]/awooop/approvals/page.tsx",
- "apps/web/src/app/[locale]/code-review/page.tsx"
+ "apps/web/src/app/[locale]/code-review/page.tsx",
+ "apps/web/src/components/command-palette/CommandPalette.tsx"
],
"summary": {
"route_path": "/iwooos",
"nav_entry_added": true,
"command_palette_entry_added": true,
+ "command_palette_security_action_unified_to_iwooos": true,
+ "command_palette_security_compliance_direct_action_allowed": false,
+ "command_palette_security_keywords_route_to_iwooos": true,
"contract_count": 36,
"active_runtime_gate_count": 0,
"approval_queue_total": 8,
diff --git a/docs/security/security-mirror-status-rollup.snapshot.json b/docs/security/security-mirror-status-rollup.snapshot.json
index e3cbfe035..31e77713b 100644
--- a/docs/security/security-mirror-status-rollup.snapshot.json
+++ b/docs/security/security-mirror-status-rollup.snapshot.json
@@ -2197,6 +2197,18 @@
"runtime_delta": false,
"execution_authorized": false,
"not_authorization": true
+ },
+ {
+ "delta_id": "s2_144_iwooos_command_palette_security_entry_unified",
+ "display_order": 173,
+ "completed_stage": "S2.144 IwoooS 命令面板資安入口收斂",
+ "progress_axis": "framework_detail",
+ "headline_percent_delta": 0,
+ "framework_delta_visible": true,
+ "why_headline_unchanged": "IwoooS 只把命令面板中的 security / 安全 / 安全合規 / compliance / 合規 等搜尋詞統一導向 /iwooos,移除命令面板對 /security-compliance 的獨立直達動作;command_palette_security_action_unified_to_iwooos=true、command_palette_security_compliance_direct_action_allowed=false、command_palette_security_keywords_route_to_iwooos=true、runtime_execution_authorized=false、active_runtime_gate_count=0,不把入口收斂當 runtime 授權、審批、掃描、修復、部署、主機更新、GitHub primary 切換或 Gitea 停用。",
+ "runtime_delta": false,
+ "execution_authorized": false,
+ "not_authorization": true
}
],
"next_safe_actions": [
diff --git a/scripts/security/security-mirror-progress-guard.py b/scripts/security/security-mirror-progress-guard.py
index 804b8690d..94c0d6c07 100755
--- a/scripts/security/security-mirror-progress-guard.py
+++ b/scripts/security/security-mirror-progress-guard.py
@@ -163,6 +163,9 @@ def validate(root: Path) -> None:
sidebar = (root / "apps" / "web" / "src" / "components" / "layout" / "sidebar.tsx").read_text(
encoding="utf-8"
)
+ command_palette = (
+ root / "apps" / "web" / "src" / "components" / "command-palette" / "CommandPalette.tsx"
+ ).read_text(encoding="utf-8")
web_messages_zh = load_json(root / "apps" / "web" / "messages" / "zh-TW.json")
web_messages_en = load_json(root / "apps" / "web" / "messages" / "en.json")
@@ -219,6 +222,11 @@ def validate(root: Path) -> None:
assert_text_not_contains("sidebar.iwooos_security_duplicate_label", sidebar, "labelKey: 'iwooosSecurityCompliance'")
assert_text_contains("sidebar.security_compliance_alias", sidebar, "aliases: ['/security-compliance']")
assert_text_not_contains("sidebar.duplicate_security_compliance_entry", sidebar, "id: 'security-compliance'")
+ assert_text_contains("command_palette.iwooos_entry", command_palette, "id: 'iwooos'")
+ assert_text_contains("command_palette.iwooos_route", command_palette, "nav('/iwooos')")
+ assert_text_contains("command_palette.security_keyword", command_palette, "'安全合規'")
+ assert_text_not_contains("command_palette.legacy_security_entry", command_palette, "id: 'security'")
+ assert_text_not_contains("command_palette.legacy_security_compliance_route", command_palette, "nav('/security-compliance')")
assert_equal(
"web_messages.zh-TW.nav.iwooos",
web_messages_zh["nav"]["iwooos"],
@@ -600,6 +608,7 @@ def validate(root: Path) -> None:
"s2_141_iwooos_all_product_coverage_snapshot",
"s2_142_iwooos_first_unlock_path_first_layer",
"s2_143_iwooos_command_map_first_layer",
+ "s2_144_iwooos_command_palette_security_entry_unified",
]
assert_equal(
"progress_delta_ledger.delta_ids",
@@ -1369,6 +1378,18 @@ def validate(root: Path) -> None:
"iwooos_projection.summary.command_palette_entry_added",
iwooos_projection["summary"]["command_palette_entry_added"],
)
+ assert_true(
+ "iwooos_projection.summary.command_palette_security_action_unified_to_iwooos",
+ iwooos_projection["summary"]["command_palette_security_action_unified_to_iwooos"],
+ )
+ assert_false(
+ "iwooos_projection.summary.command_palette_security_compliance_direct_action_allowed",
+ iwooos_projection["summary"]["command_palette_security_compliance_direct_action_allowed"],
+ )
+ assert_true(
+ "iwooos_projection.summary.command_palette_security_keywords_route_to_iwooos",
+ iwooos_projection["summary"]["command_palette_security_keywords_route_to_iwooos"],
+ )
assert_equal("iwooos_projection.summary.contract_count", iwooos_projection["summary"]["contract_count"], manifest_count)
assert_equal(
"iwooos_projection.summary.active_runtime_gate_count",