跳轉到

2026-W41 週報:沉默的失效

第十一份週報(W31 起算第十一週)。本週 4 張卡、5 個工作日(10-06 無卡),全部在第三輪「空間、消防、安全」:偵測(dc-32)的下游——釋放盤、門、影像、漏水。

這一週的母題只有一句:狀態是 Normal,保護其實不存在。 四張卡各交了一到兩個這樣的案例,加上上週的 DETECTION_COVERAGE_GAP,「缺東西」告警已經長到第六個。

本週卡片

卡 標題 這張卡最關鍵的一個事實
dc-33 氣體滅火與釋放盤 cross-zone 讓「一條偵測迴路被隔離」等於「自動釋放不可達」,而釋放盤仍顯示 Normal。 同一間 288 m³/20 °C 機房,Novec 1230 採 ISO 14520(5.3%)要 224.2 kg、採 NFPA 2001(4.5%)只要 188.8 kg(差 19%)——藥量取決於 standard 欄位,不是藥劑
dc-34 門禁控制器、讀卡機與 mantrap 門是兩個 Space 之間的邊,鎖是電力消費者。 40 扇 fail-safe 電磁鎖 × 500 mA = 20 A;不在後備電源上,市電斷的那一刻 40 扇門同時打開。沒有 DPS 的門,強闖與逾時未關事件結構上不可能發生
dc-35 CCTV 與影像保存 保存期間是「區間+覆寫」,屬於攝影機群組,且被稽核週期約束。 40 支 2 Mbps 連續 30 天 = 25.92 TB,80% 上限需 32.4 TB → RAID 6 8 TB 要 7 顆(6 顆差 0.4 TB);分群保存 39.4 TB vs 統一 93.3 TB,省 57.8%
dc-36 漏水偵測 漏水覆蓋是對「盛水設備」的關係,壞掉的感測器等於沒有感測器;距離讀值是線上距離不是地板座標。 45 m 路徑讀 27 m → 地板 (20, 7);同一個感測器,乾接點直驅閥漏 54.2 L、DCIM 輪詢漏 79.2 L,對 60 L 排水盤是不外溢 vs 外溢

串起來

單張卡是點,這週的線有三條,而且它們在兩個地方相交。

一、釋放鏈:偵測 → 判斷 → 放氣 → 連動,每一段都有一個靜默失效

dc-32 的 VESDA 取樣管把「煙進孔」變成「偵測迴路告警」,傳輸時間修正後 121.7 s;dc-33 把它接到釋放盤:121.7(傳輸)+ 30(預放延遲)+ 10(排放)= 161.7 s 才有藥在房間裡(天真算 81.6 s,差 80 s)。所以上游每一個延遲都直接加到下游。再往上一層,cross-zone 是刻意用冗餘換誤放抑制:要兩條有效迴路都確認才放——於是任何一條迴路被隔離(維護時常見)就讓釋放變成不可達,盤面卻是 Normal。dc-32 的孔堵塞與 dc-33 的迴路隔離,是同一種病在上下游各發作一次:偵測延遲已經變長、釋放已經不可達,兩者都沒有告警說它們發生了。

釋放之後是 Zone.interlocks:CRAH 停機、風門、門禁、警鈴。這裡有一個我把兩張卡並排後的推論(卡片本身沒寫):dc-33 的保持時間是 10 分鐘(結束於 640 s),期間 CRAH 被連動停掉;而 dc-23 算出的空氣側 ride-through 只有 24 秒量級(1600 kW、24→32 °C)。氣體滅火保護的是火,卻在 10 分鐘裡把熱載荷的排熱路徑關掉——防火的連動輸出,是冷卻鏈的一個外生故障情境。這件事目前不在任何一張卡的驗收表裡。

二、同一條 UPS 分支養著四個證人

dc-34 的 fail-safe 鎖(20 A)、dc-35 的 PoE 交換器(攝影機)、dc-36 的漏水控制器(powered_from)、dc-33 的釋放盤,都要掛在「某條 UPS 分支」上,而且它們是彼此的證人:門事件靠影像佐證(dc-35 的 DOOR_NO_VIDEO_COVERAGE)、漏水告警靠閥與 CRAH 停機收尾、釋放要門解鎖。掉一條分支:fail-safe 門全開(影像還在拍,但交換器若同掉就盲)、漏水偵測盲、釋放盤的 trouble 繼電器失電。這是共因——dc-10b 立下的「共祖永遠存在,必須是查詢」在這裡第一次要掃的不是電源,而是保護系統。四張卡各自寫了一種「連到電」的方式(見下方連貫性檢視 #4),而這件事需要一條查詢才看得見。

三、證據鏈:時間是唯一的 join key

門事件 → 影像片段,唯一的關聯是時間。dc-35:攝影機與門禁時鐘偏移 8 s、預錄 5 s → 安全窗 (87, 118),窗口根本不含事件;稽核每 14 天看一次、影像只留 7 天 → 第 8 天起永遠沒有證據,而錄影燈全程亮著。證據鏈被兩個非設備的東西約束:NTP 與稽核流程。這是設備資料第一次被人員流程反過來約束。

兩個交會點

  • 水 × 電 × 空間:dc-36 的 above 邊(水往下流)是 dc-28 空間層級 第一次被用來做縱向查詢;而水源清單裡有 CRAH(dc-22)、CDU(dc-26)、RDHx 歧管(dc-27)。dc-27 的「24 °C/60% RH 窗口是空集合」正好是會凝水的情境——凝結水就是 dc-36 要覆蓋的水源。另外液冷用乙二醇或介電液時,導電式感測線偵測不到介電液(LEAK_FLUID_UNDETECTABLE):冷卻鏈選了什麼流體,決定安全鏈能不能看見它。
  • 門 × 氣體 × 逃生:dc-33 釋放時門要解鎖還是鎖住(避免人進入已充氣區)是資料;dc-34 說 fail-safe 門因斷電而開、與聯動命令無關。兩者的規範要求本次都未查證,所以 Interlock.action 在模型裡是空的。

掉一個會連鎖到哪

掉的東西 第一層 第二層 有沒有告警說它發生了
一條偵測迴路被隔離 cross-zone 自動釋放不可達 火災時只有 Stage 1(預警),不放氣 RELEASE_PATH_DEGRADED(本週新增);盤面仍 Normal
一條 UPS 分支(鎖+交換器+漏水控制器同掛) fail-safe 門全開;攝影機斷電;漏水偵測盲 門事件沒影像、漏水沒人知道 目前沒有:四張卡各自有告警,沒有一個查詢跨系統找共同分支
稽核週期 ≥ 保存天數 告警被看到時影像已覆寫 事後調查無證據 EVIDENCE_WINDOW_EXPIRED(要人填 audit_lag_days)
感測線被污染或被靜音 (見連貫性檢視 #3)目前模型仍算它「有覆蓋」 盛水設備下方無有效防護 沒有——這是本週最該補的洞

節奏紀錄

本週 4/5:10-05(dc-33)、10-06 無卡、10-07(dc-34)、10-08(dc-35)、10-09(dc-36)。可觀察到的事實:

  • dc-35、dc-36 的 commit 都在 00:08–00:09 UTC(對應 08:00 +0800 排程,與 W40 一致)。但 dc-33 是 10-05 13:00 UTC、dc-34 是 10-07 11:58 UTC,都不在排程時間點。
  • 本次開工時 .git/*.lock 不存在,工作樹乾淨。

可能原因(無法從現有資料確認,只是假設):(a) 10-06 的排程沒觸發或沒能 commit,10-07 的 dc-34 是補跑;(b) dc-33 與 dc-34 是手動或重跑產生。這是連續兩週各缺一天(W40 缺 09-30、W41 缺 10-06),不同星期,看不出週期。佇列是教材驅動,缺一天不會讓 backlog 錯位,建議不補卡;若要查,請看 10-06 的排程執行紀錄。

連貫性檢視:這週累積的 model code

⚠ 範圍說明:repo 內仍沒有使用者實際寫的 .py 檔(已搜尋,只有 .venv 內的第三方套件),我檢視的是卡片裡的練習骨架與意涵段落(core.py、rack.py、suppression.py、access.py、video.py、leak.py)。本機若已有實作,請以實作對照。

先對帳:W40 的三個 🔴 在卡片層已收斂

dc-33 練習第 0 步建立了單一 core.py(Check 五態 + Result(check, reason) + Sourced + resolve() + Finding)與單一 rack.py(mounts、total_weight_kg() = 自重 + Σ mounts,刪掉 device_kg),驗收表第 3 列「snippet → UNDETERMINED」補上了防線,第 11 列驗了 Rack。dc-34 之後也都寫「from core import,不要重寫」。三筆的方向都對;是否真的做了要看你本機。W40 的 🟡 項目(NemaClass 跨距、space_id 命名)dc-34 沒有掃,仍在帳上。

🔴 1. Finding 的形狀在第一次被用就破了

dc-33 的 core.py:Finding(code, space_id, reason="")。但接下來四張卡產生 Finding 的對象是 Zone(release_findings(zone_id, ...),把 zone id 塞進 space_id)、Door、Camera、WaterSource/Sensor——全都不是 Space。dc-35 與 dc-36 又寫「有 Finding 就匯入,沒有就用 (code, subject) 元組」,等於兩種表示並存,而且重新開了 W40 #2 糾正過的「為獨立執行而複製」的口子。另外 W38 記下的 Finding.kind(FAULT_DOMAIN_SPLIT 不是錯誤)沒有進 core.py,而「缺東西」家族現在有六個告警,正需要一個 kind 來聚合。

收斂建議:Finding(code, subject_kind, subject_id, reason="", kind="violation"),kind ∈ {violation, missing_protection, info, ...};space_id 改名 subject_id;dc-37 起刪掉「沒有 core 就用元組」的退路(練習資料夾本來就有 core.py)。約 10 分鐘,掛進 dc-37 的第 0 步。

🔴 2. Door 有三到四種形狀,同一欄位兩個名字

  • 意涵段:Door{id, from_space, to_space, lock_mode, is_egress_path, mech_egress, dps, rex, tamper}
  • 練習 classify:Door(id, has_dps, unlock_s, propped_s)
  • 練習 door_findings:LockDoor(id, lock, egress, mech_egress, has_dps, lock_ma, on_ups)
  • dc-35 door_video_findings(doors, cameras, ...):要有 cameras,沒說從哪個 Door 來

dps vs has_dps、lock_mode vs lock、is_egress_path vs egress 是同一個欄位三個名字;而「門是兩個 Space 之間的邊」這個本卡最重要的決定(from_space/to_space),兩個練習類別都沒有。這正是 W39 Rack 的老模式:兩天出兩個不相容版本。

收斂建議:door.py 只有一個 Door(意涵段的欄位,has_dps 統一叫 dps),時序設定拆成 DoorTiming(unlock_s, propped_s) 傳入 classify;dc-35 的 Door.cameras 用 camera_ids 引用,不內嵌。

🔴 3. 「有效」的判定在三處各寫一次,而且一處放水

  • dc-33:偵測迴路 Isolate/Urgent Fault 不算有效,Minor Fault 算。
  • dc-34:沒有 DPS 就沒有事件(DOOR_UNMONITORED)。
  • dc-36:Sensor.state ∈ {ok, leak, fault, contaminated, silenced},但意涵 #1 寫「覆蓋只計 state ≠ fault」——contaminated 與 silenced 仍算有覆蓋。而同一張卡的常見誤解寫得很清楚:黃燈(線故障/污染)與未被監督的線是靜默失效。練習的 leak_findings 也只對 fault 出 LEAK_SENSOR_FAULT。

最後一條是本週最該修的洞:專門用來抓「靜默失效」的告警,自己對兩種靜默狀態放行。

收斂建議:core.py 加 effective(kind, state) -> Result,一張表集中定義每種觀測器哪些狀態算有效(line: {NORMAL, MINOR_FAULT}、sensor: {ok, leak}、door: dps == True),三個「缺東西」查詢都走它;驗收表補一列「state=contaminated/silenced → 不算覆蓋」。更進一步:這四張卡的覆蓋關係(Zone.space_ids、Door.camera_ids、Sensor.covers、VESDA 取樣孔→Space)形狀其實一樣,可以考慮一個通用 Coverage(observer, target, kind) 加 effective——先收斂前者,後者等 dc-37 溫濕度感測器佈點(第五個覆蓋關係)出現再決定。

🟡 4. 「連到電」有四種寫法,單位有三種

LockDoor.on_ups: bool(練習)、Door.lock_power → PowerEdge(意涵)、dc-35「PoE 交換器掛在 UPS 分支」(沒有欄位)、dc-36 controller.powered_from;負載單位是 lock_ma(mA)、lock_load_a(A)、PoE 的 W。on_ups: bool 是個可以算出來的欄位被存下來——違反本軌跡「算得出來的一律不存」的原則(dc-12 的例外是前提變欄位,這裡不是)。

收斂建議:一個 Consumer(id, draw_w | draw_a+volt_v, powered_from: node_id),on_ups 改成對電力樹的查詢;電壓未知時 volt_v 用 Sourced(..., evidence="assumed"),不要在函式裡默默假設(dc-34 計算四明說「電壓來源未說」)。這也是上面「兩」那條共因查詢的前置條件。

🟡 5. 檢查函式的回傳型別:Result 與 bool 混用

dc-33 的 end_of_hold_ok、check_occupied 回 Result;dc-34 mantrap_ok、dc-35 poe_ok/skew_ok/evidence_expired 回 bool。極性也不一致:*_ok 為真是好,evidence_expired 為真是壞。邊界慣例其實有被驗收表守住(4.51/4.50、t=33/34、(7,7)),這是好的;但 bool 沒有 UNDETERMINED 這一態,而 dc-35 的 PoE 預留值若取自 snippet 就無處可去。

收斂建議:凡是會被 Finding 消費的檢查一律回 Result;純算術(gb_per_day、released_l)維持數字。命名統一 check_*,極性一律「通過 = OK」。

🟡 6. WaterSource.above: list[Space|Asset] 混了兩種型別

dc-36 意涵 #1。水往下流是空間關係(樓層、房間、地板下夾層);資產在哪個空間是 Placement。建議 above 只存 space_id,「哪些 UPS/PDU 在水源下方」用 Placement 反查,這樣加分題 exposed_below 才不需要處理兩種節點。

🟡 7. 從 W40 留下:NemaClass 跨距、space_id 命名

沒有新進展,不重複展開(見 W40 #4、#5)。本週新增的 Zone.space_ids、Door.from_space/to_space 命名一致,是好現象。

做得好的地方

  • 「缺東西」家族有穩定的命名與問法:每張卡都回答「這個告警在沒有事件的狀況下,要從哪個欄位推導」。
  • dc-36 明確要求 q(漏水量)存為 assumption、不得偽裝成量測值,延續了 Sourced.evidence 的紀律。
  • dc-34 把來源互相矛盾(Wiegand 尾端同位)當成「來源分歧」記下並以 HID 為準,而不是默默挑一個。

建議的收斂順序:🔴1 → 🔴2 → 🔴3 放進 dc-37 練習第 0 步(約 25 分鐘,仍沿用「掛進下一張卡」的路徑);🟡4 與 🟡5 留給 dc-38;🟡6 順手改文字即可。

自我測驗

Q1.〔事實回憶,dc-33〕 288 m³ 機房、20 °C,採 NFPA 2001(Class A、4.5%)的 Novec 1230 藥量是多少?保持時間結束時,防護設備頂部的濃度至少要多少才算過?

答案

藥量 188.8 kg(W = V/S × C/(100−C),S(20 °C) = 0.07188)。85% 規則:0.85 × 4.5 = 3.825%。 對照:採 ISO 14520(5.3%)是 224.2 kg、末端 4.505%——同一間房,標準不同藥量差 19%。

Q2.〔事實回憶+建模,dc-34〕 40 扇 fail-safe 電磁鎖每扇 500 mA、不在 UPS 上。市電斷了會發生什麼?這個風險在你的資料模型裡該怎麼表達,才不會變成一個容易過期的布林?

答案

負載 40 × 0.5 = 20 A;市電斷的瞬間 40 扇門同時打開(fail-safe:斷電釋放),與聯動命令無關。 對你的模型:不要存 on_ups: bool。Door.lock_power 指向電力樹節點(powered_from),FAILSAFE_OPENS_ON_MAINS_LOSS 由「fail-safe 且路徑上沒有後備電源」查詢推導;而 20 A 是要計入該 UPS 分支負載的葉負載。

Q3.〔應用,dc-35〕 一棟新機房要 24 支 4 Mbps 攝影機連續錄影 60 天,用 16 TB 硬碟、80% 填充上限。RAID 5 與 RAID 6 各最少幾顆?另一群走道攝影機保存 14 天、稽核每 14 天看一次,有沒有問題?

答案

4 × 10.8 = 43.2 GB/天/支;43.2 × 24 × 60 = 62,208 GB(62.2 TB);÷0.8 = 77.76 TB。RAID 6 可用 (n−2)×16:n=6 只有 64 TB 不夠,n=7(80 TB);RAID 5 (n−1)×16:n=5 只有 64,n=6(80 TB)。 稽核 14 天 ≥ 保存 14 天 → evidence_expired(14, 14) = True:邊界相等也算過期(保守判定),要改保存天數或稽核週期。 對你的模型:required_tb 是對 CameraGroup 的查詢,不是欄位;audit_lag_days 是流程屬性。

Q4.〔應用,dc-36〕 一段 60 m 冷水管下方要鋪漏水感測線,單條上限 30.5 m,NetBotz 一台只有一個漏水繩連接埠,要幾條線、幾台?另假設漏水量 80 L/min、感測 5 s、閥全關 45 s、排水盤 100 L:乾接點直驅閥與 DCIM 每 30 秒輪詢,各漏多少?會不會外溢?

答案

⌈60 ÷ 30.5⌉ = 2 條、2 台(1.97 進位)。 直驅:80 × (5+0+45) ÷ 60 = 66.7 L(不外溢);輪詢最差:80 × (5+30+45) ÷ 60 = 106.7 L(外溢 6.7 L)。 注意:80 L/min 是情境假設,模型裡要存成 assumption,不得當量測值。

Q5.〔建模判斷,跨 dc-32/33/34/36〕 迴路被隔離、門沒有 DPS、漏水感測線被污染——三個「Normal 但其實無保護」的案例。你要寫成三個各自的 Finding,還是一個共用的機制?說明你的設計,以及它會逼你在 Sensor.state 上做什麼決定。

答案

共用機制:core.effective(kind, state) -> Result 一張表集中定義「哪些狀態算有效觀測」,所有「缺東西」查詢(DETECTION_COVERAGE_GAP、RELEASE_PATH_DEGRADED、DOOR_UNMONITORED、LEAK_SOURCE_UNCOVERED)都走它;Finding.kind = missing_protection 聚合同族。理由:三處各寫一次規則會漂移——dc-36 目前就已漂移(只擋 fault,放行 contaminated、silenced)。 它逼出的決定:contaminated(黃燈、線已被污染)與 silenced(人為靜音)到底算不算覆蓋?卡片的常見誤解說未被監督的線斷了就是靜默失效,所以保守答案是不算,並讓 silenced 帶 until 時限,否則「靜音」會變成永久的洞。 先收斂「有效」的定義,再談要不要抽象成 Coverage(observer, target) 關係——後者等 dc-37 出現第五個覆蓋關係再決定。

間隔複習

兩週前(W39)與四週前(W37)各抽一張。W40 抽的是 W38/W36,這次不重複。

抽 W39 的 dc-27 RDHx 與 DLC(2026-09-23,18 天前)

題目:被動式後門(RDHx)在室內 24 °C 時,進水溫的「不凝結下限」與「房間中性上限」各是多少?比較 RH 50% 與 60% 兩種室內條件,窗口各有多大?解法在哪裡?對資料模型有什麼啟示?(提示:額定點 ε = 0.703、排風溫升 21.3 K、露點 margin 1.5 K。)

答案

上限 = T_室 − ΔT(1/ε − 1) = 24 − 9.0 = 15.0 °C(RH 無關)。下限 = 露點 + 1.5:RH 50% → 12.9 + 1.5 = 14.4 °C(窗口 0.6 K);RH 60% → 15.8 + 1.5 = 17.3 °C(空集合,差 2.3 K)。 解法在房間不在門:RH 壓到 ≤ 51.9%,那是 CRAH 除濕(dc-24)的事。 啟示:兩條約束各自都是綠燈、交集是空的——模型需要對約束集合求交集的檢查,且 can_dehumidify 這類房間層級的量要能影響門的合法進水溫窗口。與本週的連結:窗口為空時門會凝水,那就是 dc-36 要覆蓋的水源。

抽 W37 的 dc-21 板式熱交換器與免費冷卻(2026-09-10,31 天前)

題目:門檻濕球 T_wb,max = T_chws − a_tower − ΔT_load·(1−ε)/ε。取 a_tower = 4 K、ΔT_load = 6 K、ε = 0.75,冰水設定 13 °C 的門檻是多少?HX 髒污使 ε 掉到 0.68 後,門檻下修多少?這個設定值的「擁有者」是誰,對資料模型意味著什麼?

答案

ε = 0.75:第三項 6 × 0.25/0.75 = 2.0 K → 13 − 4 − 2.0 = 7 °C。ε = 0.68:6 × 0.32/0.68 = 2.82 K → 13 − 4 − 2.82 = 6.18 °C,下修約 0.8 K。 擁有者在 IT 側(機櫃進風上限 → 盤管選型 → 冰水設定),不是設施。所以 chws_setpoint 要記來源與變更紀錄,且 free cooling 小時數是設定值的函數,不是氣候的函數(7 °C 冰水在台北一年 0 小時、18 °C 才有東西可拿)。

本週該問 facility 的問題

從四張卡的「該問 facility 的問題」(共 12 題)去重、排序後選 3 題。排序依據:答案會直接改變模型某個欄位或某條告警是否成立,且只有現場能給。

1.〔建議問:消防系統承包商(釋放盤與氣體系統商),並請機電一起提供土建圖〕

「氣體滅火防護區的體積計算書在哪?有沒有把地板下和天花板夾層算進去?設計採 NFPA 2001 還是 ISO 14520、設計濃度與設計溫度各是多少?最近一次圍封密閉測試(門風扇)是哪一天,之後有沒有隔間、開孔或管線貫穿的改動?」

為什麼是它:Zone.volume_m3、standard、design_temp_c、enclosure_test_at 目前全是空的,design_mass() 只能回 UNDETERMINED;而圍封改動晚於測試日期就是 ENCLOSURE_CHANGED_SINCE_TEST。來源:dc-33 該問 #1、#2。順帶可問預放延遲秒數與誰能設鎖定/旁路(dc-33 #3)。

2.〔建議問:控制系統承包商(門禁系統商),電源部分請機電確認〕

「資料機房所有逃生路徑上的門,各是 fail-safe 還是 fail-secure?fail-secure 的機械逃生把手在哪?每扇門(含機櫃區的門)有沒有 DPS?這些鎖與門禁控制器掛在哪一條 UPS 分支,斷市電後各撐多久?」

為什麼是它:Door.lock_mode、mech_egress、dps 與 lock_power 決定三個告警(EGRESS_BLOCKED_ON_POWER_LOSS、DOOR_UNMONITORED、FAILSAFE_OPENS_ON_MAINS_LOSS)是否成立,而且這個 UPS 分支問題的答案,同時回答了攝影機交換器與漏水控制器的供電(本週「串起來」第二條共因)。來源:dc-34 該問 #1、#2、#3;dc-35 該問 #3 後半。

3.〔建議問:維運(漏水通知路徑與稽核流程),閥與空調停機的接線請機電確認〕

「每台 CRAH、CDU、冷水管接頭與冷凝水盤下面是點式還是感測線?感測線型號、長度、有沒有距離定位?乾接點有沒有真的接到閥門或空調停機,還是只送到 BMS 顯示?告警是 relay、trap 還是 DCIM 輪詢(週期幾秒)?稽核人員多久看一次門禁告警與影像,比最短保存天數短嗎?」

為什麼是它:WaterSource.covers、Response.path/notify_s 與 audit_lag_days 都是現場才有的資料;同一個感測器,直驅 54.2 L 與輪詢 79.2 L 的差別,就在這題的答案裡。來源:dc-36 該問 #1、#2;dc-35 該問 #2。

沒選但值得順帶問:dc-36 的液冷用水、乙二醇還是介電液、現有感測器對它實測過嗎(問 #3 時一起要即可,對 LEAK_FLUID_UNDETECTABLE 很重要);dc-35 的攝影機與門禁 NTP 是否同源。


下一張:dc-37 溫濕度感測器佈點策略(建議第 0 步先做連貫性檢視 🔴1–🔴3)。下次間隔複習(W42):抽 W40 的卡(dc-30 ~ dc-32)+ W38 的卡(dc-23 ~ dc-25b;⚠ dc-25 已在 W40 抽過,請從 dc-23 / dc-24 / dc-25b 選)。