From 64eef5a252b63aad78f4fc2f2c0dcbd6478300fa Mon Sep 17 00:00:00 2001 From: ogt Date: Wed, 24 Jun 2026 23:07:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(iwooos):=20=E9=A1=AF=E7=A4=BA=20Wazuh=20?= =?UTF-8?q?=E5=8D=B3=E6=99=82=E4=B8=AD=E7=B9=BC=E8=B3=87=E6=96=99=E9=96=98?= =?UTF-8?q?=E9=96=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/messages/en.json | 53 +++++ apps/web/messages/zh-TW.json | 53 +++++ apps/web/src/app/[locale]/iwooos/page.tsx | 184 ++++++++++++++++++ docs/LOGBOOK.md | 35 ++++ ...OOOS-WAZUH-READONLY-API-RELEASE-HANDOFF.md | 15 ++ 5 files changed, 340 insertions(+) diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 819ca65c..3b453ab6 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -19003,6 +19003,59 @@ } } }, + "wazuhLiveMetadataEnvGate": { + "eyebrow": "Wazuh 即時中繼資料環境閘門", + "title": "Wazuh 查詢要等正式路由、負責人與機密中繼資料都過關", + "subtitle": "這張卡把 Wazuh 即時中繼資料啟用前的條件拆開:正式路由讀回、伺服端環境變數負責人、機密來源中繼資料、管理節點健康、唯讀帳號範圍與啟用後讀回都要先補齊;目前即時查詢、主動回應、主機寫入與執行期閘門都是 0。", + "checkLabel": "檢核", + "stateLabel": "狀態", + "boundaryTitle": "即時中繼資料環境邊界", + "boundaryIntro": "以下鍵值固定:正式路由 200、Wazuh 已建置或 UI 可見都不能直接代表可以查 Wazuh 即時中繼資料;不得收機密明文值、不得改 K8s 機密、不得用 Nginx 或主機操作繞過釋出閘門。", + "summary": { + "routeReadback": { + "label": "路由讀回", + "detail": "正式部署後讀回尚未通過,因此仍不能啟用即時中繼資料。" + }, + "owner": { + "label": "負責人回覆", + "detail": "伺服端環境變數與啟用責任尚未被審查者接受。" + }, + "secretMeta": { + "label": "機密中繼資料", + "detail": "只允許機密來源中繼資料與負責人,不收密碼、權杖或雜湊值。" + }, + "liveQuery": { + "label": "即時查詢", + "detail": "Wazuh API 即時查詢授權目前維持 0。" + } + }, + "items": { + "releaseReadback": { + "title": "先等正式路由不再 404", + "body": "部署後必須用正式讀回指令驗證 `/api/iwooos/wazuh`,不能用部署前 404 或閘道繞路當成功。" + }, + "serverEnv": { + "title": "伺服端環境變數需負責人", + "body": "IWOOOS_WAZUH_READONLY_ENABLED 與 Wazuh API 環境變數只能由正式伺服端流程注入,不能寫到前端 bundle。" + }, + "secretMetadata": { + "title": "機密只收中繼資料", + "body": "只記錄注入來源、負責人、維護窗口與回滾路徑;不得貼密碼、權杖、Cookie、工作階段或任何機密片段。" + }, + "managerHealth": { + "title": "Wazuh 管理節點健康待參照", + "body": "需要管理節點、API 與 TLS 健康狀態的脫敏參照;不能只用 Wazuh 已安裝或儀表板可見判斷。" + }, + "readonlyScope": { + "title": "唯讀帳號範圍待驗", + "body": "只允許中繼資料查詢範圍;主動回應、規則變更、解碼器變更與主機操作必須留在另一個閘門。" + }, + "postEnable": { + "title": "啟用後還要讀回", + "body": "即使未來環境變數啟用,也必須再驗證不回傳原始載荷、代理端原名、內網 IP 或機密。" + } + } + }, "socSiemKaliWazuhIntegration": { "eyebrow": "SOC / SIEM / Kali 112 整合控制", "title": "把 Wazuh、Kali、告警鏈與主流資安機制接成同一條證據線", diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index 819ca65c..3b453ab6 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -19003,6 +19003,59 @@ } } }, + "wazuhLiveMetadataEnvGate": { + "eyebrow": "Wazuh 即時中繼資料環境閘門", + "title": "Wazuh 查詢要等正式路由、負責人與機密中繼資料都過關", + "subtitle": "這張卡把 Wazuh 即時中繼資料啟用前的條件拆開:正式路由讀回、伺服端環境變數負責人、機密來源中繼資料、管理節點健康、唯讀帳號範圍與啟用後讀回都要先補齊;目前即時查詢、主動回應、主機寫入與執行期閘門都是 0。", + "checkLabel": "檢核", + "stateLabel": "狀態", + "boundaryTitle": "即時中繼資料環境邊界", + "boundaryIntro": "以下鍵值固定:正式路由 200、Wazuh 已建置或 UI 可見都不能直接代表可以查 Wazuh 即時中繼資料;不得收機密明文值、不得改 K8s 機密、不得用 Nginx 或主機操作繞過釋出閘門。", + "summary": { + "routeReadback": { + "label": "路由讀回", + "detail": "正式部署後讀回尚未通過,因此仍不能啟用即時中繼資料。" + }, + "owner": { + "label": "負責人回覆", + "detail": "伺服端環境變數與啟用責任尚未被審查者接受。" + }, + "secretMeta": { + "label": "機密中繼資料", + "detail": "只允許機密來源中繼資料與負責人,不收密碼、權杖或雜湊值。" + }, + "liveQuery": { + "label": "即時查詢", + "detail": "Wazuh API 即時查詢授權目前維持 0。" + } + }, + "items": { + "releaseReadback": { + "title": "先等正式路由不再 404", + "body": "部署後必須用正式讀回指令驗證 `/api/iwooos/wazuh`,不能用部署前 404 或閘道繞路當成功。" + }, + "serverEnv": { + "title": "伺服端環境變數需負責人", + "body": "IWOOOS_WAZUH_READONLY_ENABLED 與 Wazuh API 環境變數只能由正式伺服端流程注入,不能寫到前端 bundle。" + }, + "secretMetadata": { + "title": "機密只收中繼資料", + "body": "只記錄注入來源、負責人、維護窗口與回滾路徑;不得貼密碼、權杖、Cookie、工作階段或任何機密片段。" + }, + "managerHealth": { + "title": "Wazuh 管理節點健康待參照", + "body": "需要管理節點、API 與 TLS 健康狀態的脫敏參照;不能只用 Wazuh 已安裝或儀表板可見判斷。" + }, + "readonlyScope": { + "title": "唯讀帳號範圍待驗", + "body": "只允許中繼資料查詢範圍;主動回應、規則變更、解碼器變更與主機操作必須留在另一個閘門。" + }, + "postEnable": { + "title": "啟用後還要讀回", + "body": "即使未來環境變數啟用,也必須再驗證不回傳原始載荷、代理端原名、內網 IP 或機密。" + } + } + }, "socSiemKaliWazuhIntegration": { "eyebrow": "SOC / SIEM / Kali 112 整合控制", "title": "把 Wazuh、Kali、告警鏈與主流資安機制接成同一條證據線", diff --git a/apps/web/src/app/[locale]/iwooos/page.tsx b/apps/web/src/app/[locale]/iwooos/page.tsx index 006dadae..a07ac58f 100644 --- a/apps/web/src/app/[locale]/iwooos/page.tsx +++ b/apps/web/src/app/[locale]/iwooos/page.tsx @@ -271,6 +271,14 @@ type WazuhIntrusionReadbackItem = { tone: 'steady' | 'warn' | 'locked' } +type WazuhLiveMetadataEnvGateItem = { + key: string + check: string + state: string + icon: typeof ShieldCheck + tone: 'steady' | 'warn' | 'locked' +} + type SocSiemKaliWazuhIntegrationItem = { key: string check: string @@ -2182,6 +2190,50 @@ const wazuhIntrusionReadbackBoundaries = [ 'not_authorization=true', ] as const +const wazuhLiveMetadataEnvGateSummary = [ + { key: 'routeReadback', value: '0', icon: Route, tone: 'locked' }, + { key: 'owner', value: '0', icon: ClipboardCheck, tone: 'locked' }, + { key: 'secretMeta', value: '0', icon: Lock, tone: 'locked' }, + { key: 'liveQuery', value: '0', icon: Radar, tone: 'locked' }, +] as const + +const wazuhLiveMetadataEnvGateItems: WazuhLiveMetadataEnvGateItem[] = [ + { key: 'releaseReadback', check: 'ENV-1', state: '待部署驗證', icon: Route, tone: 'locked' }, + { key: 'serverEnv', check: 'ENV-2', state: '待負責人', icon: Server, tone: 'warn' }, + { key: 'secretMetadata', check: 'ENV-3', state: '只收中繼資料', icon: Lock, tone: 'locked' }, + { key: 'managerHealth', check: 'ENV-4', state: '待健康參照', icon: Activity, tone: 'warn' }, + { key: 'readonlyScope', check: 'ENV-5', state: '待範圍參照', icon: ShieldCheck, tone: 'warn' }, + { key: 'postEnable', check: 'ENV-6', state: '待讀回驗證', icon: SearchCheck, tone: 'locked' }, +] as const + +const wazuhLiveMetadataEnvGateBoundaries = [ + 'wazuh_live_metadata_env_gate_visible=true', + 'wazuh_live_metadata_env_gate_server_side_env_key_count=4', + 'wazuh_live_metadata_env_gate_required_owner_field_count=15', + 'wazuh_live_metadata_env_gate_reviewer_check_count=15', + 'wazuh_live_metadata_env_gate_outcome_lane_count=10', + 'wazuh_live_metadata_env_gate_blocked_action_count=23', + 'wazuh_live_metadata_env_gate_production_route_readback_passed_count=0', + 'wazuh_live_metadata_env_gate_live_metadata_owner_response_accepted_count=0', + 'wazuh_live_metadata_env_gate_secret_source_metadata_accepted_count=0', + 'wazuh_live_metadata_env_gate_wazuh_manager_health_ref_accepted_count=0', + 'wazuh_live_metadata_env_gate_readonly_account_scope_accepted_count=0', + 'wazuh_live_metadata_env_gate_post_enable_readback_passed_count=0', + 'wazuh_live_metadata_env_gate_wazuh_api_live_query_authorized_count=0', + 'wazuh_live_metadata_env_gate_wazuh_active_response_authorized_count=0', + 'wazuh_live_metadata_env_gate_runtime_gate_count=0', + 'secret_value_collection_allowed=false', + 'raw_wazuh_payload_storage_allowed=false', + 'k8s_secret_patch_authorized=false', + 'argocd_sync_authorized=false', + 'docker_restart_authorized=false', + 'nginx_gateway_workaround_authorized=false', + 'firewall_change_authorized=false', + 'host_write_authorized=false', + 'kali_active_scan_authorized=false', + 'not_authorization=true', +] as const + const socSiemKaliWazuhIntegrationSummary = [ { key: 'frameworks', value: '7', icon: ClipboardCheck, tone: 'steady' }, { key: 'domains', value: '16', icon: Network, tone: 'steady' }, @@ -7669,6 +7721,137 @@ function IwoooSWazuhIntrusionReadbackBoard() { ) } +function IwoooSWazuhLiveMetadataEnvGateBoard() { + const t = useTranslations('iwooos.wazuhLiveMetadataEnvGate') + const textWrap = { overflowWrap: 'anywhere' as const, wordBreak: 'break-word' as const } + + return ( +
+
+
+
+
+ + {t('eyebrow')} +
+

{t('title')}

+

+ {t('subtitle')} +

+
+ +
+ {wazuhLiveMetadataEnvGateSummary.map(item => { + const Icon = item.icon + return ( +
+
+ {t(`summary.${item.key}.label` as never)} + +
+
+ {item.value} +
+

+ {t(`summary.${item.key}.detail` as never)} +

+
+ ) + })} +
+
+ +
+ {wazuhLiveMetadataEnvGateItems.map(item => { + const Icon = item.icon + return ( +
+
+ + {t('checkLabel')} {item.check} + + +
+
+
+ {t(`items.${item.key}.title` as never)} +
+
+ {t('stateLabel')}:{item.state} +
+
+

+ {t(`items.${item.key}.body` as never)} +

+
+ ) + })} +
+ +
+ + {t('boundaryTitle')} + +

+ {t('boundaryIntro')} +

+
+ {wazuhLiveMetadataEnvGateBoundaries.map(item => ( + + {item} + + ))} +
+
+
+
+ ) +} + function IwoooSSocSiemKaliWazuhIntegrationBoard() { const t = useTranslations('iwooos.socSiemKaliWazuhIntegration') const textWrap = { overflowWrap: 'anywhere' as const, wordBreak: 'break-word' as const } @@ -20592,6 +20775,7 @@ export default function IwoooSPage({ params }: { params: { locale: string } }) { + diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 9376abb2..d9e3566e 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -35,6 +35,41 @@ **邊界**:本輪沒有手動 import、沒有 Drive write、沒有 DB restore / truncate、沒有 Docker / Nginx / firewall / K8s / ArgoCD runtime 寫入,沒有 Wazuh / SOC 修改,沒有使用聊天中的密碼,也沒有讀取或保存 secret。 +## 2026-06-24|IwoooS Wazuh 即時中繼資料環境閘門前台驗證 + +**背景**:Wazuh 只讀 API source-side 修補、release gate、release lane preflight、owner request / acceptance 與 live metadata env gate 已完成,但 production 尚未部署,`/api/iwooos/wazuh` 仍不可用來代表 Wazuh runtime 狀態。本輪補上 IwoooS 前台可視化卡片,讓使用者在 `/zh-TW/iwooos` 直接看到「正式路由讀回、伺服端環境變數負責人、機密中繼資料、管理節點健康、唯讀帳號範圍、啟用後讀回」全部仍為 `0`,避免把 Wazuh 已建置或 UI 可見誤判為可查 live metadata。 + +**Source-side 完成**: +- `apps/web/src/app/[locale]/iwooos/page.tsx` 新增 `IwoooSWazuhLiveMetadataEnvGateBoard`,位置在 Wazuh 入侵 readback 與 SOC / SIEM / Kali 整合卡之間。 +- `apps/web/messages/zh-TW.json` 與 `apps/web/messages/en.json` 新增同一份繁中鏡像文案;前台文案改為「負責人回覆、路由讀回、機密中繼資料、即時查詢」等產品治理語,不放工作視窗逐字稿、委派 XML、聊天內容或個人英文名稱。 +- 卡片邊界固定:`wazuh_live_metadata_env_gate_visible=true`、`production_route_readback_passed_count=0`、`live_metadata_owner_response_accepted_count=0`、`secret_source_metadata_accepted_count=0`、`wazuh_api_live_query_authorized_count=0`、`wazuh_active_response_authorized_count=0`、`runtime_gate_count=0`、`secret_value_collection_allowed=false`、`host_write_authorized=false`、`kali_active_scan_authorized=false`。 + +**驗證**: +- `node -e "JSON.parse(...zh-TW...); JSON.parse(...en...)"`:通過。 +- `cmp -s apps/web/messages/zh-TW.json apps/web/messages/en.json`:通過,維持繁中鏡像。 +- `pytest apps/api/tests/test_iwooos_wazuh_api.py`:`4 passed`。 +- `python3 scripts/security/security-mirror-progress-guard.py --root .`:`SECURITY_MIRROR_PROGRESS_GUARD_OK`。 +- `python3 scripts/security/wazuh-readonly-route-boundary-guard.py --root .`:`route=2 public_ui_files=1 forbidden=0 runtime_gate=0`。 +- `python3 scripts/security/wazuh-readonly-release-gate.py --root .`:`source=1 push=0 deploy=0 readback=0 runtime_gate=0`。 +- `python3 scripts/security/wazuh-readonly-release-lane-preflight.py --root .`:`ready=0 acks=0/6 evidence=0/6 runtime_gate=0`。 +- `python3 scripts/security/wazuh-readonly-release-owner-request.py --root .`:`drafts=1 sent=0 accepted=0 runtime_gate=0`。 +- `python3 scripts/security/wazuh-readonly-release-owner-response-acceptance.py --root .`:`received=0 accepted=0 acks=0/6 evidence=0/6 runtime_gate=0`。 +- `python3 scripts/security/wazuh-readonly-live-metadata-env-gate.py --root .`:`route_readback=0 owner=0 secret_meta=0 live_query=0 runtime_gate=0`。 +- `pnpm --filter @awoooi/web typecheck`:通過。 +- 首次未帶 `NEXT_PUBLIC_API_URL` 的 build 依既有前端禁令在 prerender 階段 fail;重跑 `NEXT_PUBLIC_API_URL=https://awoooi.wooo.work NEXT_PRIVATE_BUILD_WORKER_COUNT=1 SENTRY_SUPPRESS_GLOBAL_ERROR_HANDLER_FILE_WARNING=1 pnpm --filter @awoooi/web build` 通過,`92/92` static pages,`/zh-TW/iwooos` route size `61.8 kB`、First Load JS `292 kB`。 +- 本機 preview `http://localhost:3137/zh-TW/iwooos?_v=wazuh-live-metadata-env-local` 桌機寬度:卡片可見、`scrollWidth=clientWidth=1434`、水平溢出 `false`、未命中工作視窗、委派、來源執行緒、外部對話與通知暱稱等內部協作詞;卡片也未命中英文流程裸字。 +- 本機 preview 手機寬度 `390x844`:卡片可見、`scrollWidth=clientWidth=384`、水平溢出 `false`,同樣未命中工作視窗字樣與英文流程裸字。 + +**完成度**: +- Wazuh live metadata env gate source / guard:`100%`。 +- IwoooS 前台卡片 source / 本機桌機與手機驗證:`100%`。 +- Production deploy:`0%`。 +- Production `/api/iwooos/wazuh` readback:`0%`,部署前仍只允許 `predeploy_404_observed`。 +- Wazuh server-side env enable:`0%`。 +- Wazuh live query、active response、host write、Kali active scan、SOAR action:全部維持 `0 / false`。 + +**邊界**:本輪沒有 push、沒有 deploy、沒有 Nginx / Docker / K8s / firewall / Wazuh manager / secret / runtime 寫入,沒有 active scan,沒有收集或保存任何 secret value;只做 source、docs、guard、本機 build 與本機瀏覽器驗證。 + ## 2026-06-24|22:40 MOMO source absence readback 與資料 freshness blocker 定位 **背景**:22:17 已完成 MOMO import-boundary production deploy 驗證與 full cold-start refresh,但 cold-start 仍因 `MOMO_DAILY_FRESHNESS 7|2026-06-17` 保持 `BLOCKED=1`。本輪只做 MOMO scheduler / DB / import metadata 的 read-only 追查,目標是判斷資料停更是服務、版本、DB 同步、排程或來源缺席。 diff --git a/docs/security/IWOOOS-WAZUH-READONLY-API-RELEASE-HANDOFF.md b/docs/security/IWOOOS-WAZUH-READONLY-API-RELEASE-HANDOFF.md index 48c1c005..86d1109a 100644 --- a/docs/security/IWOOOS-WAZUH-READONLY-API-RELEASE-HANDOFF.md +++ b/docs/security/IWOOOS-WAZUH-READONLY-API-RELEASE-HANDOFF.md @@ -40,6 +40,9 @@ - `docs/security/wazuh-readonly-release-owner-request.snapshot.json` - `docs/security/wazuh-readonly-release-owner-response-acceptance.snapshot.json` - `docs/security/wazuh-readonly-live-metadata-env-gate.snapshot.json` +- `apps/web/src/app/[locale]/iwooos/page.tsx` +- `apps/web/messages/zh-TW.json` +- `apps/web/messages/en.json` - `docs/LOGBOOK.md` 完成內容: @@ -57,6 +60,7 @@ - 新增 release lane preflight snapshot 與 guard,固定正式 release 前必須選擇 `formal_gitea_merge`、`formal_patch_apply` 或 `maintainer_local_push_with_safe_credential` 其中一條合規 lane,且 owner ack / evidence 未到齊前不得 push、deploy、force push、使用明文 token workaround 或改 runtime。 - 新增 release owner request 草稿與 owner response acceptance 帳本,將 required ack flags、required evidence fields、allowed release methods、blocked actions、forbidden payloads 與 reviewer checks 機器可讀化;目前 request sent、response received / accepted、release ready、runtime gate 全部維持 `0`。 - 新增 live metadata env gate,固定部署後要先通過 production route readback、server-side env owner response、secret source metadata、Wazuh manager health ref、readonly account scope、post-enable readback、rollback 與 no-secret / no-raw-payload attestation;目前 live query authorized 仍為 `0`。 +- 新增 IwoooS 前台「Wazuh 即時中繼資料環境閘門」卡片,公開顯示上述 gate 的 `0 / false` 邊界;文案全部為繁體中文治理語,不放工作視窗逐字稿、委派 XML、聊天內容或個人英文名稱。 ## 已完成驗證 @@ -74,6 +78,10 @@ python3 scripts/security/security-mirror-progress-guard.py --root . python3 scripts/ops/doc-secrets-sanity-check.py docs apps/api/src/api/v1/iwooos.py apps/web/src/app/api/iwooos/wazuh/route.ts scripts/security/wazuh-readonly-route-boundary-guard.py scripts/security/wazuh-readonly-production-readback.py scripts/security/wazuh-readonly-release-gate.py scripts/security/wazuh-readonly-release-lane-preflight.py scripts/security/wazuh-readonly-release-owner-request.py scripts/security/wazuh-readonly-release-owner-response-acceptance.py scripts/security/wazuh-readonly-live-metadata-env-gate.py python3 -m py_compile apps/api/src/api/v1/iwooos.py scripts/security/wazuh-readonly-route-boundary-guard.py scripts/security/wazuh-readonly-production-readback.py scripts/security/wazuh-readonly-release-gate.py scripts/security/wazuh-readonly-release-lane-preflight.py scripts/security/wazuh-readonly-release-owner-request.py scripts/security/wazuh-readonly-release-owner-response-acceptance.py scripts/security/wazuh-readonly-live-metadata-env-gate.py scripts/security/security-mirror-progress-guard.py git diff --check +node -e "JSON.parse(require('fs').readFileSync('apps/web/messages/zh-TW.json','utf8')); JSON.parse(require('fs').readFileSync('apps/web/messages/en.json','utf8')); console.log('i18n json ok')" +cmp -s apps/web/messages/zh-TW.json apps/web/messages/en.json +pnpm --filter @awoooi/web typecheck +NEXT_PUBLIC_API_URL=https://awoooi.wooo.work NEXT_PRIVATE_BUILD_WORKER_COUNT=1 SENTRY_SUPPRESS_GLOBAL_ERROR_HANDLER_FILE_WARNING=1 pnpm --filter @awoooi/web build ``` 驗證結果: @@ -89,6 +97,12 @@ git diff --check - `doc-secrets-sanity-check`:`DOC_SECRET_SANITY_OK scanned_files=973`。 - `py_compile`:通過。 - `git diff --check`:通過。 +- i18n JSON parse:通過。 +- `zh-TW` / `en` messages mirror:通過。 +- `pnpm --filter @awoooi/web typecheck`:通過。 +- Web production build:通過,`92/92` static pages,`/zh-TW/iwooos` route size `61.8 kB`、First Load JS `292 kB`;build env 使用公網 `NEXT_PUBLIC_API_URL=https://awoooi.wooo.work`,未使用內網 IP。 +- 本機 preview desktop:`/zh-TW/iwooos` 卡片可見,水平溢出 `false`,沒有工作視窗 / 委派 / 對話字樣,卡片沒有英文流程裸字。 +- 本機 preview mobile `390x844`:卡片可見,水平溢出 `false`,同樣沒有工作視窗 / 委派 / 對話字樣。 ## 乾淨套用 Proof @@ -185,6 +199,7 @@ python3 scripts/security/wazuh-readonly-production-readback.py --json | Wazuh release lane preflight | `100%` | 已完成;owner acks `0/6`、evidence `0/6`、正式 release ready `0` | | Wazuh release owner request / acceptance | `100%` | 已完成只讀草稿與收件帳本;request sent `0`、response accepted `0` | | Wazuh live metadata env gate | `100%` | 已完成只讀 gate;route readback / owner / secret metadata / live query 仍 `0` | +| IwoooS 前台 Wazuh live metadata env gate 卡片 | `100%` | source-side 與本機桌機 / 手機驗證完成;production deploy 仍 `0` | | 乾淨套用 proof | `100%` | patch set 可落在最新 `gitea/main` 並通過同組 guard;最終 hash 以 release 前 readback 為準 | | Gitea push | `0%` | 受控 workspace HTTPS credential 缺失 | | Production deploy / readback | `0%` | 等待 release lane |