diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json
index 3d23b9cf..ea05b61d 100644
--- a/apps/web/messages/en.json
+++ b/apps/web/messages/en.json
@@ -3714,7 +3714,7 @@
"reasons": {
"providerHeartbeatNoMatch": "Provider 有心跳,但這個 Incident 尚未匹配",
"noMatchingProviderSourceEvent": "查無可匹配的 Sentry / SigNoz 事件",
- "noIncidentIds": "缺 Incident ID,無法關聯",
+ "noIncidentIds": "缺事件編號,無法關聯",
"incidentNotFound": "Incident 記錄不存在",
"fetchFailed": "讀取來源關聯失敗"
},
@@ -10988,7 +10988,7 @@
},
"kali112": {
"title": "Kali 112 已納入資安網",
- "body": "192.168.0.112 已在主機覆蓋與證據框架中;目前是只讀納管,不是已批准主動掃描、憑證掃描、/execute 或主機更新。"
+ "body": "2026-05-31 17:22 已用既有 SSH key 完成只讀快照:Kali Rolling、kernel 6.16.8、root disk 26%、待更新套件 1994、失敗 systemd unit 1。沒有啟動掃描、/execute、主機更新或重啟。"
},
"allProducts": {
"title": "所有產品先套只讀框架",
diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json
index 3d23b9cf..ea05b61d 100644
--- a/apps/web/messages/zh-TW.json
+++ b/apps/web/messages/zh-TW.json
@@ -3714,7 +3714,7 @@
"reasons": {
"providerHeartbeatNoMatch": "Provider 有心跳,但這個 Incident 尚未匹配",
"noMatchingProviderSourceEvent": "查無可匹配的 Sentry / SigNoz 事件",
- "noIncidentIds": "缺 Incident ID,無法關聯",
+ "noIncidentIds": "缺事件編號,無法關聯",
"incidentNotFound": "Incident 記錄不存在",
"fetchFailed": "讀取來源關聯失敗"
},
@@ -10988,7 +10988,7 @@
},
"kali112": {
"title": "Kali 112 已納入資安網",
- "body": "192.168.0.112 已在主機覆蓋與證據框架中;目前是只讀納管,不是已批准主動掃描、憑證掃描、/execute 或主機更新。"
+ "body": "2026-05-31 17:22 已用既有 SSH key 完成只讀快照:Kali Rolling、kernel 6.16.8、root disk 26%、待更新套件 1994、失敗 systemd unit 1。沒有啟動掃描、/execute、主機更新或重啟。"
},
"allProducts": {
"title": "所有產品先套只讀框架",
diff --git a/apps/web/src/app/[locale]/iwooos/page.tsx b/apps/web/src/app/[locale]/iwooos/page.tsx
index ecb60492..81b95112 100644
--- a/apps/web/src/app/[locale]/iwooos/page.tsx
+++ b/apps/web/src/app/[locale]/iwooos/page.tsx
@@ -636,7 +636,7 @@ const postureMetrics: PostureMetric[] = [
const fastProgressItems: FastProgressItem[] = [
{ key: 'done', value: '7 頁', icon: CheckCircle2, tone: 'steady' },
- { key: 'kali112', value: '已納管', icon: ShieldCheck, tone: 'warn' },
+ { key: 'kali112', value: '只讀通過', icon: ShieldCheck, tone: 'warn' },
{ key: 'allProducts', value: '6 / 6', icon: Radar, tone: 'steady' },
{ key: 'runtime', value: 'Gate 0', icon: Lock, tone: 'locked' },
]
diff --git a/apps/web/src/components/aiops/timeline/TimelineFilter.tsx b/apps/web/src/components/aiops/timeline/TimelineFilter.tsx
index 49b824e4..b8d154da 100644
--- a/apps/web/src/components/aiops/timeline/TimelineFilter.tsx
+++ b/apps/web/src/components/aiops/timeline/TimelineFilter.tsx
@@ -36,7 +36,7 @@ export function TimelineFilter({ filter, onChange, incidentCount }: TimelineFilt
return (
- {/* Incident ID 搜尋 */}
+ {/* 事件編號搜尋 */}
host=kali, OS=Kali GNU/Linux Rolling, kernel=Linux 6.16.8+kali-amd64
+ -> uptime=up 3 weeks, 1 day, 21 hours, 58 minutes
+ -> load=0.09 0.12 0.15, memory=885Mi/7.8Gi, root disk=19G/79G 26%
+ -> failed_units=1, upgradable_lines=1994, listening_tcp=7, listening_udp=2
+python3 -m json.tool docs/security/kali-integration-status.snapshot.json
+ -> pass
+python3 -m json.tool apps/web/messages/zh-TW.json / en.json
+ -> pass
+python3 scripts/security/security-mirror-progress-guard.py
+ -> SECURITY_MIRROR_PROGRESS_GUARD_OK
+python3 scripts/security/source-control-owner-response-guard.py
+ -> SOURCE_CONTROL_OWNER_RESPONSE_GUARD_OK
+pnpm --dir apps/web run typecheck
+ -> pass
+NEXT_PUBLIC_API_URL=https://awoooi.wooo.work pnpm --dir apps/web run build
+ -> pass
+本地 Playwright(production build / next start):
+ /zh-TW/iwooos 與 /en/iwooos -> Kali 112 只讀快照文案可見、無 Incident ID 英文殘留、無水平溢出
+```
+
+**進度邊界**:
+
+- 整體資安網 headline 仍維持 `61%`:Kali 112 已從「文件納管」推進為「可連線、已驗證、可前台呈現、guard 鎖住的只讀實機證據」,但尚未到 scan result ingestion、維護窗口更新或 runtime gate,因此先不灌水成 headline +1。
+- active runtime gate 仍為 `0`;本輪沒有掃描、credentialed scan、`/execute`、主機更新、套件升級、調校、重啟、repo / refs / workflow 變更或 GitHub primary 切換。
+- 後續要真正做 Kali 更新 / 調校,仍需維護窗口、rollback / reboot gate、failed unit 調查與人工批准。
+
## 2026-05-31|Telegram / AwoooP 執行完成與失敗判定明確化
**背景**:
diff --git a/docs/security/KALI-INTEGRATION-STATUS.md b/docs/security/KALI-INTEGRATION-STATUS.md
index b44e5dac..26d685d0 100644
--- a/docs/security/KALI-INTEGRATION-STATUS.md
+++ b/docs/security/KALI-INTEGRATION-STATUS.md
@@ -2,7 +2,7 @@
| 項目 | 內容 |
|------|------|
-| 日期 | 2026-05-13 |
+| 日期 | 2026-05-13;最新只讀快照 2026-05-31 17:22(台北) |
| Host | `192.168.0.112` |
| Asset key | `host:kali-112` |
| 狀態 | `partial_runtime_health_integrated` |
@@ -22,6 +22,27 @@ Kali 主機不是只有文件預留;`192.168.0.112` 目前已經有 live runti
但它還沒有完成「資安網閉環」整合:Kali scan result 尚未正式寫入 AWOOOI asset / compliance 表,也尚未 mirror 成 AwoooP Runtime State、Channel Event 或 Audit evidence。因此目前判定是「健康與基礎掃描已存在,治理閉環尚未接通」。
+## 0.1 2026-05-31 只讀實機快照
+
+本輪用既有 SSH key 完成 read-only 連線檢查,沒有輸入或保存密碼,沒有啟動 scan、沒有呼叫 `/execute`、沒有執行 package update、沒有調整設定、沒有重啟。
+
+| 項目 | 結果 |
+|------|------|
+| 觀測時間 | `2026-05-31T17:22:20+08:00` |
+| Collection mode | `ssh_batch_read_only_existing_key` |
+| Hostname | `kali` |
+| OS | `Kali GNU/Linux Rolling` |
+| Kernel | `Linux 6.16.8+kali-amd64` |
+| Uptime | `up 3 weeks, 1 day, 21 hours, 58 minutes` |
+| Load 1/5/15 | `0.09 0.12 0.15` |
+| Memory | `885Mi/7.8Gi` |
+| Root disk | `19G/79G 26%` |
+| Failed systemd units | `1` |
+| Upgradable packages | `1994` |
+| Listening TCP / UDP | `7 / 2` |
+
+結論:Kali `192.168.0.112` 已可被 IwoooS 以只讀方式納入證據鏈;但 `failed_systemd_unit_count=1` 與 `upgradable_package_count=1994` 代表後續仍需要維護窗口、rollback / reboot gate 與人工批准,不能直接把「可連線」解讀為已完成主機調校或安全更新。
+
## 1. 已確認的 live 狀態
| 項目 | 結果 |
diff --git a/docs/security/kali-integration-status.snapshot.json b/docs/security/kali-integration-status.snapshot.json
index 183cc5bb..b6405318 100644
--- a/docs/security/kali-integration-status.snapshot.json
+++ b/docs/security/kali-integration-status.snapshot.json
@@ -52,6 +52,27 @@
"remaining_upgradable_count": 1994,
"full_upgrade_status": "not_run_requires_maintenance_window"
},
+ "latest_read_only_observation": {
+ "observed_at_utc": "2026-05-31T09:22:20Z",
+ "observed_at_taipei": "2026-05-31T17:22:20+08:00",
+ "collection_mode": "ssh_batch_read_only_existing_key",
+ "runtime_actions_executed": false,
+ "active_scan_executed": false,
+ "package_update_executed": false,
+ "host_reboot_executed": false,
+ "hostname": "kali",
+ "os": "Kali GNU/Linux Rolling",
+ "kernel": "Linux 6.16.8+kali-amd64",
+ "uptime": "up 3 weeks, 1 day, 21 hours, 58 minutes",
+ "load_1_5_15": "0.09 0.12 0.15",
+ "memory_used_total": "885Mi/7.8Gi",
+ "disk_root_used_total_percent": "19G/79G 26%",
+ "failed_systemd_unit_count": 1,
+ "upgradable_package_count": 1994,
+ "listening_tcp_socket_count": 7,
+ "listening_udp_socket_count": 2,
+ "evidence_boundary": "只讀連線與主機狀態快照;未執行掃描、更新、調校、重啟或 /execute。"
+ },
"integration_state": {
"already_integrated": [
"Kali Scanner API 在 192.168.0.112:8080 運作且 /health healthy",
diff --git a/scripts/security/security-mirror-progress-guard.py b/scripts/security/security-mirror-progress-guard.py
index 1502f367..72331d08 100755
--- a/scripts/security/security-mirror-progress-guard.py
+++ b/scripts/security/security-mirror-progress-guard.py
@@ -76,6 +76,7 @@ def validate(root: Path) -> None:
primary_gate = load_json(security_dir / "source-control-primary-readiness-gate.snapshot.json")
rollout_policy = load_json(security_dir / "security-rollout-policy.snapshot.json")
iwooos_projection = load_json(security_dir / "iwooos-posture-projection.snapshot.json")
+ kali_status = load_json(security_dir / "kali-integration-status.snapshot.json")
iwooos_projection_page = (
root / "apps" / "web" / "src" / "app" / "[locale]" / "iwooos" / "page.tsx"
).read_text(encoding="utf-8")
@@ -5552,6 +5553,37 @@ def validate(root: Path) -> None:
"docs/security/kali-integration-status.snapshot.json",
]:
assert_contains("iwooos_projection.evidence_refs", iwooos_projection["evidence_refs"], evidence_ref)
+ latest_kali_observation = kali_status["latest_read_only_observation"]
+ assert_equal(
+ "kali_status.latest_read_only_observation.observed_at_taipei",
+ latest_kali_observation["observed_at_taipei"],
+ "2026-05-31T17:22:20+08:00",
+ )
+ assert_equal(
+ "kali_status.latest_read_only_observation.collection_mode",
+ latest_kali_observation["collection_mode"],
+ "ssh_batch_read_only_existing_key",
+ )
+ assert_equal(
+ "kali_status.latest_read_only_observation.upgradable_package_count",
+ latest_kali_observation["upgradable_package_count"],
+ 1994,
+ )
+ assert_equal(
+ "kali_status.latest_read_only_observation.failed_systemd_unit_count",
+ latest_kali_observation["failed_systemd_unit_count"],
+ 1,
+ )
+ for forbidden_runtime_flag in [
+ "runtime_actions_executed",
+ "active_scan_executed",
+ "package_update_executed",
+ "host_reboot_executed",
+ ]:
+ assert_false(
+ f"kali_status.latest_read_only_observation.{forbidden_runtime_flag}",
+ latest_kali_observation[forbidden_runtime_flag],
+ )
for output in [
"display_security_posture",
"display_progress_estimate",