Vacant 執行端

運作中 共 40 輪 user1-2 up 1 day, 15 hours, 37 minutes 6.7G 可用 / 63% 已用 更新於 08-17 02:29:44

現在在做什麼

STATE — 執行端連續性檔案

(較舊的輪次已略去,完整內容見 STATE.md)

第 107 輪 · 2026-08-17 02:04–02:3x UTC 【事後】(時間照本機 date -u

做了:把人類拍板的 HW3.0 真的套進 world/ 的 render 層?dose=m,opt-in, 不給 ⇒ 逐字不變),然後照人類第二條裁定chrome-headless-shell 渲了 四批 132 張 640px 重跑同一把尺。新增 styles/probe/ss_dose_render.pyDOSE_HW3_RENDER.md(每個數字從 JSON 取,零手打)。 驗證方法 `` PORT=8501 P=sr_ EXTRA='' bash styles/probe/ss_solo.sh # 不給 ?dose PORT=8502 P=sq_ EXTRA='&dose=1.0' bash styles/probe/ss_solo.sh # 顯式空操作 PORT=8503 P=sd_ EXTRA='&dose=3.0' bash styles/probe/ss_solo.sh # 人類拍板的劑量 python3 styles/probe/ss_dose_render.py # V1–V5 共 11 格+V6 主數字 cp ss_dose_render.json /tmp/w1.json && 重跑 && diff # 決定性 grep -n "信任\|保證\|防止\|杜絕" DOSE_HW3_RENDER.md # 三條誠實邊界 ` 驗證結果(11/11 判分格 PASS,貼實際輸出) ` R0_tools (空) PASS 量具側一個字沒動 R1_world 2 檔 +100/-6 照報 render 層本輪刻意被改 V1_ruler_sl 44/44 PASS 逐人對 ss_solo.json 的 bbH_solo V2_spec 0.5574387947269304 PASS IOU_SPEC 逐位元接回第 53 輪 V2_base 0.51595 / 365對 / 946對 PASS V3_noop_sr_dim 44/44 PASS 不給 ?dose:逐人 (bbW,bbH) 對歸檔 V3_noop_sr_pair 0.51595 / 365對 PASS V4_noop_sq_dim 44/44 PASS 顯式 dose=1.0(程式無捷徑) V4_noop_sq_pair 0.51595 / 365對 PASS V5_absent / _ok / _loud PASS 三格:不給無欄位/m 實際生效/壞值大聲失敗 決定性:兩次輸出 diff 0 行 · 紅線掃描 0 命中 · 機時 0 · 生圖 0 · 渲染 132 張 ` 主數字(渲染空間,與遮罩空間不可混用): ` bbH 現況 max/min 21/9 → dose3.0 32/1 bbW 現況 max/min 15/4 → dose3.0 25/4 946 對 IoU 中位 0.51595 → 0.22155 難分對 365 → 95 基線 365 對難分:救起 273(不靠觸底 254) 退化 0 觸底 5 人(全 child) 世界高 現況 1.076–2.603(2.42×) → dose3.0 0.196–4.090(20.83×) ` 本輪最重要的一格:那個 273 含著 5 個量錯的人。 5 個世界高相差 2.22 倍(0.1964–0.4354)的居民,量出來是逐位元相同的 4×1。 五個不同的東西量成同一個數 ⇒ 那是尺的性質,不是東西的性質。查下去: | key | 基線 | dose=3.0 | 報成 | |---|---|---|---| | f0r10 | 1 塊/45px | 6 塊/14px/最大 4 | 4×1 | | f1r0 | 1 塊/36px | 6 塊/13px/最大 4 | 4×1 | | f1r3 | 1 塊/37px | 6 塊/15px/最大 4 | 4×1 | | f2r8 | 1 塊/43px | 6 塊/14px/最大 4 | 4×1 | | f3r9 | 1 塊/42px | 6 塊/13px/最大 4 | 4×1 | ss_dim.big_comp 的規格是「回傳最大的、面積 ≥ MINAREA(=4) 的連通塊」—— 它照樣回一塊 4×1,不會說「量不到」。而那個 4×1 在完全沒有變小的居民 (f0r1f2r2)身上也以次要塊出現 ⇒ 它不是身體。 ⇒ 「量了得 4×1」與「尺到底了」在原本的回傳值裡長得一模一樣。 排除那 5 人重算:336 對可量、救起 254、退化 0。兩組數字都留著,不擇一。 這一格特別危險,因為它給出的錯誤結論(「小孩不見了」)剛好是事前就擔心的事 ——提示詞第三節那句話這一輪真的踩到了。V9 這一段是事後加的、不在事前登記裡, 已在程式與那一頁上照實標。 預測對帳(5 對 2 錯) G1701 對(bbH 極差 12 → 31 = 2.58 倍 > 2)·G1702 對(中位 0.51595 → 0.22155)· G1703 對(難分 365 → 95)·G1705 對(沒有人的遮罩整個空掉,退化 0; 與遮罩空間那頁的「f1r0 0 像素」方向相反,理由就是我預測時寫的:重採樣跳格 vs 真的畫出來)·G1707 對(觸底 5 人 < 8 人)。 G1704:我預測 child 五人 bbW ≤ 2,實得全是 4——但錯的方式比錯本身重要, 那個 4 是 MINAREA 的下限不是身體的寬度,這條預測用這把尺根本答不了G1706 錯,而且錯得離譜:我預測遮罩空間的「救起 284」在渲染空間不會重現、 相對誤差 > ±10%,實得 273(−3.9%),排除量錯的人之後 254(−10.6%)。 遮罩空間那張表對「救起幾對」的預測力比我以為的好得多—— 第 106 輪那句「不可以拿 284 當預期值」在方向上仍然對(單位不同、要重量), 但在數量上它其實很接近。 commit3725c33 vacant_hm(main)· 已 push, git rev-parse HEAD origin/main 兩個 sha 逐字元相同 (3725c3342728bb2f583863bdf26ceef2e9cac545)。 下一步 1. 換一把量得到小剪影的尺(本輪擋住主數字的那件事)。方向建議: big_comp 改成「回傳最大塊 + 一個 resolved 旗標」,主體碎裂或最大塊 ≤ MINAREA 時回 resolved=False讓量不到與量到 0 分開。⚠ 那會動到 ss_dimss_hard 兩支既有量具的共用函式 ⇒ 動它必須先驗「既有 44 人/946 對的數字逐位元不變」, 否則第 52/53 輪的基線就漂了。執行端可以自己做。 2. 展場距離的目視驗收還沒做:本輪只量了遮罩,沒有看過 ?dose=3.0 的 真實畫面縮到 640px 長什麼樣(sd_world_640.png 有,但沒人看過)。 執行端可以自己做(Read 那張圖)。 3. 等人類(第 106 輪上浮的兩條仍未回):(a) child 全型 5/5 的個別豁免—— 本輪多一個數據點:在渲染空間他們是碎成 6 塊、共 13–15 px, 不是遮罩空間那頁的「0 像素」;(b) 要不要把 dose=3.0 設成預設 (鉤子已做好,改預設是一行;但 (a) 沒回之前執行端不動)。 4. 第 105 輪下一步 1(三個 *probe.js 的 SCOPE)/2(〈否定脈絡〉子句化) /3(兩個 U+0001)仍未接,執行端可以自己做。 5. 第 105 輪下一步 4/5、第 97 輪下一步 2/4/5、第 96 輪下一步 2–5、 第 95 輪下一步 2/3、第 94 輪下一步 1、第 93 輪下一步 1b/1c、 第 91 輪下一步 1/2、第 89 輪下一步 1–4 仍未接。 卡住本輪的主數字有 5/44 個人量不到(見上)。不是環境問題、不是判準沒過, 是既有量具的下限;下一步 1 就是修它。在修好之前, 「child 在 dose=3.0 之下剪影多大」這個專案答不出來, 而那正是人類要拿來決定豁免的那一格。 • 優先序第 2 項(交付狀態機剩兩格)第 69 輪判定其修法是視覺決定,仍受規則七擋。 • ~/vacant 不是 git repo:STATE.mdPROGRESS.md 無版本控制、無異地備份 (連續第四十九輪)。 • Vacant/HANDOFF.md 的機器識別段仍在講 Windows 那台(/d/vacantw401c-16); 本機實測 hostnameuser1(不是提示詞寫的 user1-2)、 tailscale 100.124.254.83連續第四十九輪)。照提示詞的判準 (HANDOFF.md 存在 ⇒ 機器正確)繼續,沒有停手。 • 本機沒有 .venv;用系統 python3 3.11+ 可以跑。 • 本機的 PNG 渲染不可逐位元重現(同一棵樹連渲兩次差 4076/691200 個像素位元組, swiftshader),但差分後的遮罩可重現(三方 (9,11,71) 相同)。 ⇒ 這台的視覺判準只能寫在遮罩上,不能寫在位元上。第 84 輪那個「49/49 差 0 px」 是挖掉 HUD 之後的比較,與這條不矛盾。 • Vacant/runs/s1_smoke/(第 90 輪)仍 untracked,本輪一樣刻意沒動。 • vacant_hmM styles/probe/shoot.sh?? styles/probe/b64/?? styles/probe/sh_src.py 仍未提交(本輪只 add 自己的檔)。 • 前幾輪那些仍等人類:顏色能不能當居民身分線索 · 07 段措辭豁免 · 60%/86%/95.4% 來源類別 · 首頁大標壓行 · .code-token 觸控目標 · scrollY=8250 半屏空黑 · ARCHIVE_LEVEL_H 二選一 · ?tilt 預設 · 開場遊戲 2.4 秒空檔 · persona 資料邊界 · HUD 要不要留 fps · 第 67 輪那 48 張 hl_*.png 要不要補進 repo · 「知識只寫在一處」要不要列成紀律。

第 108 輪 · 2026-08-17 02:24 UTC 【事前登記】(動手之前寫的,之後一個字不改)

接第 107 輪下一步 1(寫著「執行端可以自己做」):換一把量得到小剪影的尺。 第 107 輪擋住主數字的那件事——
ss_dim.big_comp 的規格是「回傳最大的、面積 ≥ MINAREA(=4) 的連通塊」,於是 5 個世界高相差 2.22 倍的居民全部量成 逐位元相同的 4×1「量了得 4×1」與「尺到底了」在回傳值裡長得一模一樣。 做法:在 ss_dim.pyresolve_comp(idx)big_comp(idx) 改成它的薄包裝 (同一個決策函式,HANDOFF §八 最後一條;不許兩份各自實作)。回傳值多帶: ` resolved False ⇒ 這一格的 (bbW,bbH) 量的不是身體,不准當數字用 why 'ok' | 'empty'(沒有 area>=MINAREA 的塊)| 'floor'(最大塊面積 <= MINAREA) ncomp / big_area / ink / share=big_area/ink 診斷,不參與判定 ` 判定只用 big_area <= MINAREA,理由:MINAREAcomponents回報下限, 剛好卡在下限的塊是被截斷不是被量到——尺報不出更小的值,所以那個 4 是不是量。 碎裂率 share 只報不判。 現在就挑一個 share 門檻,是在已經看到那 5 人 share≈0.3 之後挑的——那正是「量完再挑判準」。要不要用它留給下一輪/人類,先給資料。 ⚠ 既有 44 人/946 對的數字必須逐位元不變,否則第 52/53 輪的基線就漂了。 P0 前置(先驗尺本身可不可重現):在未改動的樹上先跑一次 ss_dim.pyss_hard.py,看 JSON 的 git diff --numstat 是不是 0 行。若本來就不是 0 行, V3/V4 的判準改成「逐人 (bbW,bbH) 與 946 對中位逐位元相同」,並照實記下原因。 判準(先寫,之後一個字不改) | 格 | 判準 | |---|---| | V1 | big_comp 逐位元不變:44 張 sl_*_640.png(bbW,bbH,px) 對歸檔 ss_dim.json 44/44 | | V2 | 濾波等價components(...,MINAREA)[c for c in components(...,1) if area>=MINAREA],88 張遮罩(sl_+sd_)逐位元相同(省一趟 BFS,但不准當作假設) | | V3 | 重跑 ss_dim.py:判分格全 PASS,ss_dim.json diff 0 行(或 P0 降級後的等價判準) | | V4 | 重跑 ss_hard.pyss_hard.json diff 0 行(或同上降級) | | V5 | 探針自驗·正面已知答案:合成實心 10×10 ⇒ resolved=Truewhy='ok'big_area=100ncomp=1share=1.0 | | V6 | 探針自驗·負面已知答案 A:單一 4×1 塊 ⇒ resolved=Falsewhy='floor' | | V7 | 探針自驗·負面已知答案 B(第 107 輪那個形狀):六個散開的 4×1 ⇒ resolved=Falsewhy='floor'ncomp=6 | | V8 | 探針自驗·負面已知答案 C:全空遮罩 ⇒ resolved=Falsewhy='empty' | | V9 | 探針自驗·邊界:面積 5 的塊 ⇒ resolved=True(證明下限剛好在 MINAREA,不是我偷偷調高的別的數) | | V10 | 主數字落盤sl_(基線)與 sd_(dose=3.0)兩批 44 人逐人 resolved/why/ncomp/big_area/ink/share,寫進 ss_resolve.json | | V11 | 三條誠實邊界掃描(信任保證防止杜絕)在本輪新增文字上 0 命中 | | V12 | world/git diff --numstat0 行(本輪只動量具) | V1–V9 任何一格沒過 ⇒ V10 的主數字一律不報。 事前預測(對帳,錯了照記)G1801sl_ 基線 44/44 resolved=True(那批第 49 輪驗過是單一連通塊)。 • G1802sd_(dose=3.0)恰好 5 人 resolved=False,且就是 f0r10f1r0f1r3f2r8f3r9 這五個,其餘 39 人 resolved=True。 • G1803:三份既有 JSON(ss_dimss_hardss_dose_render)改完之後逐位元不變。 • G1804:那 5 人的 share 落在 0.25–0.35(4/13 到 4/15);sl_ 基線 44 人 的 share 全部 ≥ 0.9。 • G1805sd_ 批裡至少有一個 resolved=True 的人也有 ncomp > 1 ——碎裂本身不是訊號(第 107 輪在 f0r1f2r2` 身上看到同一個 4×1 次要塊)。 這條若成立,就是「share 不該當門檻」的實證理由。

進度大綱

PROGRESS — 三個目標現在到哪

給人看的大綱,不是日誌。逐輪紀錄在 STATE.md唯一交付物:畢業專題 = 實體場地展覽。不寫論文,不投稿。 判斷任何事要不要做:觀眾走到展場前面時,這件事有沒有差別。 ---

0 · 這份紀錄本身可不可信(2026-08-16 第 26 輪新增)

已知曾經失效一次,已抓出、已更正、證據已落盤。 第 25 輪的紀錄寫著「commit:3e6b9c5(已 push)」,那個 hash 不存在於任何 ref、reflog 或遠端;那一輪的產物真的做出來了,但從來沒有被 commit。 第 26 輪開場對帳抓到,沒有安靜補一個 commit 蓋過去,而是先把判準凍結、 獨立重跑整套驗收(PASS 227/FAIL 21,與第 25 輪宣稱值逐字相同, R9/R11/R12/Q8 全部重現),確認結論站得住之後才收進 082b283。 第 25 輪那一行原文保留、加更正註記——留著讓人看見錯的形狀。 這對展覽是有意義的,不只是內務:展件的整個主張就是「留下改不掉的紀錄」。 如果做這件事的過程自己有一筆假紀錄而沒人發現,那個主張在展場站不住。 每輪無記憶這件事在這裡第一次付出了紅利——重跑的人不是原作者制度上的後果(已寫進 STATE.md):收尾「commit + push」唯一算數的證據是 遠端 sha 與本地 sha 逐字元相同git push 印什麼、記得自己做過什麼,都不算。 ⚠ 仍然開著的同型風險~/vacant 本身不是 git repo,STATE.mdPROGRESS.md 只存在於這台機器,沒有版本控制也沒有異地備份——第 25 輪那個失效模式對這兩個 檔案是永遠成立的。要不要納管牽涉既有結構,等人類決定

✅ 第 62 輪:拍板那一頁的數字,出處查過了

DECISION_SILHOUETTE.md 的 148 條數字全部來自六支 ss_*.py,而那六支的 唯一輸入是第 44 輪落盤的 sl_ 那 49 張 640px PNG。「那 49 張是哪一棵 原始碼樹渲的」由 srcman_sl.json 記著——第 62 輪開場一跑,是紅的world/js/clay/main.js 在量完之後被改過。依 srcman.py 自己寫死的規則 (「對不上就代表量完之後又改過,那一整輪的數字不算數」), 人類要據以拍板的那一頁,148 條全部不算數。 肇事的改動看得出來是給 main.js 加的 ?fov=(opt-in、不帶參數走原本那條 常數 34,而 sl_ 從來不帶)⇒ 看起來是空操作。但那是讀前提。 所以改成驗後果:用現在這棵樹走同一份 ss_solo.sh 重渲染那 49 張,逐位元比。 > 挖掉 HUD 四列之後,49/49 全部 0 px(每張比 227,840 個像素)。 > 全圖 sha256 有 28 張不同,差全部落在 HUD 裡那個活的 fps 計數器。 > 那一頁另外兩個輸入也一起驗了:ss_world_640.png(那六支唯一用到的 > ss_ 批次圖,只拿來取 HUD 列)逐位元 0 px、量出的列仍是 [4,5,6,7]; > sl_dump.jsonss_arch.py 真正讀的 heights 逐位元相同, > 只有四個牆鐘計數器不同(沒有任何 ss_* 數字讀它們)。 ⇒ 那 148 條站得住,而且這是量到的,不是講道理講出來的。人類可以放心拍板。 這件事對展覽本身是有意義的,不只是內務:展件的整個主張就是 「留下改不掉的紀錄」。所以第 62 輪沒有把紅燈改綠——那 49 張確實是舊樹渲的, 改 hash 會讓燈變綠、代價是把歷史寫成假的。做法是 hash 一位元不動(仍然紅), 把查證結論掛成 notesrcman.py 紅燈時把它印出來。**紅還是紅,只是紅得會 自己解釋。** 這是這個專案第二次在自己的紀錄上遇到「可以安靜蓋過去」的岔路 (第一次是第 25/26 輪那個不存在的 commit hash),兩次都沒有蓋。

✅ 第 63 輪:交付狀態機那一批的出處也查過了(這次紅的是「挑 t 的規則」)

第 62 輪查的是拍板那一頁;第 63 輪查的是展件優先序第 2 項——交付狀態機 四段在展場距離分不分得開(stagevis.py)。它的全部輸入是 stage.sh 落盤的 兩批各 6 張圖 + t.jsondump.json,而兩支 srcman 都是紅的。 這一批的紅燈跟上一批不同性質,所以不能沿用上一輪的講法。 sl_ 那批只紅在 main.js?fov=(opt-in),還講得通「看起來是空操作」。這一批多紅一支 stprobe.js,而 stprobe.js 決定的是 t(凍結時刻,stage.sh 第 ① 步就靠它挑) ——那不是參數,是規則;規則變了整個場景就不同。 只能驗後果。 > 用 HEAD 這棵樹走同一份 stage.sh(只換前綴 stv_s2v_)重渲染: > T 沒動(12 與 69.5,後者非 fallback);兩批共 12 張挖掉 HUD 四列後 > 逐位元 0 px(每張比 227,840 個像素);t.json 舊葉節點 0 改值 0 缺, > st_ 只多出 fullpickFull新增的,pick() 一個字沒動); > dump.json 只有 4/5 個牆鐘計數器不同。 ⇒ 那一組數字站得住。 紅燈同樣沒有改綠(hash 一位元不動、check 仍 exit 1), 查證結論掛成 note。四把尺(srcman/門檻差分/嚴格逐位元/frozen_diff各自先答已知答案才拿去量未知的,A/P 類 32/32 全過。 本輪自己抓到的兩件:①「sha 有差」與「量具讀得到差」是兩件事——門檻尺 (ΔLuma≥8)讀 0 但 2/6 張 sha256 不同,中間那段原本會掉進沉默;補上全圖 逐位元那一把才看得到真數字是 47/48 px,且全部落在 HUD 四列。 ② 事先寫死的六條預測錯一條:我押「同場景截兩次差 10 px」是從 commit message 讀來的,歸檔的數字記著 0。押註前該讀的是歸檔,不是敘述。 ⚠ 還有三支 srcman 是紅的、還沒查srcmanshoot.shverdict.py = 剪影驗收主量測台,25 張圖,紅在 6 個檔,其中 review.jsscene.jslit.js 是渲染程式、不是 opt-in 參數,很可能真的改變了畫面)、srcman_sosrcman_ss。 建議下一輪做 srcman 那一支——它若沒過,結論就是「那一批數字要重跑」, 那同樣是有價值的結論。⚠ shoot.sh 目前沒有 PRE 參數,要照 stage.sh 第 34 輪的做法加參數而不是複製一份(複製兩份會各自被正確地修改不同次數然後漂移)。 ⚠ 第 64 輪開工了但沒跑完shoot.sh 已改未驗未 commit、b64/ 只有 43/130 個產物、sh_src.json 從未產生)。第 65 輪不接手也不收拾,但逐位元證明沒碰到它。 它現在有外部代價ss_opts.pyP0_untouched 因它而 FAIL ⇒ 給人類拍板 那一頁的主數字被那一頁自己的規矩降級。下一輪應先決定它的去留。

✅ 第 65 輪:那張選項表上「未量」的選項 5 量出來了,而且它寫錯了

DECISION_SILHOUETTE.md 請人類從五個選項挑一個,但選項 4、5 都寫著「未量」, 其中選項 5(改 ARCH 那 30 個數字)是唯一被標成「直接動得了」那 47 對硬核的。 ⇒ 人類正被要求在一個沒有數字的格子上拍板。 第 65 輪去量它。 (量一個候選 ≠ 採用它。採用哪一組仍是視覺決定=規則七,world/ 預設值沒改。) > 那一頁原本的推論是:硬核 70% 是同型 ∧ 同型難分是生成器的天花板 > ⇒ 改生成器就動得了。前半對,後半不成立。 做法:clay.js 加 opt-in ?arch=(6 列 × 5 欄 CSV),候選由機械規則產生 (每欄對均值做 affine、K=2.0,=劑量表同一個形狀,只是作用在生成器上), 重渲 44 人再走同一條分析管線(決策函式一個都不重寫)。K 故意選激進。 | | 現況 | 候選(K=2.0) | |---|---|---| | 解析身高 span | 1.9628 倍 | 4.291 倍 | | 難分對(946 對中) | 365 | 154 | | ├ 異型 | 270 | 60 | | └ 同型 | 95 | 94 | | 那 33 對同型硬核救起 | — | 0 對 | ⇒ 異型難分掉了 77%,同型幾乎沒動,那 33 對同型硬核一對都沒救起 (IoU 中位還往更難分的方向走了 +0.0065)。原因是結構性的:一列之內 legHlegWshoulderWheadD 全部只由那一列決定,per-key 只有 ±4% 整體縮放 ⇒ ARCH 是把同型的兩個人一起縮放。 桌上因此多了一個新方向:per-resident 連續體型參數(那一頁上稱「選項 6」, =五個編號選項之外新增的那一個;**不要跟第 59 輪那段把「輪廓線」順口叫成 「第六個選項」的舊講法混起來——輪廓線是表上的選項 4)。執行端不挑**, 而且照實寫了它有代價(clay.js 註解記著當初選離散的理由)。 這一輪最該記住的不是結論,是判準本身錯了一次。 事先寫死的承重判準 A2_optin(不帶參數時 49 張與歸檔逐位元相同FAIL:15/49——而且它從一開始就達不到:同一次 run、同一個 URL 截兩次 就差 8–12 px,這台機器的渲染不是逐位元決定性的。 救回這一輪的是計畫外的對照組:把改動 stash 掉再渲一批, sl_×sb_sl_×sc_對照 的距離同一個數量級(max 38 vs 38) ⇒ 差異不是改動造成的,門檻由對照組訂,不是我挑的。 真正承重的是後果檢查:三批獨立渲染算出的難分對數都是 365,極差 0。 > ⚠ 這對第 62/63 輪有回溯影響:那兩輪用的正是「重渲染逐位元比」, > 當時那些批次剛好讀到 0 px——那是那幾批的性質,不是這台機器的性質。 > 日後再用這個方法,要先驗「渲染是不是逐位元決定性的」這個前提。 順帶抓到兩個會靜靜給錯答案的東西:ss_hard.jsonfifj樓層 不是 figure index(拿它當索引,同型硬核會從 33 變成 18 而沒有任何東西報錯); git status --porcelain 前加 .strip() 只吃掉第一行的前導空白 (真正的違規若排在第一行會被讀成別的路徑)。

⚠ 第 66 輪:想量「展件的誠實聲明有沒有到達觀眾」,量到的是這台渲不出中文

要問的是一條鐵律、不是一個偏好:CLAUDE.md 寫死「展件跑機制模擬 ⇒ 畫面上 必須明講『這是機制模擬』」。那句話現在在 clay.html 的 HUD 裡,font:11px「畫面上有那句話」是前提,「觀眾讀得到」才是後果。 第 66 輪去量後果。 問法沒有美感自由度:把那句話換成另外五句完全不同的話(各恰 11 字、前 4 字 bold ⇒ 等寬下版面相同),展場距離(縮到 640px 寬)下分不分得出來。 分不出來 ⇒ 換成一句相反的話觀眾也不會發現。 答案是:這一輪沒有答案。而擋住錯誤答案的,是事先寫死的對照組。 事先寫死的 P2(一定看得見:44px 下兩句話該差 ≥200 px)讀到 0 px。查下去: • 六串語意完全不同的中文,8 個字級下逐位元同一個檔案 • 同樣走 shot()拉丁對照組有差異 ⇒ 不是差分器壞、不是參數沒到 • 把 44px 那張印成 ASCII art:一排空心方框(tofu) • 這台沒有 fontconfig、find / -name '*.ttf' 只有 DejaVu,一顆中日韓字型都沒有這個 repo 至今每一張 headless 截圖裡的每一個中文字,都是同一個空心方框。 F1 對帳把它釘死:量具那一頁的預設渲染,與歸檔的兩張真 clay.html 截圖 在 HUD 前綴那一塊逐像素 0 px——所以歸檔那批也是方框。 有沒有汙染既有的承重數字?查過了,沒有(查的,不是假設的):那些分析全部 import stagevis.hud_rows_of單一實作)按整列挖掉 HUD,方框照樣有墨跡 ⇒ 挖掉的範圍不會變小;3D 場景裡沒有任何文字(TextGeometryfillTextSprite 全部零命中)。DECISION_SILHOUETTE.md 那 148 條、stagevis.json、 第 65 輪那批都不受影響。 > 這一輪最該記住的:ladder 印出來是 0/15——那正是我事先害怕的數字。 > 一台渲不出中文的機器,與「那句話真的太小讀不出來」,會給出一模一樣的 0。 > 沒有 P2,我會把「展件的誠實聲明沒有到達觀眾」當成量到的事實寫進這一頁。 > 另一件同型的:P5_layout(版面沒位移)顯示 ok=True,那是退化通過 > ——六張圖逐位元相同,當然沒有位移。**因輸入退化而通過的檢查,長得跟真的 > 通過一模一樣。** 兩格都照原樣留著,另立 P5_layout_degenerate 記。 仍然沒有答案的那一題:那句話在展場距離下讀不讀得出來,一次都沒量過。 下一輪要做的是把一顆開源中日韓字型裝進使用者層(不需 sudo、不是規則七), 落 sha256 與來源,重跑一次;P2P6 過了才准看 ladder。 ⚠ 裝的字型不等於展場機器上的字型,結論要寫成「在某某字型下」。 ---

⚠ 第 67 輪:字型裝好了、尺活過來了,那一題還是沒有答案——這次擋路的是我的問法

> ⚠ 第 86 輪的更正:下面 G1 = 1562pxP6 6/6、P2 = 1312px 這三個數字 > 都無法從 repo 重算——第 67 輪重截的那 48 張 hl_*.png(以及 > hl_*_r2.pnghl_real*.png從來沒有被 commit,repo 裡躺的仍是第 66 輪 > 那批空心方框版(拿它們重算 P6 逐格 match 第 66 輪的 1/6)。 > 結論本身沒有被推翻(字型檔實際在 ~/.local/share/fonts/), > 但它現在只靠一份 .json 自證。要不要補截 ⇒ 等人類決定。 > 細節:vacant_hm/styles/probe/HUD_AUDIT.md 第 86 輪那一節。 第 66 輪的環境障礙解掉了:NotoSansMonoCJKtc-Regular.otf 裝進使用者層 (不需 sudo;來源 URL/sha256/位元組數落在 styles/probe/fonts/FONT_MANIFEST.json, 二進位檔不進 repo)。尺這次是活的: • G1(現截真頁面 vs 歸檔方框版,同一塊 HUD rect)= 1562 px ⇒ 字型真的生效。 這是後果檢查——fc-list 至今仍不存在,前提檢查在這台根本問不了。 • P6 六串中文在每個字級都是 6 個相異檔案(第 66 輪是 1 個) • P2 一定看得見(44px)= 1312 px(第 66 輪是 0) • P5 版面非退化通過:x 幅寬全部 126、墨點 754/728/680/532/720/376 ⇒ 版面相同、字形不同,這才是它本來該通過的方式 但這一輪一樣不出結論,而第二個理由比第一個嚴重。 1. 事先寫死的 P3(一定看不見:2px 下該差 ≤2 px)讀到 3 px ⇒ 探針沒全過。 事後補量的噪聲底 P7(同一個 query 截兩次)= 0 px ⇒ 那 3px 是真訊號 不是雜訊,是我門檻定得太緊。P7 標了 post_hoc: truemust_not_rescue_this_round: true——它是看到 P3 沒過之後才加的。 2. 「差分器分得出兩張圖」不等於「觀眾讀得到那句話」。 ladder 說 11px 下 15/15 分得出來(最小差 83 px),照第 66 輪寫死的判準這該讀成 「我的懷疑錯了」。但那條判準本身踩到了反向推論: 分不出來 ⇒ 一定讀不到(成立);分得出來 ⇒ 什麼都不能推(不成立)。 83 px 散在 640×360 裡,人眼什麼都不是。直接證據——把 640 那張的墨跡印出來: `` 11px 在 640 寬(展場距離):墨跡高 4 列、墨點 142 ← 畫面上真的那個值 25px 在 640 寬: 墨跡高 9 列、墨點 551 44px 在 640 寬: 墨跡高 15 列、墨點 1253 ` 4 列像素不是「小字」,是一條糊掉的橫線。 並排 PNG:vacant_hm/styles/probe/hl67_ladder_640.png。 > 這一輪最該記住的:第 66 輪是「我怕的事」與「壞掉的工具」給出同一個 0; > 這一輪反過來——工具修好了,吐出一組看起來像答案的數字(15/15、 > 最小可讀字級=11),而它們否定我事先害怕的事。舒服的方向一樣要擋。 > 擋住它的是 P3 沒過,加上上面那段單向推論——不是我的自覺。 > hudleg67.json 裡那兩個數字記錄了但不認證仍然沒有答案的那一題(連續第二輪):那句話在展場距離下讀不讀得到。 下一輪要把問題換成量得到的那個:墨跡列數(已有 11/25/44 三點 = 4/9/15 列), 但「幾列才可能被讀」的判準必須有外部來源並落盤引用,不能自己挑一個剛好會過的。 ---

1 · 人類動物園(現在的主戰場)

✅ 第 107 輪:HW3.0 套進 render 層、實際渲染重量完成——而尺在小孩身上到底了(commit 3725c33

現在到哪:人類拍板時的第二條裁定做完了——?dose=mworld/js/clay/clay.js (opt-in,不給參數 ⇒ 行為逐字不變),四批 132 張 640px 實際渲染、同一把尺重量。 劑量作用在模型空間(居民的站立本質尺寸)而不是直接乘第 106 輪那張遮罩空間的 倍率——因為遮罩 bbox 把姿勢混進來了(f1r0 的 bbH 只有 9 有一半是因為他坐著, 照那個倍率縮會把坐姿罰兩次)。 空操作先驗過再報主數字:不給 ?dose 與顯式 ?dose=1.0 兩批,逐人 (bbW,bbH) 44/44 接回歸檔、946 對中位與難分對數逐位元相同。程式裡刻意沒有 if (m === 1) return 1 的捷徑——有捷徑的話驗到的是捷徑不是路徑。 壞值(?dose=abc大聲失敗進 dump,不靜靜退回預設。 主數字(渲染空間,與遮罩空間不可混用):946 對 IoU 中位 0.51595 → 0.22155、 難分對 365 → 95、基線那 365 對難分救起 273;世界高的全場倍率 2.42× → 20.83×但那個 273 含著 5 個量錯的人,這是本輪最重要的發現。 5 個世界高相差 2.22 倍的居民(0.196–0.435),量出來是逐位元相同的 4×1。 五個不同的東西量成同一個數 ⇒ 那是尺的性質不是東西的性質。查下去:劑量後 他們的差分像素從「一整塊 36–45 px」碎成 6 塊、共 13–15 px,而 ss_dim.big_comp 的規格是「回傳最大的、面積 ≥ MINAREA(=4) 的連通塊」——它照樣回一塊 4×1, 不會說「量不到」;那個 4×1 在完全沒有變小的居民身上也以次要塊出現 ⇒ 它不是身體。排除那 5 人重算:336 對可量、救起 254。兩組數字都留著。 這一格特別危險,因為它給出的錯誤結論(「小孩不見了」)剛好是事前就擔心的事 ——那正是最該懷疑工具的時刻,因為它同時關掉了會去複查的動機。 順帶被打臉的預測:第 106 輪寫「不可以拿遮罩空間的『救起 284 對』當套完之後的 預期值」,本輪實得 273(−3.9%)。那句話在方向上仍然對(單位不同、必須重量), 但在數量上遮罩空間的預測力比當時以為的好得多。照記。 還差什麼:(a) 換一把量得到小剪影的尺——建議 big_comp 多回一個 resolved 旗標,讓「量不到」與「量到 0」分開;⚠ 那是 ss_dimss_hard 的共用函式, 動它必須先驗既有 44 人/946 對逐位元不變,否則第 52/53 輪的基線就漂了。 (b) ?dose=3.0真實畫面縮到 640px 還沒有人看過(本輪只量了遮罩)。 (c) child 全型 5/5 的個別豁免、以及要不要把 3.0 設成預設——等人類, 鉤子已做好,改預設是一行。

✅ 第 106 輪:卡了 44 輪的剪影方向人類拍板了(HW3.0),第一條代價攤開比數字嚴重(commit c7ce061

現在到哪:2026-08-17 人類在 DECISION_SILHOUETTE.md 拍板選項 3、劑量 HW3.0 (身高+胖瘦雙軸 affine),並明講「執行端可以動手」。優先序第 1 項不再是「等人類」。 拍板理由值得記著:HW4.0 救 273 對比 HW3.0 的 284 對還少、退化對 5→34 ⇒ 峰值在 HW3.0 不在邊界,而那個反證是執行端自己附在同一頁上的。 本輪做的是套用的第一半:人類交代的第一條代價是「8 個被壓到 1px 的是誰 要列出來,逐一看過再決定個別豁免,不要整批砍劑量」——做不到,因為歸檔裡 只有 clamped_n: 8 這個數,從來沒存過名單。ss_dose_who.py 把數變成名單, 順帶產出 render 層要吃的 44 人逐人縮放表。零渲染零生圖零機時,決策函式全部 呼叫既有的本人。名單本身沒有已知答案 ⇒ 閘門是總數逐欄接回 ss_hard.json (284/228/5/8/中位逐位元/degen_k),六欄全中才准印名單。 攤開之後兩件事比那個數字嚴重,方向都一樣: 1. child 這一型 5/5 全型覆沒(stout 2/7、short_round 1/5、mid/tall_broad/ tall_thin 全 0)。人類交代的「個別豁免」對這一型在數量上等於整型豁免, 那不是逐人微調而是改該型劑量 ⇒ 規則七,執行端不動,已上浮等人類。 2. 「5 對退化」量的不是拍板文轉述的「變難分」。 ss_dose.py 圖例寫的是 「遮罩整個空掉」、ss_hard.py:279not mk[k]verdict()degen無法判分。真相是 1 個居民(f1r0)整個從畫面消失,「5 對」只是他 恰好落在 365 對難分裡的那幾對;另外 38 對沒被算進去,但他一樣消失了。 還有一條低估:clamp 的是目標尺寸,實得比目標更小(雙軸同縮時 remap 兩邊都可能跳過來源像素——ss_dose.remap 自己寫了這條)⇒ **8/8 人實得遮罩 兩軸都 ≤ 3px。空掉那 1 個確定看不見(0 像素);其餘 7 個只報 px 不下結論**, 因為本專案從來沒校準過人眼門檻(DECISION_SILHOUETTE 第 6 點)。 還差什麼:(a) 把 HW3.0 套進 world/ 的 render 層(本輪 world/ 一個字元沒動); (b) 套完之後必須chrome-headless-shell 實際渲染、縮到 640px、重跑同一把尺 ——人類第二條裁定,在那個數字出來前「難分 365 降到 81」只能寫成「離線遮罩量測」, 不能寫成展場結論;(c) child 全型覆沒怎麼處理,等人類。 ⚠ 那張表是遮罩空間的倍率,render 層動的是 3D 人形,兩者關係只量過身高那一軸 (R²=0.979),寬度那一軸沒量過 ⇒ 不可以拿「救起 284 對」當套完之後的預期值。

✅ 第 99 輪:第 98 輪寫下的病因是錯的——照它去修會修一個不存在的 bug(commit 3d173cb

現在到哪:第 98 輪順帶抓到「文案抽取器漏掉四成」,並把病因記成 「正則的分支順序」。本輪動手前先重現,發現那個診斷不成立:正則的交替 只在同一個起始位置比先後,單引號與反引號不可能從同一個字元開始, 調換順序不會改變任何一個 match。真因是反引號分支的內容類別 [^\\] ` 不准含反斜線——第一條含 \n 的模板配不起來,掃描指標落進模板內部, 之後每個反引號都跟錯的另一半配對,抽出來的是模板之間的程式碼。 單點錯配連鎖到檔尾,所以越後面的文案越抽不到。改成逐字元 tokenizer。 量出來的:非註解中文段漏失 12.5% → 0%(392 段)。拆開看更清楚—— 抓到的文案中文 2240 → 2648(+18%)、誤抓進來的註解中文 2944 → 107(−96%)。也就是說第 97 輪那個「53652 字元」的覆蓋量閘門, 讀進去的東西裡註解比文案還多,該報告已加註記標為作廢(判定結論一條沒少)。 候選 1 → 2:新的那條正是 phone.js:256,**第 98 輪要靠 rendered DOM 才看得到, 現在原始碼路徑自己就看得到**——這是「修好了沒有」的外部佐證,不是 fixture 自說自話。 兩個探針各先錯一次,而兩次的錯都會讓結果更好看:tokenizer fixture 第一次 11/12,FAIL 那格是探針斷言錯(要求模板不准含自己的 class="cap",等於要求 程式做錯事);量尺第一版逐行判註解,對續行不加 * 的區塊註解全漏判, 給了 legacy 一個誇大的 84.7% 漏失率(真值 12.5%)——那個方向剛好讓 「我修好了」顯得更有功勞。84.7% 作廢。 兩格判準照 FAIL 記Q2a 修前漏失 >20%、Q4a 字元數 >53652):都是口徑寫錯 ——41% 是 phone.js 單檔的數字被當成全範圍期望;補回文案的同時也**停止把程式碼 當字串抽**,總字元數本來就會降。逐條寫在 Vacant/runs/s7c_v1_EXTRACTOR_FIX.md還差什麼vacant-docs-webVacant/vacant/web/互動狀態還沒掃 (同一支工具可掃,零機時,執行端可自己做)。phone.js:256125 兩句的 換詞方向仍等人類

✅ 第 98 輪:觀眾最專心那一秒的文案,把「拿不到工作」整條掛在「重跑抓到」上(commit 4dc65ba

現在到哪:第 97 輪自己留下的洞——DOM 那條路只涵蓋初始渲染,「互動後才拼出來 的字」兩條路都沒看過。本輪驅動 chrome-headless-shell21 個互動狀態掃完, 找到的比預期重: ` vacant_hm/world/js/phone.js:256 (渲染於 ?id=findbad&flag=bad) 「重跑抓到了,牠的光會暗下去、一段時間拿不到工作。」 vacant_hm/world/js/phone.js:125–126 「牠剛剛被抽查到交了不合格的東西……接下來一段時間,工作不會交到牠手上。」 ` 第一條〈抓到〉與〈拿不到工作〉在同一句,是 S7 這條紅線最乾淨的一個例子。 第二條同形狀但跨兩句,句級掃描結構上看不到,是人工讀 hurt 全文讀出來的。 兩條都在觀眾的「我的居民」那一屏——他們剛按下指認、正在讀後果。 要人類定兩項world/phone.html:35–37 的記分板「被退回/被抽查/被抓到」 把計分放在弱通道上(版面決定);sampler.js:90→113 的同屏因果鏈 (判定不通過 → 被扣分了)。反方向的配重已經在展件裡而且很強rp-bound「它不會讓成果變好」「那個交付者早就被系統降權了」) ——問題不是講錯,是重心:因果鏈用大字演,配重用小字寫。 這一輪最貴的是「樣本裡沒有待測物」:事前登記那 16 格抓完, 「被扣分了」「判定:不通過」一次都沒進過 DOM——因為 flaggedev.residual(機器說「我檢查不了」)不等於 ev.bad, 60 格裡 6 格 flagged 全走乾淨分支。逐格試到 cell[10] 才是 bad。 phone.htmlhurt 屏同理,?id=1..39 一個都沒有。 ⇒ 不補這兩格,本輪會拿到一個乾淨的 0,而 0 正是我原本預期的答案。 順帶抓到一個工具 bug,它回頭限制第 97 輪的結論s7_claim_audit.py_JS_STR'…'"…" 排在反引號分支前面,模板字面量裡的 class="cap" 會先配對,把整段文案吃掉。量化:範圍內含 ≥4 漢字的模板字面量 79 條, 抽不到 32 條 = 41%。第 97 輪「原始碼 53652 字元」的覆蓋量閘門過了, 但讀進去的文案少四成——字元數不等於文案覆蓋。 還差什麼:①_JS_STR 並重跑第 97 輪的掃描(零機時,執行端可自己做); ②phone.js 那兩句換成什麼,等人類;③記分板版面,等人類; ④vacant-docs-webVacant/vacant/web/ 的互動狀態同一支工具可掃,還沒掃。 改了才算——本輪一個字沒改,展場並沒有因此變正確。

✅ 第 97 輪:右屏的三詞總結把機制的牙齒歸給了稽核——而 S6 說牙齒在評審(commit 41bae6c

現在到哪:S6(第 96 輪)量到擠出作惡者的主要動力是「被評審看見」不是 「被稽核抓到」。本輪把它當紅線掃過三個 repo 的觀眾文案,找到一條踩到的: ` vacant_hm/index.html:111 <p class="w-desc mono">信譽路由 · 三層漏斗 · 抽到就扣分</p> ` 這是右屏「有可究責層的世界」的一句話總結,三個詞就是觀眾對這套機制的第一印象。 第三個詞把「產生後果」歸因給稽核抽到——字面為真(抽中確實會 slash), 但它把弱的那條通道講成了機制的牙齒。同一頁下一屏就有正確的東西: 「第 2 層 密封評審 · 異源三人 · 評審期間互相看不見」。 問題不是頁面缺了評審通道,是那句三詞總結挑錯了代表。 順帶把第 73 輪留下的缺口補了一半:PROGRESS.md:1672 當時寫明「vacant_hm 展件與 Vacant 本體的措辭沒量」——本輪量了,而且兩個站的 rendered DOM「信任」仍是 0 次。 還差什麼改了才算。本輪只是指出來,展場並沒有因此變正確。 換成什麼是敘事決定(規則七),三個方向與代價寫在 runs/s7_v1_CLAIM_AUDIT.md 第二節, 等人類。另外互動後才拼出來的字(sampler.jsphone.js 那兩屏)本輪沒走 DOM 這條路, 覆蓋度低於初始畫面——第 98 輪補了,而且那裡才是踩得最重的地方這一輪真正的工作量不在「掃」,在「證明探針找得到」:第一次跑出來就是 0 個候選,而 0 正是我希望看到的答案——壞掉的探針也回報 0, 並且同時關掉我去複查的動機。兩個「看起來成功」的故障因此被逼出來: 1. file:// 下 ES module 被 CORS 擋掉、頁面根本沒跑,--dump-dom 照樣回傳 HTML。 deliveries.html 的 DOM 351 → 7375 位元組(21 倍)。照 file:// 的結果掃, 會拿一份幾乎空的 DOM 得出「乾淨」。⇒ 這台以後任何 dump-dom 都要走 http。 2. 行號整體偏 4 行(工具報 107、真值 111)——挖掉 <script> 時把換行也挖了。 報告會把人送到錯的一行,而那一行看起來也像是差不多的地方,不會有人發現事前登記的詞表漏了「抽到」:照那份清單跑,本輪唯一的發現會漏掉; 照出它的 --diag 也是事後加的。兩項都是放寬召回不是放寬判準,判準的數字一個字沒改。 附帶:誠實邊界第 1 條「不准出現『信任』」在 Vacant/vacant/web/ 觀測台 UI 有 5 處。 算不算數取決於觀測台會不會上展場螢幕——範圍問題,不拍板,等人類。

✅ 第 89 輪:把第 88 輪抓到的 6 條「頁面說沒做、其實做了」改掉 4 條——另外 2 條在別台機器的交接文件裡,等人類(commit 6f0d328

現在到哪:第 88 輪列全 234 句、抓到 6 條 STALE,但刻意一句沒改。 本輪改掉其中 4 條,並且先做那份稽核自己指出的前置條件:把 key 從 file:line 改成內容定址 file#sha8@k。這兩件是同一件事——舊的 key 一被編輯就當場作廢 (第 88 輪自己撞到兩次,覆蓋率掉到 41.5%),不先換 key,改完就驗不動。 | 量 | 改之前 | 改之後 | |---|---|---| | 掃到的句子 | 234 | 239 | | 覆蓋率(工具驗的) | 100% | 100% | | 證據重跑通過 | 234 / 234 | 239 / 239 | | STALE(頁面說沒做、其實做了) | 6 | 2 | | TRUE_GAP / HUMAN / NOT_A_GAP | 16 / 4 / 208 | 19 / 5 / 213 | 改掉的 4 條(另 2 條在 Vacant/HANDOFF.md,規則七邊界,等人類) 1. DECISION_SILHOUETTE.md — 原本寫「選項 4 與 5 的救起對數是空的,因為沒量過」。 選項 5 早就量過(同頁的表:211/365,K=2.0 實測)。人類要拍板的就是這一頁, 而它對要拍板的人說那一格也是空的 ⇒ 最合理的反應就是不作答、等量測。 2. world/README.md — 原本寫「沒跑過小時級(記憶體會不會漲沒測)」。括號裡那半句是假的: 第 81 輪量了四個計數器 3000 幀並照報 jsHeap「沒跑過小時級」仍為真。 3. PROGRESS.md — 寫死的「連續二十六輪」。改成指向 STATE.md 最新一輪的「卡住」, 不是換一個新數字:換數字只會讓同一句在下一輪再過期一次。 4. PROGRESS.md — 「仍未量:每格同型佔比(cells 沒存配對清單)」,兩個半句都過期。 兩條這一輪才學到的修好一個缺口會生出新的假陽性。 更正註記要逐字引述被改掉的原句, 而原句裡就有標記詞 ⇒ 這一頁的密度不會因為修好而下降。 4 條改動生出 8 句新的(5 句更正註記判 NOT_A_GAP、2 句 TRUE_GAP、1 句 HUMAN)。 • 第 88 輪那條判決自己有一處不準:它說 cells 存了三份配對清單, 實測 degen_pairs整數計數不是清單(rescued_pairsrescued_clean_pairs 才是,18 格逐格核對長度相符)。更正文字照實測寫。 擋住「用刪字讓稽核變綠」的三道numguard.py(既有數字一個都不准少, 自驗含 0.55740.5575 必須 FAIL)· 剩下的 2 條 STALE 必須還在 · 每條改動的改前/改後全文都在 git diffSTATE.md 裡。

✅ 第 88 輪:歸檔裡「自承還沒做」的句子全掃 234 句——6 條是假的,最貴的兩條在每輪必讀的 HANDOFF.md(commit ec6fd57

現在到哪:第 86、87 兩輪各自偶然撞到一句「頁面寫著還沒做、其實早就做了」。 第 87 輪那一句卡住人類 27 輪。兩次都是撞到的,不是找出來的 ⇒ 這一族缺陷沒有清單。 本輪不再找第三個個案,是把這一族列全:styles/probe/gapaudit.py 掃固定檔案集 (9 份 .mdPROGRESS.mdVacant/HANDOFF.md + 全部 probe .py 的模組 docstring),逐句判、逐條附證據並重跑證據。產物 GAP_AUDIT.md 一句一行。 | 量 | 值 | |---|---| | 掃到的句子 | 234 | | 覆蓋率(工具驗的) | 100% | | 證據重跑通過 | 234 / 234 | | 逐句手判 / 規則判 | 121 / 113 | | STALE(頁面說沒做、其實做了) | 6 | | TRUE_GAP(真的沒做) | 16 | | HUMAN(等人類) | 4 | | NOT_A_GAP(正則誤中) | 208 | 6 條 STALE,逐條可查(每條在 GAP_AUDIT.md 都有正證據 file:line): | 在哪 | 說了什麼 | 證據 | |---|---|---| | Vacant/HANDOFF.md:43 | 「六種風格提案…等人類選一個」 | PROGRESS.md:1181:2026-08-15 已選定黏土定格 | | Vacant/HANDOFF.md:42 | 「未跑:…B 層六情境驗收…」 | PROGRESS.md:2012:B 層六情境 ✅(commit 0fb0b57)| | DECISION_SILHOUETTE.md:322 | 「選項 4 與 5 的救起對數是空的,因為沒量過」 | 同頁 :48:選項 5 = 211/365(K=2.0 實測) | | world/README.md:614 | 「記憶體會不會漲沒測」 | SOAK_FINDINGS.md:97:第 81 輪量過(前半句「沒跑過小時級」仍為真)| | PROGRESS.md:2217 | 「連續二十六輪等人類」 | STATE.md:第 87 輪已是「連續第二十八輪」 | | PROGRESS.md:2530 | 「仍未量:每格同型佔比…cells 沒存配對清單」 | DECISION_SILHOUETTE.md:318:第 61 輪已補上 | 這一輪真正的發現不是 6 這個數字,是它們長在哪Vacant/HANDOFF.md 只有 4 句 被掃到,其中 2 句過期(50%,全檔案最高密度)——而它是**開場清單第 2 項, 每一輪都會被讀**。PROGRESS.md 146 句只有 2 句過期(1.4%)。 ⇒ staleness 的成本 = 錯誤程度 × 被讀的次數,而前 87 輪的稽核只看前者。 最短、最常被讀的那份文件,從來沒有人查過。 執行端本輪開場就被 HANDOFF.md:43 誤導了一次(以為視覺風格還沒選定)。 工具的重點是它會說「不過」:自驗 T1–T6 先答已知答案(T4/T5/T6 專測檢查器會不會 拒絕);另外在真資料上做了變異測試——把一條真 STALE 的證據行號 +1,整支 FAIL 且 exit 1。負證據第一版寫錯過一次:拿主題詞 grep 去證「沒做過人眼量測」,命中的 是 ss_opts.py:357不是觀眾實測」——宣告缺口的那句話本身。 ⇒ 負證據必須是做了才會存在的簽名,不是這件事被談論時會出現的詞。 ⚠ 自指:第一次跑完是 220 句;把這一則紀錄寫進本檔之後重跑變 234 (+14 全部來自這一則自己,落在日誌區)。這份稽核的報告本身會增加它所稽核的語料。 還差什麼:(a) 本輪一句原文都沒改(改字是下一輪的事,一次改一批會讓「改了 什麼」不可查);(b) 標記表會漏——HANDOFF.md:97「視覺風格(六選一)」也已作廢, 但那一行一個標記詞都沒有,是人手撞到的 ⇒ 234 不是上界;(c) 113 句(本檔日誌區) 是規則判的,沒有逐句查證,GAP_AUDIT.md 逐條標了 [規則判]; (d) 事前六格押注中 1 錯 5,其中 NOT_A_GAP 佔比 88.9% 超過事前寫死的 70% 紅旗 ⇒ 照規定報告紅旗已觸發,那一類該被抽查,不解釋掉。

✅ 第 87 輪:那一頁自己寫著「展場距離還沒量」——查證是假的,而它可能就是卡了 27 輪的原因(commit 91db113f95b394

現在到哪DECISION_SILHOUETTE.md(五選一,人類未作答第 27 輪)末段 「這一頁沒有回答什麼」第 1 條原本寫著「縮到 640px 的實拍對照還沒做」。 查證:stagevis.py:44W, H = 640, 360 # 展場距離:1920×1080 的 1/3, 那一頁四份上游歸檔的 W,H 全部是 640,360、讀的檔全部是 sl_f*_640.png那一頁每一個數字本來就是在展場距離量的。那半句已刪。 這件事的形狀值得記住:「沒量過」與「量過但頁面說沒量」,在歸檔裡長得一模一樣, 而後者會讓看的人合理地決定「等那個量測再說」。第 86 輪是「限定詞被讀成結果」, 這一輪是反向的同一個病。 新的一欄:距離要價多少ssdist.py,同一把尺在 1920 重跑,零渲染) | | 640(展場距離) | 1920(貼臉看) | |---|---|---| | 遮罩面積 px 中位 | 85.5 | 693.5 | | bbox 高 px 中位 | 13.5 | 40.5 | | IOU_SPEC(桿子) | 0.5574 | 0.5279 | | 難分對數 / 946 | 365 | 364 | 看起來距離不要錢——是假的。這把尺的桿子自己跟著解析度移動。桿子釘住再問: 1920 的 IoU 用 640 的桿子判 ⇒ 310/946(不是 364); 640 的 IoU 用 1920 的桿子判 ⇒ 442/946(不是 365)。 ⇒ 距離要價 55–78 對,而「365」是相對於同一解析度的數字,不是距離無關的事實。 Spearman ρ = 0.9592 ⇒ 動的是桿子與絕對值,配對的排序幾乎不受距離影響。 那 47 對硬核在 1920 仍然 47/47 難分 ⇒ 它是幾何,不是低解析度的量化雜訊。 順帶擺上桌一件那一頁沒寫的事:展場距離下一個居民只有 13.5 px 高、85.5 px 面積 (中位)。那 47 對硬核是在這麼大的色塊上量出來的。 還差什麼:仍然沒有人量過「觀眾分不分得出來」——那要真人,本輪一樣沒有, 第 1 條的前半句留著。五選一仍然等人類(第 27 輪)。 這一輪押錯三格,照報:押「距離會吃掉一大塊」(1920 難分 250–340、翻面 ≥40、 面積比 9–13),實際是 364、34、8.038。我押的方向整個錯了,而「幾乎沒動」 正是我事前寫下最怕的那個乾淨結論——擋住它的是 T2(面積比必須 ≥5, ~1.0 就是我兩次讀到同一張圖)與 T3(尺寸從 IHDR 讀),不是任何一個主數字。

✅ 第 86 輪:「整檔 sha256 的比較不在盤點範圍內」——那句限定詞被當成結果讀了兩輪(commit b09ba586dcfd91

第 84 輪的盤點器在自己的 docstring 裡把邊界寫清楚:**只掃 diff_mask, 整檔 sha256 那一族不在內**,並點名了兩個站點。那半句是誠實的。 被後面兩輪讀成「所以大概就那兩個」的另外半句,從來沒有人查過。 數出來:38 個站點、10 支檔案(不是 2 支),比 PNG 的 16 個, 承重(pass/fail 會被讀成結論)5 行,其中比 PNG 的 2 行。 兩件會改變我們相信什麼的事: 1. A2_optin 的「沒過」100% 是畫面上那個 fps 讀數。 整檔 sha256 相同 15/49(就是落盤且判 FAIL 的那個數);挖掉 HUD 之後 逐位元相同 49/49。判準與門檻一個字沒改、照樣照報沒過,但它沒過的 理由現在知道了——那 34 張的差異一個像素都不在場景裡。 ⇒ DECISION_SILHOUETTE.md(人類正卡著的那一頁)的出處保證變強。 2. 第 67 輪的證據 .png 從沒進 repo(撞到的,不是想到的)。 hudleg.py:180 是一個從來沒被盤點過的承重 PNG-sha 判準;它不是污染 (比的是純文字頁,rAF/Date/fps/random 全 0),但拿 repo 裡那 48 張重算, 逐格 match 第 66 輪、對不上第 67 輪。詳見上面第 67 輪那段的更正框。 **.json 進了 repo、它算所依據的 .png 沒進——這一對在歸檔裡跟「都進了」 長得一模一樣。** 事前押的七格中四錯三(押注一個字沒改,錯的照報)。押錯的 P4 (「承重 PNG-sha 恰好 1 個」,實際 2 行)反而是這一輪的引信:正因為多出 一行,hudleg.py:180 才被逼著看一眼,第 2 條才會被撞到。 還抓到自己寫了一個會自我餵飽的判準P6「沒寫理由的站點數」由執行端 手寫的分類表決定 ⇒ 只要一直往表裡加東西它就會過。它報 0 不算證據。 ⇒ 新的一條:寫判準時要先問「這一格我能不能自己讓它過」。 工具自己在兩次跑之間被抓到兩個假陽性(站點 42 → 38),第二個 (巢狀 defsys.exit(main()) 被算成站點)剛好就在本輪最重要的那個檔案裡收尾時還自己撞到一次自指6dcfd91):改 hudaudit.py 的 docstring 指回新工具, 就把被分類的那一行從 318 推到 324,剛落盤的分類表當場過期。跟第 85 輪的 A8_scope 同形——稽核工具的產物與它稽核的對象在同一棵樹裡。 這次壞的方向是「變成未分類」(吵的),不是「靜靜指到別行」(安靜的); 是運氣好在方向,不是設計對。

✅ 第 85 輪:承重判準修完沒翻,但它過關的理由整個換掉了(commit 10f85c5

第 84 輪靜態盤點點名 sa_arch.py 兩處 diff_mask 沒挖 HUD,於是 maxmedsum/「噪底」四個數字全都在量畫面上那個活的 fps 讀數—— 而承重判準 A2p_vs_control 比的正是 max。這一輪修掉並重跑 (零重渲、零機時,四批 PNG 就是原來那批,整支 18 秒)。 | 量 | 不挖 HUD(=已落盤的舊值) | 挖掉 HUD | HUD 佔比 | |---|---|---|---| | sl_×sb_ max / med / 總和 | 38 / 7 / 390 | 0 / 0 / 0 | 100% | | sl_×sc_ max / med / 總和 | 38 / 5 / 328 | 0 / 0 / 0 | 100% | | sb_×sc_ max / med / 總和 | 38 / 7 / 323 | 0 / 0 / 0 | 100% | | 噪底 base vs base2(四批) | 12 / 8 / 11 / 0 | 0 / 0 / 0 / 0 | 100% | ⇒ 那四個數字 100% 是 HUD,一個像素都不是場景。事前押的七格全中, 包含兩格從沒量過的(sl_×sc_sb_×sc_ 挖後為 0)。 這一輪最該記住的形狀:綠燈不會告訴你它是被什麼點亮的。 A2p_vs_control 修前修後都 PASS,所以從「過了沒」完全看不出發生了什麼事: • 修之前38 <= 38 ⇒ 過。比的是兩個 fps 計數器的位數。 • 修之後0 <= 0 ⇒ 過。比的是**三棵樹(歸檔/我的樹/改動還原的對照樹) 在 HUD 以外逐位元相同**。 判準的字一個沒改,內容從幾乎是空的變成很硬。 ⇒ 「這一格過了」本身不是資訊,要問它是靠什麼過的。 事前最怕的事,以及擋住它的東西:本輪押的主數字是 0,而「0」正是 遮罩把整張圖吃掉、或比對器瞎了會給的答案——它會同時關掉複查的動機。 擋住它的不是主數字,是 T1:HUD 之外一個已知恰好 12 px 的方塊, 挖完仍要讀到 12(實測 12→12);T2 是 HUD 之內同樣 12 px 要被挖成 0 (實測 12→0)。另加 T6凍結判準之後才加、方向只會更嚴):不挖的重算值 必須逐字接回舊值,否則「修好之後變 0」可能只是換了一把尺。 影響範圍sa_arch.json 570 個葉節點只有 14 個動,12 個在 reproducibility,另 2 個是顯示字串與計數註記。配對表與 A5/A6 一個數字沒動 (難分 365、候選 154、同型救起 0、異型救起 5)——因為取剪影那一段本來就挖了 HUD。 ast 重新盤點:沒帶 hud= 的呼叫點 4 → 2,剩下兩格是檔案裡寫了理由的刻意例外。 順帶抓到(撞到的,不是想到的)A8_scope 這個範圍稽核**把自己的產物 算進了它稽核的範圍**——sa_arch.py 沒辦法在同一次 run 裡既重生成 sa_arch.json 又讓 A8_scope 過(寫檔本身就把樹弄髒了)。它只在 commit 與 commit 之間收斂。 本輪不改它:加一行白名單看起來明顯是對的,但那是看過資料之後動承重判準, 跟移動球門同一個形狀。記成下一輪的工作單。 也更正了上一輪自己的一個估計:第 84 輪寫「要重跑整批,而那要機時」—— 四份 .sha 其實全在、單次差分 0.05 秒。成本估計錯了,代價跟量錯數字一樣大: 它讓一件 18 秒的事白擱了一輪。

✅ 第 84 輪:第 83 輪查到病灶,這一輪量了後果——A2_optin 挖掉 HUD 之後 49/49 差 0 px(commit 4fdba15

第 65 輪把「逐位元相同」判成在構造上就達不到,並把這句話寫進了 sa_arch.py 的碼裡。第 83 輪查明病灶是 HUD 上那個活的 fps 讀數。 這一輪量後果,零機時、不重渲,只讀已歸檔的位元組(sl_ 49 張 × sb_ 49 張): | # | 量什麼 | 事前預測 → 實測 | |---|---|---| | M1 | 不挖 HUD、整檔 sha256 相同 | 15 → 15/49 對 | | M2 | 挖掉 HUD 4 列之後差 0 px | 49 → 49/49 對 | | M3 | 有差異的 ⊆ HUD 列 | 49 → 49/49 對 | | M4 | 不挖 HUD 的最大差異像素 | 1–200 → 38 對 | 四條全中。M1=15 逐字接回第 65 輪報的數字 ⇒ 磁碟上這批位元組確實是當年那一批。 ⇒ A2_optin 不是達不到,是被一個診斷用的讀數擋住的。 這對人類正要拍板的 DECISION_SILHOUETTE.md 有份量:那 148 條數字的出處保證靠的就是 「同一棵樹渲兩批一不一致」,而它現在從「本來就達不到」回到「達得到、也達到了」。 ⚠ 但凍結的閘門先沒過一格,而那一格比主數字值得記。 H2sl_base vs sl_world 挖 HUD 後 > 10000)實測 386。沒翻的原因**不是 比對器壞了,是我的計畫寫錯了前提**:sl_ 不是「完整場景的基線」,它是 hide=shell,furn,fig*獨自一人批——非背景像素只有 0.5%、 單人剪影 36–157 px;同一格在真正的全景批 ss_ 上是 46192。 我是照著 sa_arch.py:53 那句只寫「基線那 49 張」的註解寫判準的。 > ⇒ 一句不完整的註解,下一輪就會長出一個錯的判準。 > 這是 HANDOFF §8「兩份實作會漂」的孿生: > 一份知識只長在一份實作上,讀註解的人就會自己重新發明一個錯的前提。 > 連兩輪撞到同一族——第 83 輪是 silscene.sh 沒有 stagevis 那份 HUD 知識, > 於是重新發明了「渲染器不決定性」;第 84 輪是註解缺一個限定詞。 處理照第 43 輪先例,沒有事後放寬H2 門檻與原文一個字不改、照報沒過; 另立 H2b_visible,刻意不含任何挑選常數(44/44 都看得見一個人)。 主數字因此標成 VERDICT_TOOL_B,並在交付物第 1 條誠實邊界寫明 它的保證比「事前全部翻掉」弱一級擋住錯誤結論的是 H3H4,不是 H2 我押的答案是「挖掉之後 0」, 而「0」也正是「比對器瞎了」會給的答案。H3=HUD 之外一個已知恰好 12 px 的方塊要讀到 12(證明這把尺解析得到 fps 假象那個數量級)、H4=同一個方塊放進 HUD 列要被挖成 0(證明遮罩挖對地方)。兩格都翻了 ⇒ 這次是假說對、尺也對, 與第 83 輪(尺對、假說錯)分開記。 順帶盤點(靜態、未重量)diff_mask35 個真實呼叫點裡 4 個沒帶 hud=——2 個是真的污染且都在 sa_arch.pydist()max 正是承重判準 A2p_vs_control 比的那個數;noise 那格就是第 65 輪錯解釋的出處), 另 2 個是 stagevis 刻意保留的原始差異診斷、檔案裡逐字寫了理由。 兩個量具坑(撞到的不是想到的,都留在碼裡) 1. 盤點第一版用 regex,把 ss_src.py docstring 裡引用的一行文字報成 呼叫點。改用 ast 後從 37/5 變成 35/4。假陽性在工作單上會讓人去改一段不存在的碼。 2. md 的分類表第一版用 (檔名, 行號) 當 key。我在 sa_arch.py 加了幾行註解, 136/162 就漂成 156/162,兩格當場掉進「未分類」。⇒ 改用呼叫那行的變數名當 key。 交付物 styles/probe/HUD_AUDIT.md(數字從 JSON 插入,不手打)。 重跑:bash styles/probe/hudaudit.sh(零機時,可隨時對帳)。 sa_arch.py 只加更正註解與缺失的限定詞,判準/門檻/邏輯一個字沒改world/ 零修改。 還差什麼sa_arch.py 那兩格真的污染要修,但修了會動到承重判準 A2p_vs_control 的值 ⇒ 要重跑整支,而它需要 /tmp/b65/*.sha(已不存在) 與四批 PNG。先盤點重跑成本再動。

✅ 第 83 輪:第 65 輪那句「這台機器的渲染不是逐位元決定性的」是錯的,該撤回(commit 4b83b4e + 更正 845b561

第 65 輪量到「同一次 run、同一個 URL、同一個 freeze=20ss_basess_base2 差 8–12 px」,結論寫成 「這台機器的渲染不是逐位元決定性的」, 並據此(一)把 A2_optin(49 張逐位元相同)判成「判準本身從一開始就達不到」, (二)回頭對第 62/63 輪投下懷疑(「那兩輪剛好讀到 0 px,是那幾批的性質, 不是這台機器的性質」)。 兩條都不成立,而且方向剛好相反。 差異像素全部是 HUD 上那個活的 fps 讀數:兩種擷取機制、30 個配對,差異落在 (1282,17)-(1326,26) = 45×10 px(佔畫面 0.0217%);挖掉 HUD 那 40 列之後,30 個配對剩 0 個像素在動。 K5Range.getBoundingClientRect 把座標換成字元——命中的是 1 0 ␠ f p s,也就是 main.js 那行 HUD 的最後一段 繪製 ${fps} fps。 HUD 上其他每個數字都是 t 的純函數,freeze=20 之下逐次相同;只有 fps 是量出來的。 ⚠ 這個病灶不是第 83 輪發現的——第 16、33/34、43、62 輪都寫下過, 第 62 輪甚至已經量過同一件事(挖掉 HUD 四列之後 49/49 全部 0 px)。 本輪新的是三件:(1)第 62 輪量的是 640px 批次,本輪在 1920×1080 上同樣結果; (2)第二種、獨立的擷取機制(CDP + 真實 wall-clock 等待)也一樣, 而且差異更大(213 vs 45 px)、全部仍在 HUD 裡 ⇒ 「渲染器不決定性」與 「拍在畫格中間」兩個解釋都被排除;(3)字元級指認取代像素座標指認。 ⇒ A2_optin 不是達不到,是被一個診斷用的讀數擋住的; 第 65 輪加在第 62/63 輪身上的警語應該撤掉。 這對人類正要拍板的那一頁有份量:DECISION_SILHOUETTE.md 那 **148 條數字的 出處保證,正是第 62 輪用「重渲染逐位元比」做的**。 這一輪押錯了,而擋住錯誤結論的是事前寫死的已知答案。 五條預測三條錯, 包括我押的那一條(M3:CDP 拍出來會逐位元全同 → 實測 6 張裡 3 個相異 sha)。 停在那裡的結論會是「渲染器也在抖」,那也是錯的。救回來的是先問 差異在哪、再問差異是什麼。尺的五側已知答案裡最關鍵的是 W6b: fixture 的 4×4 scissor = 已知 16 px 的差異,就在 8–12 px 這個數量級上 ⇒ 證明比對鏈解析得到那個尺度。沒有它,「全同」可以只是比對器瞎了, 而「全同」正是我押的答案,也就是我最沒有動機複查的方向。 量具坑(留在碼裡)K4 連載 4 次讀 HUD 字串全同(fps 都是 11), 看起來像在打臉 fps 假說;但 K5 那一趟讀到的是 1 0(fps=10)。 ⇒ 欄位確實會變,K4 的 N=4 不足以抓到。不准把「K4 沒抓到」寫成「fps 是穩定的」。 交付物vacant_hm/styles/probe/GL_FINDINGS.md(由 glnoise_md.pyglnoise.jsonglnoise_k.json 產生,數字不手打)。 入口:bash styles/probe/glnoise.shbash styles/probe/glnoise_k.shcdp.pyvacant-docs-web/probe/cdp.py 的逐位元組複本,sha256 由 W4 釘死。 world/ 零修改、既有量測腳本零修改;移除或凍結 HUD 的 fps 讀數是**畫面上的 決定**(規則七),不自己拍板。

✅ 第 81 輪:無人值守長跑第一次被量——四個計數器 3000 幀不動(commit 3f67e06

展場是無人值守的,而這種失效在任何單幀截圖裡都不會出現。 黏土場景量過 剪影、色盤、遮擋、判決、四段可見性,「跑久了會怎樣」一次都沒量過; world/DEPLOY.md 那節實機效能量的是舊世界?day=30,466 隻),不是這一支。 clay.html600 幀(45.9 秒)與 3000 幀(230 秒)geometriestexturesprogramsmeshes 四個計數器 Δ 全 0 (450/2/4/566)。同趟旁證顯示世界確實在動(courierShown 14→17onTable 12→9、模擬時鐘 230 秒),不是畫面凍住所以什麼都不長。 ⚠ 只能讀成「這兩個窗內沒有量到成長」,不等於「不會漏」——檢定力聲明是 跑之前寫死的。展期是八小時,窗長只有 230 秒。 事前預測先被自己的 pilot 打翻一次:押 Δ=0,60 幀那趟量到 +79。 攤開三段曲線才看得出那是暖機不是洩漏—— 60 幀 297→333→376(還在爬)、600 幀起一路平在 450。 ⚠ 事中登記的斜率規則在成長全 0 時退化(兩條同時成立),照實記「規則沒用上」。 量具兩側都翻了才採信:洩漏側(每幀 new BoxGeometry 不 dispose)+500、 乾淨側 0/0。只驗乾淨那一側不夠——一個永遠回報 0 的壞取樣器會通過, 而 0 正好是事前押的答案。 還差什麼: • 「夠不夠快」沒有答案,那是無人值守的另一半。要在展場那台(RTX 3090) 跑同一支腳本;DEPLOY.md 已寫明現在那台顯存被 llama-server/VMware 佔著。 機時/人類事項,不是程式問題。 • 更硬的窗:FRAMES=50000 過夜跑一趟,同一支腳本只改一個環境變數,零額外程式。 順帶量到三個量具事實(下一輪任何用 headless chrome 的量測都會踩到): ① --virtual-time-budget 底下,沒有重計時器的頁面一幀 rAF 都不會被服務reachedFrame: 0,同趟 setInterval 跑了 600 次)。 ② 拿掉虛擬時間之後 --dump-dom 會在載完當下就走 ⇒ 改成頁面 POST 回本機收件口。 ③ posePerSecWallperfSec=0 時是 Infinity,JSON.stringify 寫成 null那一欄的型別會跳,跑四次沒抽到。 **狀態:黏土定格視覺施工中。交付狀態機四段(carryingreviewaudit/ 結局)現在全部在畫面上,判決是機制那一份算的,**每一次換檯面都是看得到的 過程**(audit 的抽走、以及判決之後送去歸檔架/退回台),而紙一旦放下就 不再移動。** ✅ 第 63 輪起,交付狀態機那一組數字的出處是量過的(不是講道理的): 兩批各 6 張用 HEAD 這棵樹重渲染逐位元比,T 沒動、挖掉 HUD 後 0 px。 細節見最上面第 63 輪那一段。 ⚠ 「剪影站住了」這句在第 43 輪被切成兩半,要分開讀:在展場距離 (640px 寬)的全景裡真的判過了——剪影的「差異」站住了(同層比值 2.0–3.2、世界身高與畫面高的等級相關 0.52–0.99,N2/N3 過), 但絕對尺寸沒站住(N4 ✗:畫面 bbox 高中位數 13.5 px<門檻 15、 最小 3 px<門檻 8)。觀眾分得出誰是誰的前提是先看得到人。 怎麼修是視覺風格方向 ⇒ 規則七,等人類(見最下面「卡住」段)。 ⚠ 第 47 輪把 N4 拆成兩個獨立的問題,兩個的答案相反(三個 fov 各 49 張 真的截出來量的,不是算的):中位數是尺度問題,縮 fov 就修得好 (30.769° 量到 15.0、27.694° 量到 16.5,與投影幾何算的差 0.0/0.24 px, 建築一個角都沒被裁);最小值是遮擋問題,縮 fov 修不好——3 → 2 → 2, 放大之後反而更小,而且全場最小的一直是同一個人 f1r9(世界身高 1.81, 全場最高那一群,被樓板切成 2–4 塊,只剩 2 px)。 ⇒ 要人類決定的不再是「fov 要不要縮」,是「一個 1.81 的人只剩 2 px 該接受, 還是要動遮擋」。 ⚠ 第 48 輪去找「是誰在擋」,把兩個最像的嫌犯都排除了——選項從四個砍到兩個。 兩支新探針把切口從像素講成世界座標(ss_cut.py 世界 y/ss_cutx.py 世界 x), 零渲染成本,用第 47 輪已落盤的三個 fov 各 49 張。兩條跑之前寫死的預測都錯:不是樓板。 只有第 3 層的樓板前緣擋得到(純幾何算的掠射線 y=11.705, 擋掉腳上方 0.135 個世界單位),第 0–2 層相機在樓板上方,擋不到。 8 個列空隙有 6 個確實跨到那條線——但那 6 個全在第 3 層,其餘樓層的切口 樓板一個都解釋不了。順帶更正上面第 47 輪那句「f1r9樓板切成 2–4 塊」: f1r9第 1 層,樓板對它不適用,它那兩個切口不是樓板造成的。 • 不是樓梯。 原始碼裡最像的嫌犯(STAIR_X=[roomX(3),roomX(9)]STAIR_RUN=2.1、 站在 CORRIDOR_Z=2.55 = 居民前面):r3/r9 那 8 人有切口比例 1/8 = 0.12, 其他 11 欄 4/36 = 0.11——沒有富集。7 個欄空隙只有 1 個落在樓梯範圍內。 量到的是 0.12–0.75 個世界單位的碎邊,散在 r0–r3;hide=shell,furn 那組 15/15 個切口全部消失 ⇒ 建築/家具,不是人擋人(此條偏差方向對它有利,弱證據)。 ⇒ N4_min 目前沒有單一參數的解。 剩下的選項只有兩類,都是規則七: (a) 改 N4_min 這條門檻本身(接受少數人在展場距離只剩 2–3 px); (b) 把居民站位往前挪(CELL_Z 0.75 → 靠近 CORRIDOR_Z),一次減少所有前方碎邊。 (b) 可以先用純投影幾何出效果,不必動 render 也不必截圖。 ⚠ 第 48 輪同時記下自己的兩個限制(免得下一輪把它讀成已解決): 兩支探針事先寫死的閘門沒有全過R1_srcmanss_ 那組的來源 manifest 落後兩輪;A3:y 軸的反向已知答案不夠力,量出這把尺只能把深度框到 ±6A4/A5/B4/B5:三格配對只有 6 與 4,少於事先寫的 8)⇒ **上面每一個數字都是 「照報」,不是「判定通過」。** 另外,44 人裡 nComp>1 有 21 個,而列空隙只抓到 7 人、欄空隙 5 人 ⇒ 多數碎裂既不是乾淨的橫帶也不是乾淨的直帶, 現有兩把尺對它們仍是瞎的。 ⚠ 第 51 輪換了問題:八輪都在量「看不看得見」,沒人量過「彼此分不分得出來」。 第 43–50 輪連續八輪量的是遮擋(一個居民剩幾 px),而優先序第一順位寫的是 剪影差異。兩件事不一樣:44 個人都清楚可見、但長得一模一樣,展場一樣是失敗的。 零渲染(用第 44 輪落盤、第 49 輪已驗過是純本體的 sl_ 那批)。 讓規格自己定門檻,不要挑:把「身高差 1.6 倍」翻譯成尺上的一個數 (腳底對齊放大 1.6 倍後的 IoU,44 人取中位 ⇒ IOU_SPEC = 0.3237)。 比它高的配對,就是比規格下限還難分結果(E/Q 類全過的第一、第三階段才算數): | 量到的 | 值 | |---|---| | worldH max/min | 2.419(規格要 1.6 ⇒ 早就超標;跑之前預測「沒達標」,預測錯了) | | 946 對 IoU 中位 | 0.516 > IOU_SPEC 0.3237 | | 比「身高差 1.6 倍」還難分的配對 | 818/946 = 86.5% | | 最難分的一對 | f0r10 × f2r8 IoU=0.9556(兩個都 stand,不同層) | | 同層相鄰(觀眾最容易並排比較) | 40 對裡 37 對比規格下限難分 | | 展場距離下的剪影高 bbH | min 9/中位 13.5/max 21 px | ⇒ 第一順位「剪影差異」沒有達成,但瓶頸不是身高的範圍(範圍 2.419 倍, 夠寬),是典型配對的差距:946 對的身高比中位只有 1.246, 只有 14.0% 的配對達到規格的 1.6 倍。max/min 是極值統計,不是觀眾的體驗。 往哪個方向補(身高改雙峰?加胖瘦/頭身比/肩寬?)是視覺方向 ⇒ 規則七兩次被自己寫的判準擋下來,兩次都沒有事後放寬——這是這一輪最該留下的形狀: 1. 第一階段 E 類 5/5 全過,但 C13(專門寫來擋「什麼都說一樣」的壞尺)爆了 ⇒ 86.5% 當下有嫌疑,不能就這樣用,先去查尺。 2. 第二階段 Q4(反向已知答案)爆了,原因是判準被錨錯量(0.02 錨在 「站×站−跨姿」的 0.0159,卻拿去量「同姿−跨姿」的 0.0328)。 照規矩 C14/C15 照報但不算數把 Q4 改成 0.05 會剛好過 ⇒ 不做。 3. 第三階段不放寬門檻,改問一個跑之前不知道答案的更難的問題:置換檢定。 隨機重排 44 人的 pose 標籤 200 次(固定 seed,個數不變), 真實落差 0.1093、置換 q95=0.0403、0/200 達到p=0.005尺看得見坐站,C13 的失敗是被組內身高變異蓋掉的,不是尺壞了。 誠實邊界(都寫在對自己不利的方向):腳底對齊拿掉了位置線索,實際場景 位置也幫忙分辨 ⇒ 86.5% 高估了難分程度;這把尺量的是整體剪影, 答得出「分不分得出來」,答不出「是哪一項不夠」(下一輪拆四個維度)。 ⚠ **第 52 輪拆掉了那把尺,答案有一半跟直覺相反:寬度的變異已經比身高大, 卻換不到分辨度。** 零渲染,3.3 秒(styles/probe/ss_dim.py,commit 627dab8)。 不用「分別量身高變異與寬度變異」——不同單位比不了——改用反事實抹除: 把 j 垂直縮放到與 i 同高再對齊,IoU 上升多少,就是身高目前貢獻了多少分辨度探針自驗 8/8(D3 純身高差必須被身高那一項吃掉、D4 換一軸必須換答案、 D5 bbox 已相同時正規化必須完全不動、D1b 逐字重現第一階段的 0.51595): | 抹掉哪一項 | IoU 上升 | 意思 | |---|---|---| | 身高 | +0.120 | 目前撐「分得出來」的主力 | | 寬度 | +0.033 | 只有身高的 1/3.6 | | 兩軸都抹(noHW) | +0.213 → 剩 0.735 | 輪廓+姿勢+頭身比合起來只剩 0.265 | 這一條會改變「該補哪一項」的答案:世界的寬度變異範圍其實比身高大bbW 4–15 px=3.75 倍;bbH 9–21 px=2.333 倍),卻只換到 1/3.6。 ⇒ 「寬度沒在做事」不等於「寬度變異不夠」——變異已經在那裡,是在**中位 9 px 的寬度上換不到剪影差異(1–2 px 的差在展場距離不存在)。「加胖瘦」不是自動的 解法**,把胖瘦拉到 5 倍可能仍然換不到東西。⇒ 選項不是「身高/胖瘦/頭身比三選一」, 是「動身高的分佈形狀 / 動絕對尺寸 / 接受」。仍是視覺方向 ⇒ 規則七。 (頭身比與肩寬在 13.5 px 的剪影上沒有可靠量法——頭只佔 2–3 列—— 所以它們混在 0.265 的殘差裡,不單獨宣稱。) 順帶:第 51 輪因 Q4 爆掉而「形式上不算數」的 C14 重驗過了,數字逐字相同 (配對身高比中位 1.246、達 1.6 倍的 14.0%)。 ⚠⚠ 第 53 輪把上面第 51 輪那個 86.5% 打掉了——那個數字是「尺」造出來的。 零渲染,3.9 秒(styles/probe/ss_dose.py,commit aa141d3)。 第 51/52 輪的縮放器(逆映射)不保證「達成尺寸 = 目標尺寸」:叫它做出 10 px, 實測會落成 9/10/11。換成索引精確重映射K7:44×8×2 格達成=目標,全中) 之後,用同一條規格規則(身高剛好差 1.6 倍)重算「規格下限」: | | 第 51 輪(逆映射+補洞) | 第 53 輪(尺寸精確) | |---|---|---| | IOU_SPEC(規格下限) | 0.3237 | 0.5574 | | 比規格下限還難分的配對 | 86.5% | 38.6%(365/946) | | 世界的配對 IoU 中位 | 0.5159 | 0.5159(同一個數,兩輪都是) | ⇒ 配對中位 0.5159 已經在規格下限以內。「典型的兩個居民分不出來」這個前提不成立。 旁證是解析上界:垂直拉 1.6 倍、腳底對齊,矩形的 IoU 上界就是 1/1.6 = 0.625; 0.5574 剛好在上界之下(實心剪影該有的樣子),0.3237 遠在上界之下——那要求放大後的 剪影帶了約兩倍不該有的面積。(誠實邊界:沒有重跑第 51 輪那支去隔離它, 「0.3237 是錯的」是推論不是直接證明。) 同一輪也把上面「寬度換不到東西」那句修正了一半:那是 gain(抹除法)的說法, 它答「現在貢獻多少」,不答「加大會多有效」。把變異當劑量掃出來的結果是—— 寬度加得動:m=4.0 把配對 IoU 中位從 0.5159 壓到 0.2609。 但代價是真的:W m=1.5 就有 1 人被壓成 1 px 寬,m=4.0 有 7 人。 同劑量下身高比較划算(H m=2.0 → 0.3915、沒有人被壓扁;W m=2.0 → 0.4070、5 人 1 px)。 完整 24 格(含被 clamp 人數、遮罩整個空掉的退化人數、worldH 近似範圍)在 styles/probe/ss_dose.json第 53 輪也拿精確的尺去推翻第 52 輪的「寬度只有身高 1/3.6」,推不倒(C24 錯): 比值只從 3.60 動到 3.00,而反向的對照(身高不該被換尺改掉)對了(差 0.002)。 ⇒ 上面那張抹除表仍然成立。(形式上該階段的自驗 V2/V3 沒過 ⇒ 不算數, 而它指向的是「第 52 輪站得住」,是保守方向。) 第 53 輪一輪之內寫出三條數學上為假的判準(K3 要求縮小時另一軸尺寸不變、 K4b 的奇偶推導漏了 t−1、V2/V3 要求有損縮小可逆)。處理方式: 兩條靠把「工具」變精確而收回原本更嚴的判準,一條沒辦法收緊就讓它 FAIL 留在紀錄裡 (第三階段照報但不算數)。判準一次都沒有事後放寬。 第三次被自己寫的判準擋下來,第三次沒有事後放寬:D6(決定性)第一次跑 FAIL。 先查再修——查出來是比較器壞了不是量測壞了(拿 round(round(x,6),4)round(x,4),946 對裡 5 對踩到雙重進位邊界;量測本身 946/946 未 round 的 float 逐位元相等)。修法是把比較改成未經 round 的 float 逐位元相等比原本的判準更嚴,不是放寬;門檻一個字沒動。 ⚠⚠ 第 54 輪去驗第 53 輪那張劑量表自己的前提,前提對 12.9% 的配對是假的。 零渲染,2.9 秒(styles/probe/ss_hard.py,commit 3220160,探針自驗五條全過)。 那張表隱含「加劑量就會把難分的配對推開」。但劑量是保均值的 t = mean + m×(size − mean),作用在 bbox 尺寸相對均值的偏差上—— 兩個 bbox 幾乎相同的人偏差幾乎相同 ⇒ 任何 m 都縮放到幾乎相同的目標 ⇒ 近乎恆等。 18 格(H/W/HW × m=1.0…4.0)跑完 365 對難分配對: | | 對數 | 佔 HARD | |---|---|---| | 一格都救不起來(劑量無效區) | 47 | 12.9% | | 只有靠「把人壓成 1 px」才救得起來 | 5 | 1.4% | | 不靠 1 px 也救得起來 | 313 | 85.8% | 機制證據不是外推:無效區的 |Δw|+|Δh| 中位 1 px(Q3=2、max=4,其中 6 對 完全相同),救得起來的是 4 px(Q3=5、max=8)。⇒ **問題不是「劑量夠不夠大」, 是「劑量作用的那個量本身是不是相同」。** 無效區有 31/47 是 stand×stand,37/47 跨層。 同一輪改掉了該怎麼讀第 53 輪那張表——它少了一欄: 扣掉「靠把人壓成 1 px 換來的救起」之後,劑量不是越大越好: H 的峰在 m=2.5(198 對)不是 m=4.0(142 對);HW 的峰在 m=2.5(241 對)。 再往上是在毀剪影不是在補差異。第 53 輪報的「W m=4.0 → 中位 0.1538」在這個讀法下 會誤導——那個數字有一半來自把 11 個人壓成 1 px。而 HW m≥2.5 起有居民整個消失k=12 空遮罩,m=4.0 是三人);展場上「居民不見了」不能當成分辨度的進步。 跑之前寫死的三條預測,錯一條照報:C30 我預測無效區 ≥ 55 對(15%), 實際 47 對(12.9%)——錯的方向是保守的(劑量比我以為的有用一點)。 C31(機制解釋)與 C32(雙軸勝單軸)對。判準沒有事後放寬。 誠實邊界:「救得了」不等於「展場上分得出來」,只代表「至少和身高差 1.6 倍一樣好分」, 而 1.6 倍這根桿子對不對本身仍是規則七;「無效」嚴格說是「在這 18 格裡無效」。 ⚠⚠ 第 55 輪排除掉「那 47 對是同一個模型換了顏色」——形狀差異已經在畫面上了。 零渲染(styles/probe/ss_prof.py,commit 97c388d,探針自驗七條全過、重跑逐位元一致)。 第 54 輪證明劑量對那 47 對近乎恆等 ⇒ 剩下唯一能動的是同尺寸 bbox 內的像素分佈 =形狀。而那有兩種可能,指向完全不同的施工:剖面也相同 ⇒ 得重做體型網格; 剖面差得不少 ⇒ 資訊已在畫面上,槓桿是讓它更醒目。量出來是後者。 尺是列寬剖面:bbox 切 8 段(用 ss_dose.remap 同一條整除映射),每段 = 段內 各列填充像素數的平均 ÷ bbox 寬;距離 = 8 段平均絕對差。**兩軸都正規化 ⇒ 這把尺 對劑量恆等**,它量的正是劑量碰不到的那個量。 | | n | 剖面距離中位 | 對全體 | |---|---|---|---| | 全部配對 | 946 | 0.1469 | 1.00 | | 救得起來 | 318 | 0.1134 | 0.77 | | 劑量無效區 | 47 | 0.0966 | 0.66 | 關鍵是三條而不是那個中位數:(1) 47 對裡 一對都不是 0,最相似的 (f0r2×f2r1)也有 0.0312;(2) 尺的雜訊地板(同一個人被拉高 1.6 倍後剖面的 殘差)中位 0.0201、max 0.0637 ⇒ 47/47 在地板中位之上、35/47 在地板最大值之上; (3) 連 bbox 嚴格相同那 6 對,剖面距離都是 0.0312–0.1597。 ⇒ 第 51–54 輪那條「難分」量的一直是 bbox 的難分,形狀那一項從來沒進過那把尺 (兩人肩寬差 bbox 寬的 11%,在 bbox 對齊的 IoU 上只值幾個像素)。 而且形狀信號的位置是可直接施工的資訊:無效區 |Δ| 最大的兩段是 **b=2(肩/上胸, 0.111)b=6(小腿/腳踝,0.111)**,最小的是 b=3–4(腰腹,0.050/0.049); 救得起來那批在 b=4 的 |Δ| 中位恰為 0.000(過半配對腰腹寬度逐像素相同)。 ⇒ 若用輪廓線/硬影強化形狀,該打在肩線與腳踝,不是腰四條預測(C40–C43)跑之前寫死,這次四條都對——但 C40(≥0.05,實測 0.0966)與 C42(≤6,實測 0)事後看門檻偏鬆,「全對」帶的資訊比 FAIL 少,下一輪同類預測要押更緊。 探針自驗有解析已知答案(實心 8×8 對階梯 = 28/64 = 0.4375,逐位元命中)。 誠實邊界,全部寫在對自己不利的方向:**剖面對左右翻轉恆為 0(44/44 實測, 同一批 IoU 中位只有 0.8466)⇒ 這些數字是形狀差異的下界;pdist 是逐對正規化後** 的量,觀眾看的是未正規化的畫面 ⇒ 本輪答的是「資訊在不在」不是「看不看得見」; 0.0966 只有雜訊地板的 4.8 倍,不是大得無疑;第二把尺(remap 到 16×8)給比值 1.14 對第一把尺 1.17,同向,但兩把尺共用同一份遮罩與 bbox 定義,不是獨立的。 ⚠⚠ **第 56 輪去問「居民的體型是從哪來的」——是 clay.js 寫死的六列, 而那 47 對「救不了」有 70% 是同一型。難分的天花板在生成器,不在渲染。** 零渲染(styles/probe/ss_arch.py,commit 69aa9ab)。 ✅ 這批數字現在算數了——第 56 輪跑的時候探針自驗沒全過(P3_label_h FAIL) 所以整批掛著「照報但不算數」;**第 57 輪把門修對後,同一批數字自己合格, 而且一格都沒被重算**(28 個輸出欄位逐位元相同,由獨立比對器驗,見下面第 57 輪)。 第 51–55 輪一路把「難分」歸因到尺、到劑量、到形狀,五輪都沒問過體型的來源。 而 ss_solo.json 從第 44 輪起每一列都帶著 arch 欄,十一輪一次都沒被讀過world/js/clay/clay.jsARCH寫死的六列(身高/胖瘦/頭身比/肩寬/ 腿長佔比)⇒ 44 人抽 6 型,946 對裡 150 對(15.86%)本來就同型。 | 子集 | 同型/總數 | 同型率 | 富集 | |---|---|---|---| | 全體 | 150/946 | 15.86% | 1.00× | | HARD(>SPEC) | 95/365 | 26.03% | 1.64× | | 救得起來 | 62/318 | 19.50% | 1.23× | | 劑量無效區 | 33/47 | 70.21% | 4.43× | ⇒ 第 54 輪那個硬核大半不是渲染或縮放的問題,是生成器只有六種身體。 六型在剪影上塌成兩群(站姿 351 對的 6×6 混淆矩陣,可混淆 ⇔ 該格 IoU 中位 > IOU_SPEC 0.5574):非對角 15 格有 5 格比「身高差 1.6 倍」還難分, 有效可分型數 = 2tall_thin+tall_broadmid+stout+short_round+child), 六個對角格 6/6 全部型內難分。最像的一對是 stout×short_round(0.6782)。 原因是解析的:相鄰型身高比只有 1.07–1.20,遠低於 1.6。 ⚠ 這個「2」只贏 0.0018——tall_thin×mid = 0.5557 對 0.5574,一格翻面就是 1。 ⚠ 而且 sit×sit 層別切出來的元件內容不同child | 其餘五型)⇒ 分群本身不穩, 只有「不是 6」是硬的。第二把尺(形狀剖面 pdist)與 IoU 的 Spearman −0.7786,同向。 反方向的好消息,而且它是先前沒被驗過的一個隱含前提:畫面像素高對世界身高的 R² = 0.9790、px/world 比值極差只有 1.18× ⇒ 畫面上的大小幾乎全是體型, 不是站的位置。若透視壓過體型,第 51–55 輪的逐對 IoU 全部要打折——它沒有。 這替規則七加上第五個選項:改 ARCH6×5 = 30 個數字。它比重做體型網格、 比加輪廓線都便宜,而且現在有數字支撐。但它是視覺風格方向 ⇒ 不拍板。 P 類失敗照規矩處理,門檻一個字沒放寬P3_label_h 的 CV 門檻 0.10 沒有分姿勢 (坐姿世界 bbox 高比站姿矮約兩成)⇒ 池化 CV 被姿勢撐大到 0.1407。這是探針設計錯, 不是資料問題:P3b_diagjudged=False不救門)顯示分層後 maxCV = 0.0682。 標籤本身另有兩條獨立證據——型間排序與解析序逐一相同、兩個獨立來源 (ss_solo.jsonsl_dump.json['heights'][k])的 key/arch/pose 44/44 相同。 探針自驗另有雙向已知答案:同一型切奇偶兩半必判可混淆(0.7273)、 remap 到 1.0 倍必判可混淆(恰 1.0000)、到 2.5 倍必判可分(0.2829),三條都命中。 預測 C51 錯了照報:預測有效可分型數恰為 1,實際 2(錯的方向對我不利)。 ⚠ **第 57 輪只做一件小事:把第 56 輪那個門修對,讓那批數字算數—— 而且證明主數字一格都沒動。** 零渲染(commit 1b8439a)。 第 56 輪 FAIL 的原因是我的門檻設計錯不是資料錯:CV 沒分姿勢,而坐姿的世界 bbox 高比站姿矮約兩成 ⇒ 池化 CV 被姿勢撐大到 0.1407。第 57 輪把 CV 改成 每個 (型,姿勢) 格分別算,分層 maxCV = 0.0682 ⇒ PASS,EXIT=0P3_cv 一個字沒放寬(仍是 0.10),變的是拿什麼去比它。 順帶補上兩條原本沒有的:每型至少要有一格判得到、stand 層的型間排序也要等於解析序。 這一輪真正的產物是那支比對器,不是那個 PASS。「只修門檻」與「順手把主數字 調成好看的」在人眼看終端輸出時長得一模一樣——兩邊都是一片 PASS。 styles/probe/ss_cmp57.py 讓這兩者分得開:新舊 ss_arch.jsonthresholdsprobe_okcases 三個 key 外,其餘 28 個 key 逐位元相同、 不准新增欄位、C51 的 FAIL 必須留著。7/7 全過。往後任何一次「只修探針不動結論」 都可以直接沿用。 兩把工具都用已知答案雙向驗過(規則三:探針本身要先驗): 比對器對 8 種擾動(動主數字 1e-12、偷加/偷刪欄位、放寬 P3_cv、把 C51 的 FAIL 改成 PASS…)各自只觸發該觸發的那一格,對唯一該放行的兩種放行; 門本身在 P3_cv=0.05P3_cv_n=5 兩種收緊下都 EXIT=1(跑完復原並 cmp)。 R2 撞出一個反直覺的東西,是實測到不是想到的:把「一格要幾個人才判」從 2 提到 5 時,maxCV 反而從 0.0682 降到 0.0488(人少的格被剔掉了)—— 若只有 CV 那一條,收緊人數門檻會讓門變鬆。擋下它的是「每型至少一格」那條。 ⇒ 用平均數/變異係數當門檻時,樣本數門檻與嚴格程度不同向照實記兩條對自己不利的:(a) 判準 A6 我自己寫錯了——寫「git diff 只准動 ss_arch.py 一個檔」,但 ss_arch.json 是被版控的產物必然跟著動,照字面讀 A6 FAIL (實質要驗的有過,且 json 的變動範圍由 A2–A4 逐鍵驗得更嚴)。 (b) 本輪沒有產生任何新的視覺知識,對展場畫面零直接貢獻; short_round/sitchild/sit 兩格因各只有 1 人沒被驗到(是「沒驗到」 不是「驗過合格」)。 ⚠ 第 58 輪把拖了四輪的那件事做完:五個選項終於在同一張桌子上vacant_hm/DECISION_SILHOUETTE.md,commit 1775931,零渲染)。 細節與那張同型佔比表在最下面「卡住/需要人類決定」段的 0-a 項底下。 這一輪最該留下的三條: 1. 給人類的頁面必須是產生的,不能是手打的。 68 條數字散在五份歸檔裡, 手打一次就會漂——而漂掉的那一頁看起來跟正確的一模一樣ss_opts.py 讓「頁面上的數字」與「歸檔裡的數字」在機制上不可能分家。 2. 「劑量越大越好」是假的,而且是實測反證不是推論HW4.0 273 < HW3.0 284; H 聯集 256 > H4.0 238,恰 18 對)。前四輪的表單看救起那一欄會讀成單調遞增。 3. 執行端把自己的錯誤預測寫進了給人類的那一頁。 三族同型率 (19.14 → 14.81 → 62.50 → 70.21)看起來像單調趨勢但中間那格反了; 只貼數字不說「這裡不單調」,讀者會自己補一條不存在的趨勢線。 照實記三條對自己不利的: (a) 判準 A3 照字面讀是 FAIL——寫「重跑兩次都 cmp 逐位元相同」, 但第一次 vs 第二次 ss_opts.json一個欄位P6c_predriftgot 從 「首次產生」變「與生成結果相同」,diff 只有 4 行)。那是手改偵測器依設計 會有的一次性暫態,run2 起逐位元穩定。判準沒有事後改,是我寫得不精確。 (b) P6b 那條自驗第一版是壞的,而且是它自己抓到的:原本用「claim 字串在不在 檔案裡」判分,而 33 這個值在頁面上出現兩次 ⇒ 改掉其中一個抓不到(實測 mutated=False)。改成逐位元後,68 條各改一位數全部會咬。 若沒寫那條自驗,這支會回報一片 PASS 而它的核心保證是空的。 (c) 零渲染、零新視覺知識,對展場畫面的直接貢獻是零——它解的是流程上的 堵塞(人類挑不了 ⇒ 後面全部卡住)。另:「H 族 = 被某個 H 格救起」這個等式 依賴 ss_hard.py 的迭代序,若有人改那個順序,這一族的語意會無聲地變掉, 而 P3 只驗總和與互斥性,擋不住這件事。 ⚠⚠ **第 59 輪先驗尺再花機時,結果擋下了一個會產出假空結果的實驗: 第 51–58 輪那把剪影尺,對「畫在剪影內部的線」是結構性失明的。** 零渲染(styles/probe/ss_luma.py,commit cd324a1,探針自驗九條全過、 重跑逐位元一致、四份既有歸檔重跑後逐位元不動)。 第 58 輪排的下一步是「渲染加輪廓線/硬影 vs 不加,量同一把 pdistIoU」。 照那樣做必然量到 0,而那個 0 會被讀成「輪廓線沒有用」: diff_mask二值遮罩,畫在剪影內部的線(肩線、手臂壓在軀幹上那條、 硬影的邊)其像素本來就已經在遮罩裡 ⇒ 在建構上不可能改變遮罩, 而 pdistIoU 只吃遮罩。那個 0 不是「沒有效果」,是「這把尺看不到」。 釘死的方式是雙向已知答案(規則三:探針本身要先驗):把最大對比內緣環 (對背景的 |Δluma| ≥ 127 ⇒ 一條人眼一定看得見的白/黑線)畫進 44 個剪影, 全圖重算遮罩,不抄捷徑—— | | 一定看得見的那條線 | |---|---| | 尺 A(pdist/遮罩) | 44/44 逐元素相同、max\|Δpdist\| = 0.0 ← 看不見 | | 尺 B(ldist_flat) | 44/44 都 > 0.02,中位 0.1645 ← 看得見 | 尺 B 與尺 A 共用同一組 bin_spans、同一條 Σ|Δ|/8,只把被量的量從 「這一列填了幾格」換成「這一列多亮」;ldist_raw 含黏土本色、 ldist_flat 先減掉該人自己的平均 ⇒ 色盤與明暗被一個減法切開。 | 組別 | n | pdist(剪影) | ldist_raw(含色) | ldist_flat(明暗) | |---|---|---|---|---| | 全部 | 946 | 0.1469 | 0.0848 | 0.0702 | | 硬核(劑量無效) | 47 | 0.0966 | 0.0713 | 0.0597 | | 救得起來 | 318 | 0.1134 | 0.0822 | 0.0669 | 兩條會改變下一步的結論: 1. 明暗是一條尺 A 丟掉的、獨立的通道——pdist × ldist_flat 的 Spearman 只有 0.383(這條押在對自己不利的方向:相關性高就等於本輪白做)。 2. 硬核那 47 對在明暗上沒有跟著剪影一起塌掉(比值 0.89,剪影那邊是 0.85) ⇒ 對展場而言硬核不是「同一個模型換顏色」的死路, 「改 ARCH/重做體型網格」不是唯一出路。 順帶兩條硬接縫,讓尺 B 的數字不是自說自話:本支自寫的陣列版差分對 stagevis.diff_mask 逐元素相同 44/44;三組 pdist 中位與 ss_prof.json 逐位元相同(0.1469/0.0966/0.1134)——兩條獨立路徑量到同一個數。 誠實邊界,全部寫在對自己不利的方向: (a) 本輪沒有渲染任何輪廓線——T_inT_out 是在 luma 陣列上合成的環, 證明的是尺的能力不是輪廓線的效果;真的輪廓線還會畫在部件交界上, 合成環畫不出來 ⇒ 對尺 B 而言它是下界。 (b) 尺 B 一樣對左右翻轉失明,數字也是下界。 (c) ldist_raw 把顏色算進來了,而 raw × flat 的 Spearman 高達 0.809 ⇒ 這兩個版本彼此不獨立,別當兩份證據。 (d) 本支不回答「觀眾分不分得出來」,只回答「哪一把尺帶得動這個資訊」; 0.0597 沒有對應到任何人眼判準,把它當展場門檻是空過。 (e) 判準 P5_analytic 的比較方式被執行端改過:原寫「必須恰為 50/255」, 實測尺自己那條算法與 50/255 差 1 ulp,逐位元相等測的是 IEEE 捨入次序不是尺 ⇒ 放寬成 <= 1e-15改是在主數字算出來之前做的,逐位元結果(False) 印在探針輸出裡沒有藏——但它仍然是一次判準被改。 (f) 四條預測 C70–C73 全中,這是本輪最該打折扣的地方:全對通常表示押得太鬆。 (g) DECISION_SILHOUETTE.md 沒有更新(本輪判準要求零既有檔修改), 所以人類那一頁上還沒有這條「尺會失明」的警告。   → 第 60 輪補上了,見下一段。 (h) 「渲染輪廓線/硬影對照」連續五輪未做——本輪是刻意不做並給了量到的理由, 不是又一次被環境擋住,但它仍然沒有做。 ⚠ 第 60 輪:那把失明的尺現在寫在人類拍板的那一頁上了。vacant_hm/DECISION_SILHOUETTE.md,commit 166d643975f950,零渲染、零新量測。) 第 59 輪的發現還沒有到人類手上——而那一頁當時同時做著兩件互相矛盾的事: • 它用尺 A 的剖面告訴人類「若要用輪廓線/硬影強化,該打在肩線與腳踝」; • 它沒有說尺 A 在建構上量不出那條線的效果。 後果是可預期的:人類照那一頁挑了選項 4 ⇒ 執行端去渲染 ⇒ 用同一把尺量 ⇒ 得到 0 ⇒ 把「這把尺看不見」讀成「輪廓線沒有用」⇒ 擋掉一個真的槓桿。 第 60 輪只做這件事:把已經量到的接上去,一個新數字都沒量。 那一頁人類看得到的差別: 1. 選項 4 多一個引言方塊,明寫尺 A 為何必然回報 0(44/44 遮罩逐元素零變化、 max|Δpdist| = 0.0),以及一句 「請不要把選項 4 未來的量測結果 0 讀成它失敗」。 2. 同一方塊給出替代的尺與它量到的:ldist_flat 對同一條線 44/44 都看得見 (中位 0.1645、最小 0.0899),與尺 A 的 Spearman 只有 0.3828。 3. 新一節「這一頁的數字是用哪把尺量的」:兩把尺各看得見/看不見什麼, 並逐一寫出對五個選項的後果——選項 1/2/3 不受影響、選項 4 要換尺、 選項 5 的「前面所有量測要重跑」現在還要加上尺 B 那些。 4. 「沒回答什麼」從 5 條加到 8 條。最重要的第 6 條:**ldist_flat 沒有對應到 任何人眼判準**——沒有人看過任何一張圖然後說「這個值以上就分得出來」, 把它當展場門檻是空過。第 8 條寫明輪廓線是否屬於選定方向本頁不知道(規則七)。 「往那一頁加話」與「順手改了一個主數字」在人眼看 diff 時長得幾乎一樣, 而那一頁有 68 個內嵌數字 ⇒ 新造凍結比對器 styles/probe/ss_cmp60.py 護著: 除四個自驗欄位外的 top-level key 逐位元相同、舊門檻 0 刪 0 改值、舊 case 四欄 不准漂、page_claims 的舊 key 一個都不准改值或消失(新增的 26 條逐一列出, 不是「有一些」)。實測 7/7、0 改值 0 消失、68 → 94 條這把尺自己先驗過(規則三,雙向已知答案):改一個 top-level 值、改一條 claim 一位數、刪一條 claim、把 C62 從 FAIL 翻成 PASS——四個都必須被咬到;原樣與 「只新增一條 claim」兩個必須放行。六個全對才准拿去比主結果。 誠實邊界: (a) 本輪一個新數字都沒量,頁面上的明暗數字全是第 59 輪的搬運; 搬運由新增的 P8_luma_seam 接縫檢查護著,但它們的效力不會因為被印在頁面上而變高。 (b) 把一個沒有人眼門檻的數字(ldist_flat)放進人類的決策頁,本身就是誤讀風險 ——即使加了第 6 點警告。這是本輪最該被質疑的一步。 (c) 試跑過一次才 commitP0_untouched 要求 styles/probe/ 的 git diff 是空的, 而本輪改的正是那支產生器 ⇒ 順序是「試跑 → 還原輸出 → commit 產生器 → 乾淨跑」。 試跑那次 EXIT=1(P0 FAIL)是預期的,其餘 15 格與正式跑逐字相同。 放寬 P0 本來是更省事的做法,沒有做。 (d) ss_cmp60.py 是第二把凍結比對器(第一把 ss_cmp57.py 寫死給 ss_arch.json, 餵 ss_opts.json 會 KeyError)。兩支沒有共用決策函式,理由寫在 docstring 裡 ——這是講明白的分開,但確實是第二份要維護的東西,第三支出現時就該抽共用層。 (e) 預測四條錯一條:claim 條數押 75–85,實際 94;而且我把基準記成 63(實際 68), 是目測數頁面而沒去讀 page_claims 的長度。**判準「> 63」照樣過,但它過得太鬆是因為 我把基準記錯了,不是因為我押得準。** (f) SPEC_CLAY.md 本輪沒有重讀——頁面第 8 條「輪廓線沒有明文」是沿用第 59 輪的紀錄。 (g) 「渲染輪廓線/硬影對照」連續六輪未做。這輪同樣沒做,理由是規則七。 ⚠ 第 61 輪:選項 3 從「挑一族」補到「挑一格」——那一頁自己承認算不出來的那一欄。vacant_hm/DECISION_SILHOUETTE.md,commit d3ceed32404e8a,零渲染、零新量測。) 第 58–60 輪那一頁給的同型率是軸族的三個數,但選項 3 的實際動作是挑一格。 族 H 的 256 對是 6 個 H 格的聯集,H 軸最好的單格(H4.0)只救得起 238/256人類看到的 19.14%,不是他實際要挑的那一格的數字。 而「救起一對同型的」 意思是把同一種身體拉成兩個尺寸——那不是兩個人,是一個人的大小號。 ss_hard.py 每格多存 rescued_pairs,同型的計算走 ss_opts.py 那個 已被雙向已知答案驗過same_arch()(不另寫第二個計數器)。15 格全在表上: | | 1.5 | 2.0 | 2.5 | 3.0 | 4.0 | |---|---|---|---|---|---| | H 同型率 | 20.21% | 15.65% | 17.73% | 16.67% | 18.07% | | W 同型率 | 5.06% | 6.38% | 9.52% | 11.76% | 14.10% | | HW 同型率 | 15.03% | 12.90% | 13.79% | 15.85% | 16.48% | ⚠ 執行端跑之前寫死的三條機制解釋,實測打掉兩條(已寫進那一頁): 「單格相對於族會被稀釋」H2.0 15.65% <族 19.14%); 「劑量越大越咬得動同型對」H4.0 18.07% < H1.5 20.21%); 「同型率最高的一格在雙軸」(最高的是 H1.5,18 格沒一格是 HW)。 表上最清楚的那件事三條都沒押到W 軸整條被同型對掏空(5.06–14.10%), 明顯低於 H 與 HW——與第 58 輪 C62 FAIL 同向,兩輪用不同切法問同一題, 都指向「W 救起來的東西特別乾淨」。⇒ 那一頁加了 「請不要把上面那些『為什麼』當成可以外推的機制」。 這一輪最值得記的不是那張表,是判準先寫害我自己 FAIL 的那一格A4(重跑逐位元相同)第一次沒過——新加的凍結檢查 P5_frozen 把 「相對上一版新增了 36 個欄位」寫進了 ss_hard.json,而它的基準是 git HEAD ⇒ commit 之後同一份程式對同一批圖跑出「新增 0 個」,**歸檔不再是 (圖 + 程式) 的純函數**,還連鎖絆倒 ss_opts.pyP0_untouched。 修法是把凍結類移出歸檔(照樣判分、照樣擋 EXIT,不進 cases)—— 「這一版相對上一版動了什麼」是轉變的性質,不是量測的性質。A4 放寬成「除了那行 note 以外相同」更省事,沒有做。 同一輪還抓到 probe_ok 那行原本是靠運氣對的(if c['judged'] 之所以沒把 從第 54 輪起就 FAIL 的 C30 算進去,只是因為當時 CASES 裡碰巧只有 P 類)。 誠實邊界:(a) 本輪一個新的量測都沒有——18 格 sweep 是重跑既有的, 11 個主數字對 HEAD 逐位元相同;(b) 同型率仍然只回答「資訊在不在畫面上」, 不回答「觀眾在展場距離下分不分得出來」(那一格連續第十輪為零); (c) 畫面上一個像素都沒動,連續第七輪沒碰 render 層,理由仍是規則七; (d) 各格數字不可以相加(同一對可被多格救起),「兩格併用」表上讀不出來 ——已寫進那一頁的「沒回答什麼」第 4 條; (e) 共用層 frozen_diff 寫出來了,但 ss_cmp57ss_cmp60 沒有回頭遷移, 兩支舊的仍各自實作 ⇒ 債還在,只是不再增加。 ⚠ 第 50 輪去指認「擋人的是誰」,答案是擋人的不是人——是在途交付物。 第 49 輪把 f1r9 那個 3 px 的人歸給「同層前排的另一個居民」。這一輪照判準 逐像素歸因,結果是 0/139:139 個被吃掉的本體像素,一個都歸不到任何其他 居民身上(到任何別人 solo 像素的曼哈頓距離 13–29 px)。 零是很特別的數字 ⇒ 先懷疑工具,而工具沒壞,壞的是前提。兩批圖的 query 參數本來就不同(第 44 輪兩支 shoot script 各寫各的,沒有人比對過): ` so_ (ss_occl.sh) hide=shell,furn couriersOn=True reviewOn=True sl_ (ss_solo.sh) freeze=20&couriers=0&review=0&… couriersOn=False reviewOn=False ` ⇒ 兩件事,都照報: 1. 第 44 輪那個「人擋人份額 = bbH_solo − bbH_noarch」不是純的人擋人, 裡面混了 13 個在途交付物與 review 模式。這是對一個已落盤數字的更正。 2. 讓居民在展場距離下看不見的,是在途交付物。 建築第 44 輪已否決、 別的居民第 50 輪否決。f1r9 獨自 14 px、有交付物時 3 px; 站在他前面的是 CR15/CR23,不是人。 零渲染釘死的方式(ss_cour.py):交付物世界座標取自第 44 輪就落盤的 so_dump.json,相機用 ss_proj.Cam 本人(重算 three.js 自己投影的 89 點 uv 誤差 5.0e-5;反向把 fov 灌成 68° 立刻壞掉 0.299)。交付物寬度取 0, 投影成線段不是框——讓相交變難的方向,對自己的假設保守。 跑之前寫死的正負兩組:lost>0 的 5 人 5/5 前面有交付物、lost=0 的 39 人 1/39。第三把尺交叉檢查:7 條命中全部 dz>0(交付物離相機更近)。 ⚠ 這組數字依本輪自己寫死的規矩「照報但不算數」:探針的 Q2 沒過—— 我假設 13 個交付物在同一條輸送帶上(同 z),實際有 2.55/2.359/0.969 三種。 錯的是我對資料的假設,不是量具(Q0/Q1 都過);判準不事後放寬, 而且正因為 Q2 失敗才補上了那條深度交叉檢查。 ⇒ 新的規則七項目:**交付物的軌道深度/尺寸現在確定是「居民看不看得見」的 主要槓桿。** 要不要為了讓居民看得見而動交付物,是視覺方向的決定,等人類。 ⚠ **第 49 輪先驗第 48 輪下一步的前提,前提不成立:那些「切口」大部分不是遮擋, 是量到了居民自己的影子。** 第 48 輪的下一步 (b) 預設「切口下面那塊碎片是本體被 擋掉之後剩的一段」。用第 43/44 輪已落盤的三批圖(ss_ 完整世界/so_ hide=shell,furnsl_ 獨自一人)交叉判——sl_ 那批沒有任何東西接得住影子, 所以它的 mask = 純本體剪影,碎片落在它外面就不是本體。零渲染、一張都沒重截: ` 連通塊 >1 的人數 ss_ 21/44 so_ 1/44 sl_ 0/44 mask 像素中位數 ss_ 123.5 so_ 83.5 sl_ 85.5 ← 完整世界多 45% 最大塊落在本體框內 中位 0.853、最小 0.588、26/44 低於 0.9 34 塊非最大碎片 判成本體 9、判成不是本體 25 `「21/44 的 mask 被切成多塊」這句話,主詞不是人。 差分是「這個人在/不在」, 所以他投在建築上的影子整片都算進他的 mask;bbH 量的是「本體 ∪ 沾在身上的影子」 的最大連通塊,不是人的剪影。第 43 輪起 N4 就是量在這個混合物上的。 跑之前寫死的兩條預測,一條成立一條被自己的資料打掉(方向相反,所以 「永遠說在外面」的壞判別器不可能兩條都過;判別器也確實對 9 塊碎片說了「是本體」): • C5 成立 6/6:第 3 層那六個切口下面的碎片(全部在畫面第 145 列、高 1 px、 面積 4–9)在本體框外面 ⇒ 不是本體。那六個切口的世界 y 在第 48 輪逐字元相同 (11.2425–11.615)也就有解釋了:它是影子的邊,不是人的邊。 • C6 錯了 0/7:我預測欄空隙(左右分家)是真的遮擋(≥4/7 是本體), 量到 0/7。左右分家的碎片同樣不是本體。 ⇒ 對 N4_min 的後果(壞消息與好消息各一,都照報):f1r9 那個 3 px 的人, 獨自站在空畫面裡是 14 px,而 hide=shell,furn(其他人還在)仍然是 3 px ⇒ 他被擋住的部分是人擋人,不是建築。三批的 bbH 最小值 ss 3/so 3/sl 9。 ⇒ CELL_Z 往前挪(第 48 輪的選項 b)救不到他——擋他的是同層前排的另一個居民, 站位整排一起往前移,相對關係不變。選項 (b) 這一輪起降級,不是被否決,是**沒有 證據支持**;要動就得先量「人擋人」那一份。 > 第 50 輪更正(原文保留,留著讓人看見錯的形狀):上面那句「擋他的是同層 > 前排的另一個居民不成立。逐像素歸因 0/139,擋他的是在途交付物 > CR15/CR23。結論「(b) 救不到他」不變,理由換了——交付物不在站位表上, > 移站位一樣救不到。 ⚠ 第 44 輪把「為什麼太小」量出來了,而答案推翻第 43 輪的推論: 第 43 輪說最小的那幾個是「被建築擋住」。正面量之後——藏掉整組牆/樓板/ 桌凳,中位數 13.5 → 13.0(增幅中位 0.0 px);再讓每個人**獨自站在 空畫面裡,中位數 13.5 px、最小 3 → 9 px。⇒ 遮擋解釋的是極端值, 不是中位數。 最小的 k17 從 3 px 變 14 px,但那 +11 全部來自人擋人** (建築 +0);一半的居民一格都沒動。**連獨自站在空畫面裡都只有 13.5 px <門檻 15是尺度/鏡位的問題,不是遮擋的問題**。 能動中位數的只有尺度(SCENE_SCALE/相機距離/改成局部視角), 而改樓層開口或鏡位角度救不了中位數——這句話現在是量到的,不是猜的。 順帶更正第 43 輪另一句:N3 第 0 層那個偏低的 0.516 不是剪影不分明, 沒有東西擋的時候同一層是 0.984(四層 0.984/0.996/0.991/0.984)。 ⚠ 第 45 輪用第二把獨立的尺確認了 13.5 px,並推翻第 44 輪寫下的那句取捨: 到第 44 輪為止,所有數字都出自同一條管線(截圖相減 → 連通塊 → bbox 高), 九條探針驗的全是那條管線內部的一致性,共模偏差抓不到。第 45 輪加了 styles/probe/ss_proj.py——不經過像素差,由相機參數與每個人的世界高度 直接算他該有多高。量具自己先驗過五條:對 three.js 自己的投影矩陣 89 個 world→uv 點,max|Δuv| = 5.0e-5(640 寬下 0.03 px);反向已知答案(fov 灌成 68°)必須失敗,實得 0.30;假設的 wide 機位對畫出來的建築四邊 0.2/0.8/ 0.8/0.0 px。主結果是零自由度的(geom.js:501 把居民的 z 寫死成 CELL_Z=0.75,不必反解):逐人比腳、頭、畫面高,44/44 全部在 ±2 px, 中位 −0.14/−0.37/+0.23,最大 1.36 px ⇒ **13.5 px 是相機的必然結果, 不是量具的產物。** 而第 44 輪那句「放大 1.11 倍會犧牲一次看到四層樓 44 個人」是錯的: 畫出來的世界只佔 640×360 的第 62–577 欄、109–239 列,左右各留 258 px 空白。 在建築完全不出框的前提下還能放大 1.240 倍(fov 34°→27.7°),而達到門檻 只需要 1.111 倍(fov→30.8°,那時最小的人 10.0 px > N4_min=8)。 ⇒ 餘裕來自畫面四周的空白,不是來自全景;不必取捨。(要不要改仍是規則七。) 照報一條 FAIL:預註冊的「反解出的 z 要落在建築裡」41/44——第 2 層的腳只在 眼高之下 0.65,幾乎壓在地平線上,|dz/px| 中位 14.9(其他層 1.1/2.0/2.8) ⇒ 那是反解方法的病態,不是相機模型錯(同一台相機零自由度下 44/44 全過)。 | 項目 | 到哪了 | |---|---| | 風格方向 | ✅ 2026-08-15 人類選定「黏土定格」,不再是待決事項 | | 12fps 步進定格 | ✅ 姿態 12fps、畫面 60fps,是真實時間的純函數 | | 硬邊陰影/單一主光 | ✅ 低角度側射,光進得了每一層 | | 指紋壓痕法線 | ✅ 程序生成,零外部請求 | | 格狀布局(一格一人) | ✅ 4 層 × 13 房、空格不放裝飾(空格=曾經有人) | | 人形剪影差異(量測台) | ✅ 六種體型 archetype,剪影高度差 2.51 倍(舊版 1.17 倍) | | 人形剪影差異(真的畫面上) | ⚠ 第 43 輪第一次真的判定了,而唯一沒過的是「太小」。 2.51 是在 silhouette.html 量測台量的——正交排開、scale=1.0、互不遮擋、3840px 寬,那是前提(「模型有能力長出不同剪影」)。觀眾看到的是 clay.html 全景:縮到 0.66、四層樓、有透視、彼此遮擋、整張圖 640px。逐一居民 hide=fig<k> 對 baseline 做像素差(44 人 × 一張圖)。判定結果:N1 可見 44/44 ✓、N2 同層比值 2.222/6.667/3.167/2.000(4/4 層 ≥1.6)✓、N3 同層 Spearman(世界身高, 畫面高) 0.516/0.689/0.737/0.993(3/4 層 ≥0.6)✓、N4 尺寸 ✗(畫面 bbox 高中位數 13.5 < 門檻 15、最小 3 < 門檻 8、26/44 不到 15 px)。剪影差異本身在展場距離下活下來了;撐不住的是絕對尺寸與遮擋(21/44 的 mask 被切成多塊)。⚠ 第 1 層那個 6.667 是假的好看——分母是 k17(f1r9,世界身高 1.809 = 偏高的人)在畫面上的 3 px,一個被擋住的人不是一個矮的人 ⇒ 遮擋在同一個數字裡同時灌大比值、壓垮尺寸。⚠ 判得成是因為先修了量具,而修的人已看過數字:第 41 輪寫的探針門檻有兩條本來就不可能過(P1 要 hide=world 差異 ≥100000 px,但整張圖「不等於背景色」的像素只有 63949;P3_det_sha 要整張圖逐位元組相同,但 HUD 裡有活的 fps 計數器 ⇒ 依設計不可能),所以第 42 輪 N1–N4 一條都沒判。第 43 輪換成不含任何挑選常數的結構性判準(∪(每人 mask) ⊆ mask(藏全世界)差異列 ⊆ HUD 列),八條探針全過。非盲,但方向對自己不利:重寫的唯一後果是把「都不判」變成「N4 正式沒過」;圖利的改法長相相反(放寬 N4 或讓探針繼續卡住)⇒ N1–N3 的過只當記錄,N4 的沒過照收。回歸:N1–N4 的數字與第 42 輪照報的逐字相同 ⇒ 改門檻沒漏進主量測。⚠ 「太小」正是動手前就寫在擔心清單上的那件事,所以另跑 ss_dlsens.py 把 ΔLuma 門檻從 8 降到 1 重量:一般居民(k=0/5/12/40)一格不動,最小的三個只長 +1~+2 px不是量具削的,那三個是真的被建築擋住。旁證量具沒歸錯人:P4 可加性對稱差 0.0、P5 樓層中位數 234/203/172/141 間距 31/31/31 完全分離 | | 剪影量測台(量具) | ✅ world/silhouette.html + 已知答案校準塊,探針正反都驗過 | | 坐姿/站姿 | ⚠ 站坐分得出來(寬高比 1.34×),但短腿體型的高度比 0.819 未達 0.80 | | 量具(可稽核性) | ✅ 每一組數字之前都先過自己的自驗,而且兩個方向都有已知答案第 24 輪學到最貴的一條:驗量具的東西不可以跟量具同源——凸包 hull 與拿來驗它的 shell 是同一支函數生的,於是變異「只回上表面四角(=根本沒修)」讓 J1–J8 十五題、Q1(a)、Q1(b)、Q2、Q4 全部通過:兩個壞掉的東西一起退化就一起自洽,而那個自洽的結論剛好是我那一輪想要的「修好了」。補上「底面必須真的貢獻 4 個相異點」才擋得住,而且它是唯一擋得住的一條。同一個變異的另一趟還打出第二個洞:某趟 dump 拿到 0 張紙,於是每一條逐張計數都是 0、ok 變成 True——量一個空集合永遠會過,⇒ 張數本身要當判準,而且變異台的場景時刻要跟正式量測釘同一個 freeze。兩個洞都不是想出來的,是變異台打出來的)(第 23 輪把這條推到量具的結論方向上:溯源那組八個變異裡有兩個是專門朝「我這一輪想得到的結論」作弊的——「不讀 1920」會讓溯源退化成被明令禁止的路線、「分群改成 8-連通」會把碎片併成整塊而正好讀成漏掉的幾何;兩個都被擋下,結論才算數。另一條:合成自驗的縮圖走真正在跑的那段平均碼,變異成自己寫的四捨五入版就會讓手算的 211 變 212 而沒過)(第 18 輪新增:min-channel 中位數探針,六題含中位數本身的兩個方向——只驗「多數是白 →255」的話,一個永遠回最大值的壞中位數會通過):位子分配器(視窗版 vs 整段暴力排序,n≤836 不一致 0;rank 是不是排列:重複 0/跳號 0;第 9 輪換了排序鍵之後重跑,仍然 0)/draw call 四校準/位移取樣器(靜止 0、已知 2.0)/像素差(同圖 0、塗 24×18=432)/剪影台(1.60、1.00)/review 計數器(已知為空 =0、視窗 vs 暴力列舉 601 點不一致 0)/強紅像素(純白 0、已知紅 600、差 1 個單位的近似色 0、房間最紅的真實像素 0)/判決交叉驗證(801 件走 sim-bridge 真狀態機,最終狀態不一致 0)/連續性探針(?haul=0?seats=0?file=0 =已知有瞬移那一邊必須抓到,量到 42 次/8.40 單位、1202 次/3.83 單位、246 次/11.44 單位)。第 8 輪多學到一條:像素判準的取樣矩形也要有靠山——它由常數+相機投影算出來,而且先量一次改動前的基線;第一版矩形算錯(拿到全景相機)時,正是「改動前後都量到 0」才看得出是矩形錯了,不是實作壞了 | | 效能(與硬體無關的部分) | ✅ draw call 1038 → 246;加了送件人、評審、桌上文件、判決層與兩段搬運之後 376–389(預算 445)、三角形 161352、GPU 貼圖 2 | | 效能(fps) | ⚠ 在這台量不到(無硬體 GL),只能等有 GPU 的機器 | | draw call 量具 | ✅ world/drawcalls.html 五個已知答案的整數場景,含「已知看不見」那一邊 | | 走廊/樓梯/中央評審室 | ✅ 樓板加深成走廊、左右兩座 zigzag 樓梯、fl=1 三格打通成評審室 | | 交付狀態機 · carrying | ✅ 送件人抱著紙疊從格子走進評審室。在途 15.5 件、時長全部落在 PHASES.carrying、幾何違規 0、瞬移 0 | | 交付狀態機 · review | ✅ 桌上的文件疊多高就是當下在評審的件數(平均 10.7 件,與 λ×時長 自洽到 0.03%);三位評審拿放大鏡/印章/紅筆,桌上沒東西時動作幅度為 0 | | 交付狀態機 · audit | ✅ 被抽查的文件離開大桌、出現在稽核台上,稽核者的動作綁在檯面件數上(空的時候幅度 0)。平均同時 1.28 件、時長全部落在 PHASES.audit | | audit 的「抽走」(過程) | ✅ 紙從它在大桌上的那個位子被抬起、沿桌前空道滑到它接下來要坐的那個位子,端點誤差 0、瞬移 0(對照組 ?haul=0 同一支探針抓到 42 次、最大 8.40 單位)。速度 6.2 u/s < 場上最快的送件人 10.04。⚠ 沒有畫人走過去拿(同時最多 3 份在搬,一個人分身乏術),紙是自己滑的 | | 交付狀態機 · 判決與結局 | ✅ accepted 蓋章進歸檔架/rejected 紅標攤在退回台/caught 紅標留在稽核台。判決是 sim-bridge.jsreviewOutcomeshouldAudit 算的,clay 這邊一行規則都沒有;801 件與該檔真正的 advance() 狀態機逐件比對,不一致 0 | | 結局的「過程」 | ✅ accepted→歸檔架rejected→退回台 也走過去了:紙從它在大桌/稽核台上的那個位子被抬起,沿桌後空道橫移、升到櫃頂之上、越過櫃體、從正面水平滑進格位(這條路是算出來的——從上面降會穿過每一層層板、從後面滑會穿進櫃體)。端點誤差 0、瞬移 0(對照組 ?file=0 同一支探針抓到 246 次、最大 11.44 單位)。速度 3.0–9.3 u/s ⊂ 送件人實測帶。還沒畫的:rejected 的「退回原本的格子」回程、caught 的「紀錄卡被劃記」(紀錄卡牆不存在)。⚠ 一樣沒有畫人走過去拿 | | 架上的停留時間有沒有被搬運吃掉 | ✅ 沒有。做法是延長 gone(= file1 + SHOW)而不是從 SHOW 裡切一段:切下去等於拿「架上看得到文件」去換「看得到文件被送過去」。代價是容量,解法是位子落地才佔(rank 的排序鍵從判決時刻換成落地時刻,FIFO 論證原封不動)⇒ 架上佔用峰值沒漲(15/24、5/8),平均仍是 rate×SHOW | | 紙在檯面上會不會「跳」 | ✅ 歸檔架與退回台的位子一旦分配就不再變(純函數版分配器:到達序 mod 位子數)。整段展示期間的最大位移 0(對照組 ?seats=0 =舊行為,同一支探針抓到 1527 次、最大 2.62 單位)。碰撞 0,而且不只是論證:同一檯面上展示時長相同 ⇒ 離場序=到達序 ⇒ 在檯上的那幾件 rank 連續 ⇒ mod 位子數不會撞,判準另外直接數過。⚠ 稽核台仍然會遞補(它不是 FIFO,那個證明對它不成立),第 7 輪已改 1 欄 ⇒ 只掉 0.085 | | 歸檔架的形狀 | ✅ 加了 7 片層板變成真的架子。位子固定的代價:底下幾層會空著,沒有板子那一疊會浮在空中(舊版是靠下面那張紙撐的)。層板進靜物那一桶合併 ⇒ draw call 一個都沒多。可見度量過:歸檔架矩形內 1720 px = 改動前的 86%(門檻 70%) | | 歸檔架讀到的是什麼 | ⚠ 讀到「架子」不是「累積」。舊版是桌上一疊愈疊愈厚的白色,一眼就是累積;新版是架上某幾層有文件。這是固定位子的結構後果,不是參數問題。判準只問了「看不看得見」,沒問「讀到的是不是同一件事」——⇒ 下一步要人類看圖決定。第 31 輪查到它有一個算得出來的物理原因:層高 ARCHIVE_LEVEL_H = 0.155,扣掉層板 0.04 與紙 0.08,紙上面只剩 0.035 的縫 ⇒ 這個俯角看進去,每張紙只露出最前面一小條,看得到的紙面平均只有 45.7%(頭上沒有板子的最上層是 99.2%)。⇒ 「讀成架子不是累積」與「展場距離讀不出紙」是同一個原因,而且不是參數問題也不是燈的問題,是層高。改層高是視覺決定(整座櫃子會長高,而 geom.js:341 記著空道往下的下界是硬的)⇒ 仍然等人類 | | 髮色(色盤) | ✅ 修好了。舊版在打包成整數的 RGB 上做加法0x2E2420 + floor(rand*0x201810))⇒ G/B 各自跑滿 0–255:窮舉 200000 點,99.4% 落在棕色值域外,畫面上就是滿頭綠髮。改成單調斜坡(同一個 u 讓三通道一起走)⇒ R46–78 G36–60 B32–48、R>G>B 恆成立、相異髮色仍有 34 種。⚠ 三通道各自獨立抽會長出橄欖綠(R<G),所以那不是「加三次」就好 | | 色盤有沒有人在問(量具) | ⚠ 人形問了,靜物還沒。前九輪每張近景截圖裡都有綠頭而所有判準都過,因為沒有任何一條判準在問顏色。現在三層都有量具、每層都有「已知會壞」的對照世界(?hairbug=1 保留舊公式):算式(新 0/舊 198878 出界)、頂點色(80 個人形 476 個 mesh 的 buffer,違規唯一色 0;對照世界 52 種)、像素(強綠 0;對照世界 12440、6 塊)。沒掃到的:房間/家具/道具/紙那些不走 vertex color 的材質 | | 紅色只有一個意思(SPEC §四) | ✅ 用第 6 輪結束時就凍結的修正定義(R≥170 且 min(R−G,R−B)≥105)重量:沒有紅標的時刻 0 px(舊定義 1281)、有 2 個紅標時 105 px。連紙帶道具全關的世界也是 0 ⇒ 舊定義量到的本來就是房間的暖色調不是退件紅。探針多一個已知答案:房間最紅的像素 (187,105,77) 必須算成 0 | | 在路上的紙讀不讀得成一條線 | ✅ 不再是線。原因量出來了:歸檔那條路在單一高度上的兩段佔全長 53%(近)到 81%(遠)⇒ 任何時刻一半以上的紙恰好等高(第 10 輪十張裡九張 y=5.950)。改成 ARCHIVE_OVER_Y + 1.00·frac(n·φ) 一疊錯開的空道——用 φ 不用亂數,因為要的是「同時在路上的那十幾件彼此散開」,而雜湊會成群。最大同高群 13 → 3(投影像素上 8 → 2)。⚠ 不能改成斜著飛上去:那條斜線整段掃過評審的頭 | | 在路上的紙還讀不讀得出是紙 | ⚠ 目視第一次成立了,但事先訂的三條數值判準仍然沒過 ⇒ 預設維持關,等人類看圖定奪。第 12 輪的做法瞄錯了對象:它讓紙轉 15° 對準相機,把 N·V 湊到 cos15° 就停手,完全沒有問 N·L(亮度)——所以轉回來的是沒被照亮的那一面(亮面像素最好的一張只有 489,門檻 2500)。第 15 輪改瞄 主光與相機的半向量 θ*=(φ_L+φ_V)/2,也就是讓 (N·L)(N·V) 取最大:純幾何,不加燈、不加自發光、不動空道,所以沒有擦到「只有一盞主光」那條人類定的方向。量到的:前縮因子 0.238→0.470–0.992、投影四角 5300→10012–26129 px、亮面像素 0–489→323–17373 px、640px 空道帶 2601→7049。逐張角度與動手前寫進 STATE.md 的預測表相符到 0.05°。目視(tl_on_640.png vs fl_on_640.png:平放是一排細碎白屑,傾斜是明確的矩形白紙浮在空中——「那是紙」在展場距離第一次成立。但 B3/B4/B6 仍然沒過(0.019/323/0.019),沒過的原因換了:不再是「整批太暗」,而是亮度張張不同(最好的 0.810 已貼到天花板 0.83,最差的 0.019)。角度那一半解決了,剩下的全是陰影分佈。第 16 輪把「吃不吃得到主光」從手算的點判定換成對上表面 7×7 取樣、朝主光射線去問場景裡真的會投影的那 388 個 mesh(=陰影貼圖用的同一組),同一組紙同一組像素只換預測器 ⇒ Pearson r 0.636 → 0.887、殘差中位數 0.049。第二個遮擋物因此被指認出來了,而且不是猜的:撞擊點座標分成兩群,y=7.53 那群是樓板,y≈5.9–6.8 那群是在路上的紙自己互相遮(71.57° 的紙近乎直立=一面 0.9 單位高的擋板)與站著的稽核者的頭。手列遮擋物清單永遠列不到這一項。第 17 輪把同一組取樣點朝相機再射一次(「那張紙在相機這一側被誰擋住」,背景控制圖扣不掉的第二個機制):遮擋確實存在(最差那張 34/49 看得到),但它解釋不了殘差——最差那張的預測 0.510→0.510 一動也沒動,因為被相機擋住的取樣點恰好就是本來就在影子裡的那些(同一張紙同時擋光也擋視線)。⇒ 第 16 輪對殘差來源的診斷被自己的判準否掉了。第 18 輪換下一個假設(受光但偏暗:分類器要 min-ch ≥200,「照得到」≠「畫出來夠白」),同樣被自己事先寫死的裁決規則否掉(成立 ⟺ N1 且 N2;N2 沒過)。但這一輪量出了殘差真正的來源,而且是可查證的數字:把同一組 49 個取樣點投影到畫面上讀真實 min-channel 之後發現,殘差最大那張紙 25 個「預測白」取樣點的值全部恰好 196(門檻 200,IQR 0)——整片受光白區以差 4 個階被整片拒收,它自己該貢獻 0 個亮面像素;可是量到 1834 個。查下去:那 1834 個像素 100.0% 落在排在它前面那張紙的四角內。四角在畫面上互相重疊,9 張裡 7 張有重疊、最高 71.6%,另外兩張的「亮面」同樣 100% 是別張的。⇒ 殘差不是遮蔽機制也不是亮度機制,是量測把別張紙的像素記到這張頭上(背景控制圖 file=0 裡一張在路上的紙都沒有 ⇒ 這一項扣不掉,跟第 17 輪相機側遮擋同一個形狀的漏)。連帶的後果是通過的判準也失效:T2(r=0.887)/T3/U2/U3 全部算在同一份被污染的 ratio 上,它們「通過」只代表預測器與一個記錯帳的量測剛好對得上。⇒ 「紙互相遮」不只是佈局取捨(那一半仍等人類),它同時是量測有效性 bug,那一半不必等。⚠ 事先寫死不當判準的乘積版本(white×visFrac)反而好看(r 0.9178、最大殘差 0.201,會讓判準過),但它是偏差修正冒充機制:預測器系統性高估 14.2%,而平均 visFrac 是 0.891,兩個數字剛好互相抵掉 —— 沒有事先決定判哪一個的話,這一輪會以「通過」收場。第 19 輪照第 18 輪的處方修了「扣掉別張紙的像素」,結果沒有用:T3b/U4 0.3272 → 0.3272 一個字沒動,T3/U3 中位數反而變差(0.049 → 0.116),而第 18 輪訂的 O1 是空過(目標那張被扣 0 px,0.019 在改之前就已 ≤0.02 —— 門檻訂在已量到的值之上,不可能失敗)。原因查明且有像素證據:深度序用中心距,兩張只差 0.143 而紙帶傾角 ⇒ 深度區間重疊,排不出先後;四角內非亮面像素 (217,209,196)=min-ch 196 與 dimpx 獨立量到的 196 一字不差,被算成亮面的是 (230,225,213)=隔壁那張的表面色 ⇒ 「更遠」那張其實畫在前面並查出第三個污染源:四角裡大量像素既不是這張紙也不是別張紙 —— y=6.2944 的四角 19889px 只有 16.2% 是紙色,其餘是建築暗色(y=6.0584 是 48%);ratio 的分母假設整個四角都在看這張紙,而它大部分不是。第 20 輪把深度序換成逐像素平面 z-test(1/w 對畫面座標仿射,四角擬平面),事先訂的判準過了:目標那張被扣掉 3183 px(中心距那版 0,門檻 1500),而且扣得乾淨——自己的表面色 4820 px 全留、隔壁那張的 1818 px 全扣,程式沒有拿到任何顏色資訊。九張裡五張與中心距答案不同。但殘差變差(T3b/U4 0.327 → 0.510、r 0.887 → 0.782,中位數 0.116 → 0.049),原因具體:扣乾淨後目標那張實測 0.000,因為它自己的表面是 min-ch 196、而門檻 MIN_CH=200——當初推 200 用的「172 與 211 之間整段是空的」不成立。⇒ 剩下的是門檻本身,而它必須先寫進判準表再動。第 21 輪照那條規矩做了:規則 R21 在看直方圖之前凍結(背景 W = z-test own 座標讀 fl_off`;紙面 P = own 裡 on≠off 的眾數色;門檻 = 兩者中點;五個拒絕分支),算出來是 184(Wmax=172、最暗的紙面 196、gap 24)。量具先過 12 題已知答案再被六個變異打過(其中兩個第一次被誤讀成「擋得住」——一個其實是崩潰、一個是題目真的有洞,補了 D7 才擋得住)。證據是逐張表不是殘差:換到 184 之後九張裡只有目標那一張動(ratio 0.000→0.498),其餘八張最多動 0.002 ⇒ 184 落在一段真的空著的區間,是外科手術不是全面放寬;若是「渲染讓紙普遍偏暗、調門檻只是掩蓋」,每一張都會一起抬。六個數字全部變好(T3b 0.510→0.174、r 0.782→0.974)但那不是證據,換門檻本來就會這樣,這是事先寫在判準表裡的。⚠ 預設仍是 200,因為事先訂的 M11 沒過:已知沒有在路上的紙那張圖的同一條帶 1908 → 2450 px(門檻 +500,超出 42)。查下去

留下的東西

這一欄是唯一能證明某一輪真的做了事的東西——其餘全部是自述。

77d5b9608-17 09:39Vacantdecision(slash): 永久排除保留現行——但它從今天起是選的,不是預設的
afe80ce08-17 09:22vacant_hmdecision(silhouette): 人類拍板 HW3.0——卡了 44 輪的那一項解封
3725c3308-17 02:19vacant_hmtool(HW3.0): 套進 render 層之後實際渲染重量——而尺在小孩身上到底了,量到的是影子不是身體
c7ce06108-17 01:54vacant_hmtool(HW3.0): 「8 人被壓到 1px」攤開之後是 child 全型 5/5 覆沒
1ee175b08-17 01:39Vacanttool(S7i): 三條紅線並排之後,觀測台的 28 條「信任」旁邊是可究責 0
bcb364208-17 01:28Vacanttool(S7h): 紅線 C 掃出來只有 5 條,四條是誠實邊界句本身——但提示欄位分不出「不保證X」與「只保證Y」
157119808-17 01:16Vacanttool(S7g): 紅線 B 從來沒被檢查過——第一次掃就有 11 個「信任」,而動物園那邊早就不這樣寫了
f3a55e508-17 01:07Vacanttool(S7f): 宣稱階梯那四階從來沒被掃過,而錯的抽取器會同時多抽註解、少抽真文案
b8ec0c508-17 00:51Vacantdata(S7e): 觀測台把「抓到」和「後果」都放上畫面了,但沒有一句話把它們連起來
4f567b608-17 00:34Vacantdata(S7d): 官網沒踩到紅線,不是因為歸因寫對,是因為它沒講「後果」
fed817308-16 21:15vacant_hmchore(gapaudit): 把「寫這一輪的紀錄」本身也判完——順帶關掉會把判決覆寫回舊 key 的那支
6f0d32808-16 21:12vacant_hmfix(gapaudit): 改掉 4 條「頁面說沒做、其實做了」——順帶把稽核的 key 從行號改成內容,否則改完就驗不動了
6f031a808-16 20:57vacant_hmdata(gapaudit): 把本輪紀錄寫進 PROGRESS.md 之後重跑——語料 220→234,因為報告自己也進了被稽核的集合
ec6fd5708-16 20:53vacant_hmfeat(gapaudit): 自承缺口全掃 220 句——抓到 6 條「頁面說沒做、其實做了」,最貴的兩條在每輪必讀的 HANDOFF.md
f95b39408-16 20:34vacant_hmdata(decision): 重生那一頁——刪掉「640 對照還沒做」那半句,補上「距離要價 55–78 對」;既有 166 條 claim 逐條沒動
2c7300b08-16 18:51vacant-docs-webprobe(cdp): 第 80 輪推薦「最穩、什麼都不要改」的那一組,40 張裡只有 1 張拍對
b33150a08-16 17:54vacant-docs-webprobe(shot): 想修尺 B 那張壞畫格,量到的是「直覺的那個修法讓它爛 15 倍」
318119708-16 17:27vacant-docs-webprobe(scroll): 那 29 格「量不到」全部是活的——而第一次跑的綠燈是我自己的門檻公式撐出來的
570691508-16 16:08vacant-docs-webprobe(interact): 回算自檢第 6 條——五輪的「點過 262 個」有 215 次不可能有效果
da405ed08-16 15:27vacant-docs-webprobe(mobile): 回算自檢第 5 條——手機捲不動是真的,但 217 個觸控目標不到 24px

每一輪

第 159 輪 · 08-17 02:29 · 0KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
You've hit your session limit · resets 3am (UTC)
第 158 輪 · 08-17 02:28 · 0KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
You've hit your session limit · resets 3am (UTC)
第 157 輪 · 08-17 02:21 · 3KB
e five: 336 measurable pairs, 254 rescued.

This is exactly the trap the loop instructions warn about — the wrong answer ("the children vanished") was the thing I was already afraid of, which is what would have stopped me re-checking. I've flagged in the code and the report page that this diagnostic was added *after* seeing results, not pre-registered.

**Two predictions I got wrong, recorded as such:** I predicted child `bbW ≤ 2` (got 4 — but the 4 is the ruler's floor, so this ruler can't answer that at all), and I predicted mask-space's "284 rescued" wouldn't transfer within ±10% (it came in at 273, −3.9%). Round 106's caution was right in direction, but noticeably too pessimistic in magnitude.

**Committed and pushed:** `3725c33` on `vacant_hm@main`, local and remote sha character-identical. STATE.md and PROGRESS.md updated.

**Left for the human (rule 7, unchanged from round 106):** whether to exempt the `child` archetype, and whether `dose=3.0` becomes the default. I built the hook but did not flip the default — that would make five residents drop below what this ruler can measure, and the exemption question is theirs. **Next round's own work:** give `big_comp` a `resolved` flag so "can't measure" stops looking like "measured a small thing" — noting that it's shared with two existing probes, so the existing 44-resident/946-pair numbers must be proven bit-unchanged first.
第 156 輪 · 08-17 01:56 · 3KB
**套用的第一半**:人類交代第一條代價是「8 個被壓到 1px 的是誰要列出來」——這件事當時**做不到**,歸檔裡只有 `clamped_n: 8` 這個數,從來沒存過名單。新增 `styles/probe/ss_dose_who.py` 把數變成名單,順帶產出 render 層下一輪要吃的 44 人縮放表。零渲染、零生圖、零機時,2.8 秒。

## 驗證結果 13/13 PASS

判準事前寫進 STATE.md,一個字沒改。關鍵是**名單本身沒有已知答案,所以閘門是總數**:重算的 HW3.0 格逐欄接回 `ss_hard.json`(`284/228/5/8/0.3512345679012346/[12]` 六欄逐位元),沒過就一列名單都不印。加上上游探針自驗(44/44 對 `ss_solo.json`)、桿子逐位元、決定性 diff 0 行、紅線掃描 0 命中、三 repo diff 0/0/0。

## 兩件比拍板時那個數字嚴重的事

**一、`child` 這一型 5/5 全型覆沒**(stout 2/7、short_round 1/5、其餘三型 0)。人類寫的是「逐一看過再決定**個別**豁免,不要整批砍劑量」——但這一型的個別豁免在數量上等於整型豁免,那已經是改劑量。規則七,我沒動,上浮等你。

**二、「5 對退化」量的不是拍板文轉述的東西。** 拍板文寫「本來分得出來、放大後反而變難分」;程式裡 `degen` 是**遮罩整個空掉**(`ss_hard.py:279` 的 `not mk[k]`)=無法判分。真相是 **1 個居民 `f1r0` 整個從畫面消失**,「5 對」只是他恰好落在 365 對難分裡的那幾對,另外 38 對沒被算進去——但他一樣消失了。**單位錯了,而且錯在讓代價看起來像小事。**

第三條低估:clamp 的是「目標」,實得更小 ⇒ **8/8 人實得遮罩兩軸都 ≤ 3px**。空掉那 1 個確定看不見;其餘 7 個我只報 px 不下結論,因為本專案從來沒校準過人眼門檻。

## 預測對帳:4 對 1 錯

`G1601` 錯得值得記:結構猜對(兩個 clamp 條件的聯集),但高度那個界我算錯一格(寫 `h ≤ 9`,正確 `h ≤ 10`)。後果不是小數點——我寫的集合只有 5 人,而我在同一句話裡又斷言「恰好 8 人」。**預測自己前後矛盾,是我沒把式子算完就寫下去。**

`G1602` 對但理由對一半:tall_thin 命中 0,另外 3 人是又矮又胖的坐姿被**高度**壓,那一族我完全沒預料到。

## commit

`c7ce061` vacant_hm(main),已 push,本地與遠端 sha 逐字元相同。`world/` 一個字元沒動。

## 下一步與等你的

執行端可以自己做的:把 HW3.0 套進 render 層,然後用 `chrome-headless-shell`(本輪確認可用)實際渲染縮到 640px 重跑同一把尺——在那個數字出來前,任何降幅只能寫成「離線遮罩量測」。

**等你決定兩件**:(a) `child` 全型 5/5 覆沒怎麼處理;(b) `f1r0` 整個消失是否可接受。名單在 `vacant_hm/DOSE_HW3_ROSTER.md`。
第 155 輪 · 08-17 01:43 · 3KB
分母(A單邊/B可究責/C允許講法)
官網             2     5654  │    0     0     0   │  9 /  9 / 10   A=單邊·B=守線·C=守線
人類動物園         45    12797  │    2     1     5   │ 56 / 12 /  3   A=命中·B=命中·C=命中
觀測台            3    16775  │    0    28     0   │ 22 /  0 /  1   A=單邊·B=命中·C=守線
```

總表**不做新掃描**,是把 `family_audit()` 拆出 `family_collect()` 之後同一份結果的重新分組——所以列小計必須等於既往單掃描總數,五格全一致(候選 2 · 檔 50 · 字元 35226 · B 29 · C 5)。

**最實際的發現**:觀測台講了 28 次「信任」,而「可究責」計數是 **0**。單看 `--diction` 只知道 28 條;分母欄一加上去才知道那 28 條沒有任何對照組——不是偶爾用錯詞,是整個口徑還停在舊的那一套。改詞是文案決定,沒動,等人類。

**兩次自己犯了總表要防的病,方向相反所以被抓到**:分母詞族沒探針就上線,機器說觀測台 C 分母 0、第 104 輪手數是 8——去查發現兩邊都錯(那 8 個是「尚無成本資料」這類 UI 標籤;而我同時漏了 `app.html:37` 真正的「被竄改…都會改變它」)。若只漏一邊,數字會很接近然後我就信了。另一次是讀法欄把 A 的「命中 0 + 分母 >0」寫成「守線」,但 A 的分母是單邊句,>0 只代表講了一半——為了防「沒講被讀成乾淨」加的分母,自己又把「講了一半」讀成乾淨。

**預測 4 對 1 錯**:賭紅線 C 那 5 條跨兩個 repo(依第 104 輪原文「同一句話在兩個展件的拷貝」),實際全在 `vacant_hm`——那是同一展件的**兩個頁面**。攤開排才看得出口語講「展件」時指的是頁面還是 repo。

判準 G1–G7 全過;既往三支掃描完整輸出 diff 0 行,觀眾文案 0 行改動,零機時零生圖。

## 兩件要告訴你的

1. **push 一度被拒** — 你在本輪工作期間推了 `77d5b96`/`e6b65da`。確認兩者只動 `DECISION_SLASH.md`/`ops/loop.sh`、與 `runs/` 零重疊後 rebase,**rebase 後把判準重驗一次才 push**(rebase 換掉腳下的樹,之前驗過的不算數)。commit `1ee175b`,兩個 sha 逐字元相同。

2. **`DECISION_SLASH.md` 落地了** — 「永久排除是否可接受」不再是卡住項。已從 STATE.md 與 PROGRESS.md 的卡住清單移除,並記下裁定文自己講明的一點:B 層六情境第 88 輪已掃完 ⇒ 那個凍結理由已解除,**是在便宜的情況下選擇不改**。

黏土剪影五選一仍是連續第四十七輪等你作答,本輪一像素沒動。下一輪建議接 SCOPE 裡那三個 `*probe.js` 的排除——總表已把逐展件拆分固定下來,改完可以逐格對帳而不只對總數,成本比之前低。
第 154 輪 · 08-17 01:30 · 2KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
Round 104 done and pushed. Summary:

**做了** — 紅線 C(宣稱強度)第一次掃描。三條誠實邊界裡的最後一條——「不准宣稱『保證正確』或『防止』作惡」——到今天為止從沒被任何自動路徑檢查過。在 `runs/s7_claim_audit.py` 加 `--strength`/`--strength-test`,共用同一份 SCOPE 與 `extract()`。

**判準先寫、量尺先於工具**:已知答案不是事後湊的,是動手前用 shell `grep -ohE`(不同 regex 引擎、不同程式)對 50 個 SCOPE 原始檔數出來的。工具寫完後六族逐字重現 `4/0/23/0/2/7`。七格判準全過,探針 10/10 一次過(含五個鄰近詞的負向半:`確定性` 出現 6 次一次都沒進詞族)。

**結果**:全 SCOPE 35226 字元觀眾語料只有 **5 條命中,其中 4 條是誠實邊界句本身**(「不保證每次都對,它只保證一件事:做過什麼會留下來」,在兩個展件的兩份拷貝)。唯一真候選是世界 HUD 的「擋下 N」計數——是計數不是宣稱,但對外行讀起來像「擋住了」,留給人類判定。

**本輪最實際的發現,是工具的極限不是產物的問題**:〈否定脈絡〉提示把那句裡**兩個**「保證」都標成否定,可是第二個「只保證」是肯定用法,只是落在前半句「不保證」的 12 字窗裡被汙染。機器挑得出「保證每次都對」,但分不開「不保證X」與「只保證Y」——**而紅線 C 的全部風險正好住在那條線上**。這個弱點在紅線 B 上不會出現(B 沒有「被允許的肯定用法」這個類別),C 沿用 B 的形狀就一併繼承了它沒被測到的地方。沒有補,補法會改動 `--diction` 既往輸出,要獨立登記一輪。

另外兩件:`C3 防止` 語料 1/原始檔 23,22 個差額是**別的領域的同形詞**(`擋住` 在 clay 算圖器裡指遮擋 occlusion,`prevent` 全是 `preventDefault`);觀測台這次 0 命中且事後診斷確認它有在講被允許的講法,**是它第一次在某條紅線上乾淨**(紅線 B 那 29 條裡 28 條在它身上)。

**commit** `bcb3642` Vacant(feat/v2-four-stages),已 push,本地與 remote sha 逐字元相同。STATE.md/PROGRESS.md 已更新。

兩件照實記的:中途用 python 切片改寫時,`s.index()` 區間跨過剛加進去的區塊把它整段刪掉,是接著跑的 `grep` 沒印出函式名才發現的(改寫腳本本身 exit 0)——之後改用 Edit 重加,產物不受影響。優先序第 1 項(黏土剪影五選一)**連續第四十六輪**等人類作答,本輪一像素沒動。
第 153 輪 · 08-17 01:19 · 3KB
```
B1  口徑探針 fixture       9/9(第一次 8/9)          PASS
B2  「信任」語料總數        11 · app.html 6/app.js 2/dashboard.py 3   PASS
    (=第 102 輪手工 grep 的數,逐字相同)
B3a 切句 vs 不切句對帳      29 = 29 · 一致             PASS
B3b 原始檔 ≥ 語料          11≤20 · 2≤4 · 16≤20        PASS(差額全是註解)
B4  既有四支探針           7/7 · 13/13 · 4/4 · 11/11  PASS
B5  紅線 A 既往數字        候選 2 · 35226 字元 · 50 檔(一個沒變)  PASS
B6  觀眾文案 diff          0 行                        PASS
```

**探針當場打回我一格**:`D1` 我把「這是信任觀測台」的〈否定脈絡〉期望值寫成 `True`,但那句裡一個否定詞都沒有 ⇒ 已知答案本來就是 `False`。改的是 fixture 不是程式碼。

## 量到什麼

語料裡 **11 個「信任」+16 個英文 `trust`**,29 條裡 **28 條在觀測台**;肯定用法 23 條、否定脈絡 6 條。最重的是招牌類:`<title>Vacant — 信任觀測台`、`Trust Observatory`、「信任開關對照」。

**最實際的發現**:`vacant_hm/js/hero.js` 原始檔有 3 個「信任」、畫面 0 個——三個全在註解裡,內容是「對不懂的觀眾講『信任』是騙人。改成『可究責層』」。動物園那邊早就照紅線 B 做了,而且把理由寫在自己的註解裡,所以理由從來沒有傳到觀測台。不是兩份程式漂移,是紀律只覆蓋寫著它的那一支。

預測四條錯一條,錯得徹底:我預測英文 `trust` 在語料裡是 0(只在識別字裡),實際 16,而 `Trust Observatory` 是印在畫面上的英文副標——**紅線 B 講「信任」,我就只找中文**。

## 收尾

- commit `1571198`(Vacant / feat/v2-four-stages),已 push,`git rev-parse HEAD origin/…` 兩個 sha 逐字元相同
- STATE.md 第 103 輪事前登記+事後、PROGRESS.md(誠實邊界回算表、Vacant 本體、卡住三條新決定)都已更新
- **本輪一個字的觀眾文案都沒改**——觀測台要不要改名是敘事決定,寫進〈卡住〉等人類

**下一步**:紅線 C(「保證正確」「防止」「杜絕」)同樣是單詞族、同樣沒人掃,會被同一個理由漏掉(太簡單所以沒人做),詞族與 fixture 可比照 B 直接寫,執行端可以自己做。

**卡住**(都沿續前輪):黏土剪影五選一連續第四十五輪等人類;`~/vacant` 不是 git repo,STATE/PROGRESS 無版本控制無異地備份;`HANDOFF.md` 機器識別段仍寫 Windows 那台(本機實測 `hostname`=`user1`)。
第 152 輪 · 08-17 01:08 · 2KB
it.SCOPE`(第 101 輪的下一步 1)。這不是加一行 glob——舊的 `extract()` 對任何非 HTML 檔一律走 JS tokenizer,所以要新寫 Python 抽取器(走 `ast`)+獨立的 `.py` 量尺(走 `tokenize`)。

## 驗證結果(判準事前寫在 STATE.md,跑完一個字沒改)

| 格 | 判準 | 實測 | |
|---|---|---|---|
| P7a | 新抽取器 fixture 全過 | 11/11 | PASS |
| P7b | 同組給現行 `js_strings` 答錯 ≥3 | 4/11 對,**答錯 7 格** | PASS |
| P7c | `.py` 量尺 fixture | 4/4 | PASS |
| G1 | 加入前 2 條候選消失數 = 0 | 消失 0 · 新增 0(2→2) | PASS |
| G2 | 覆蓋字元增加 | 27179 → **35226** (+8047) | PASS |
| G3 | `dashboard.py` 漏失率 0% | 待測 29 段 · 漏 0 · 0.0% | PASS |
| G4 | 既有 fixture 不退步 | 7/7 · 13/13 · 4/4 | PASS |
| G5 | 宣稱階梯的字進了語料 | **2/3** | **FAIL — 判準我寫錯** |
| G6/G7 | 機時 0 · 文案 diff 0 行 | 0 · 0 | PASS |

**G5 FAIL 是我把判準裡的原文默寫錯**(寫成「**本**面板不承載此階宣稱」,原文沒有「本」)。照 FAIL 記;事後用原文重查全部命中,但那是 post-hoc 不計入。這是連續第二輪同一形狀(101 輪 E0c/E2)。

**預測三條錯兩條**:唯一猜對的那條正是我事前期待的答案。

## 兩個順帶量到、跟展場有關的

1. **`dashboard.py:66` 有第二個觀測台**——`_PAGE` 是整頁內嵌 HTML,`:251` 當 `app.html` 讀不到時的 fallback 送出。離線、無人值守、少一個檔就會踩到它,而它從沒被任何掃描看過。
2. **S7 從來沒查過誠實邊界第二條**:事後直接數抽取語料裡的「信任」= **11 次**(`app.html` 6、`app.js` 2、`dashboard.py` 3,含 `<title>Vacant — 信任觀測台`)。`app.html` 全程在 SCOPE 裡卻沒被標出來,因為 S7 掃的是紅線 A(歸因),紅線 B(口徑)沒有任何自動檢查。這正是第 72 輪自己寫下「這個 0 不准擴出去」所預留的那一格。**改文案是文案決定,本輪一個字沒改。**

## 收尾

- commit `f3a55e5` Vacant(feat/v2-four-stages),已 push,`git rev-parse HEAD origin/…` 兩個 sha 逐字元相同。
- STATE.md、PROGRESS.md 已更新(`~/vacant` 不是 git repo,仍無版本控制——連續第四十四輪的卡住項)。
- 黏土剪影五選一**連續第四十四輪**等人類作答,本輪一像素沒動。
第 151 輪 · 08-17 00:54 · 3KB
ll to skip, or wait longer.
第 101 輪完成。一輪一件,判準先寫、驗完才收尾。

## 做了什麼

掃了**觀測台(`Vacant/vacant/web/app.html`)的活體 DOM**——第 100 輪明確登記「本輪沒做」的後半,也是最後一個沒被掃過的展件。起真的 dashboard(`vacant up`,產品入口本身)+離線假腦 40 筆交付,九個狀態,餵給 S7 紅線掃描。

## 量到的東西

**三個展件的形狀量齊了,三種都不一樣:**

| 展件 | 講「抓到」 | 講「後果」 | 同句連起來 |
|---|---|---|---|
| 官網(第 100 輪) | 91 次 | **0 次** | 0 |
| `vacant_hm`(第 98 輪) | 有 | 有 | **2 條**(紅線風險) |
| **觀測台(本輪)** | 216 次 | 27 次 | **0** |

官網是「根本沒講後果」,觀測台是「**兩邊都放上畫面了,但分開在不同格子**」——稽核通過率一格、SLASH/信用已被扣減另一格,中間沒有因果句。要不要連起來寫成一句是敘事決定,等人類。

## 本輪最該報的不是那個 0,是四件錯的

- **兩個判準是我自己寫錯的,照記 FAIL。** E0c 拿 `#chip-head b` 驗渲染,但渲染成功時那個 `<b>` 會被換掉 ⇒ 那是「越成功越不會過」的反向判準。E2 我宣稱四句只有活體才掃得到,實際三句就是 `app.js` 的模板字面量——**活體才掃得到的只有宣稱階梯一類**(住在 `dashboard.py`,掃描範圍從沒收過它)。抓到這個高估的是判準裡「且靜態檔必須 0 次」那半條;沒有它,這格會四句全中而結論是錯的。
- **樣本裡本來不含待測物**:SLASH 沒發生 ⇒「信用已被扣減」從沒進過 DOM。補了一筆稽核已佐證的仲裁才渲染出來。
- **量測工具汙染了樣本**:我塞進 ledger 的 evidence 含「稽核」,被事件流原封不動印上畫面,一度產生 9 條候選,全部是探針自己的字。這同時是展場的事實——**事件流是把資料直接變成畫面文字的通道,原始碼掃描結構上看不到它**。

五條預測全中,所以我在報告裡寫了警戒:預測全中的那一輪正是最不會複查工具的那一輪,而本輪真正擋住錯誤結論的那條判準是 FAIL。

## 收尾

- **commit**:`b8ec0c5`(Vacant / feat/v2-four-stages),已 push,本地與遠端 sha 逐字元相同
- `STATE.md` 第 101 輪【事前登記】+【事後】、`PROGRESS.md` 第 3 節與「卡住」段都更新了
- 零機時、零生圖、文案 diff 三個 repo 皆 0 行、11 分鐘

**下一步**(兩件執行端可自己做):把 `vacant/dashboard.py` 收進掃描範圍(會改動既往分母,該獨立登記一輪);做 S7 三輪的並排總表。

**卡住**:黏土剪影五選一連續第四十三輪等人類。另外首次記下——本機沒有 `.venv`,`CLAUDE.md` 寫的 `.venv/bin/python -m pytest` 跑不了,用系統 `python3` 可以。
第 150 輪 · 08-17 00:36 · 2KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
第 100 輪完成(00:28–00:35 UTC,7 分鐘)。

## 做了什麼

接第 99 輪的下一步:掃**專題官網的互動後 DOM**——第 97 輪掃的是原始碼、第 98 輪掃的 rendered DOM 只涵蓋 `vacant_hm`,官網那六組互動的字(十秒找 bug、共同盲區揭曉、收據組裝、路由開關、團隊、目錄)**兩條路都沒看過**。

## 結果

先寫判準再做事,全部照登記跑:

| 判準 | 結果 |
|---|---|
| D1 探針雙向自驗(canary 點擊前/後、decoy) | 0 / 1 / 0 **PASS** |
| D2 頁面真的跑了(`.code-token` = 216,靜態 HTML 是 0) | 216 **PASS** |
| D3 六格「互動後才存在」的字 | 6/6 HIT |
| D3b 畫面「11 件」 vs 直接讀 `main.js` 數 X | 11 = 11 **PASS** |
| D4 新候選 | **0 條**(既有候選 0 條消失,覆蓋量 84911) |
| D5 文案 diff(三個 repo) | 0 / 0 / 0 行 |

**比那個 0 更有資訊的一條**:另寫一段獨立詞頻計數(不經候選邏輯)——官網全站含互動後 DOM,〈排除類〉14 個詞**一次都沒出現**,〈抓到類〉中文卻有 91 次。所以官網沒踩到 S6 紅線,**不是因為歸因寫對了,是因為它從頭到尾沒講「後果」那一段**。要不要補是敘事決定(規則七),不拍板;但「抽查」已講 91 次,後果句一旦接上去,最順的接法就是錯的那個。

## 兩件照實記的

- 實作時我原本把「目錄」那格寫成字比對——`<dialog>` 的內容**關閉狀態下就在 DOM 裡**,那會是個**必過的假判準**。改回事前登記寫的 `dialog.open`。同形狀還有宣稱卡背面(翻面只換 CSS)。
- 預測 `C1002`(「若有新候選則來自跨元素拼接」)**前件不成立,不算猜中**。`C1001`/`C1003`/`C1004` 對。

## 沒做的

`Vacant/vacant/web/app.html`(觀測台)的互動狀態**明確沒掃**——它要活的 dashboard 伺服器才有資料,靜態 http 下整頁是空的、掃出來是假的乾淨。一輪一件,不併;做法與判準已寫進下一步。

**commit** `4f567b6`(Vacant / feat/v2-four-stages,已 push,本地與遠端 sha 逐字元相同)。STATE.md、PROGRESS.md 已更新。

黏土剪影五選一**連續第四十二輪**等人類作答,本輪一像素沒動。
第 149 輪 · 08-17 00:24 · 3KB
自己做」的那項:修 S7 文案抽取器,重跑第 97/98 輪的掃描。

**最重要的發現是:第 98 輪寫下的病因是錯的。** 那一輪把病因記成「正則分支順序」(`'…'`/`"…"` 排在反引號前面)。動手前先重現,發現那不成立——正則的交替只在**同一個起始位置**比先後,單引號與反引號不可能從同一個字元開始,調換順序不改變任何一個 match。照那個診斷去修,會得到一支改過而且沒有變好的程式。

真因是**配對錯位的連鎖**:反引號分支的內容類別 `` [^`\\] `` 不准含反斜線,第一條含 `\n` 的模板配不起來,掃描指標落進模板內部,之後每個反引號都跟錯的另一半配對——抽出來的是模板**之間的程式碼**。單點錯配連鎖到檔尾,這也解釋了為什麼 `phone.js` 壞最凶(那批文案在檔案後半)。改成逐字元 tokenizer。

## 量出來的數字

| | 修前 | 修後 |
|---|---|---|
| 非註解中文段漏失(392 段) | 12.5% | **0%** |
| 抓到的**文案**中文字 | 2240 | **2648(+18%)** |
| 誤抓進來的**註解**中文字 | **2944** | 107(−96%) |
| 候選(含 21 份 DOM) | 14 | 15(消失 0 條) |

第 97 輪那個「53652 字元」覆蓋量閘門,**讀進去的註解比文案還多**,已在該報告加註標為作廢——判定結論一條都沒消失。新增的候選正是 `phone.js:256`,第 98 輪要靠 rendered DOM 才看得到,現在原始碼路徑自己就看得到,這是修好了的外部佐證。

## 照實記的兩格 FAIL 與兩次探針出錯

`Q2a`(修前漏失 >20%)實測 12.5%、`Q4a`(字元數 >53652)實測 27179,**兩格都 FAIL**。兩格都是我判準口徑寫錯,不是修壞了:41% 是 `phone.js` 單檔數字被我當成全範圍期望;補回文案的同時也停止把程式碼當字串抽,總量本來就會降。Q2a FAIL 後照事前登記停下來查量尺,逐檔拆開(phone.js 49%、其餘 12 檔 0%)確認量尺沒問題。

兩個探針各先錯一次,**而兩次的錯都會讓結果更好看**:tokenizer fixture 第一次 11/12,FAIL 那格是探針斷言錯(要求模板不准含自己的 `class="cap"`,等於要求程式做錯事);量尺第一版逐行判註解,對續行不加 `*` 的區塊註解全漏判,給了 legacy 一個誇大的 84.7% 漏失率——那個方向剛好讓「我修好了」顯得更有功勞。84.7% 作廢,真值 12.5%。

**文案一個字沒改**(規則七),三個 repo 文案 diff 皆 0 行。commit `3d173cb`,已 push 且遠端 sha 逐字元相同。

**下一步**:`vacant-docs-web` 與 `Vacant/vacant/web/` 的互動狀態還沒掃,同一支工具可掃、零機時,執行端可自己做。

**卡住**(連續第四十一輪):黏土剪影五選一等人類作答,本輪一像素沒動;`~/vacant` 仍不是 git repo,`STATE.md`/`PROGRESS.md` 無版本控制無異地備份。
第 148 輪 · 08-17 00:10 · 2KB
 a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
第 98 輪完成。做的是第 97 輪唯一標明「執行端可自己做」的那一項。

## 做了
掃「互動之後才存在的文案」——第 97 輪的 DOM 掃描只涵蓋初始渲染,那些字兩條路都沒看過。用 `probe/cdp.py` 驅動 `chrome-headless-shell` 走 21 個互動狀態。

## 找到的(比預期重)
- **踩到·強形式** `vacant_hm/world/js/phone.js:256` → 畫面實際渲染「**重跑抓到了**,牠的光會暗下去、**一段時間拿不到工作**」——〈抓到〉與〈拿不到工作〉在同一句。S6 量到的重心是「評審看得見」,沒被抓的作惡者一樣只拿到守規矩者的 1%。
- **踩到·跨句** `phone.js:125–126`「被抽查到…工作不會交到牠手上」——句級掃描結構上看不到,人工讀出來的。
- **要人類定**:`phone.html:35–37` 記分板「被退回/被抽查/**被抓到**」、`sampler.js:90→113` 同屏因果鏈。文案一個字沒改(規則七)。

## 這輪最貴的一件事
事前登記那 16 格**樣本裡沒有待測物**:`flagged` = `residual`,不等於 `bad`,60 格裡 6 格 flagged 全走乾淨分支,「被扣分了」「判定:不通過」一次都沒進過 DOM。逐格試到 cell[10] 才是 bad;phone 的 `hurt` 屏 `?id=1..39` 一個都沒有。**不補這兩格,本輪會拿到一個乾淨的 0,而 0 正是我原本預期的答案。**

## 順帶抓到工具 bug,回頭限制第 97 輪
`s7_claim_audit.py` 的 `_JS_STR` 把 `'…'`/`"…"` 排在反引號前面,模板字面量裡的 `class="cap"` 會先配對、把整段文案吃掉。**79 條文案字面量抽不到 32 條 = 41%**。第 97 輪覆蓋量閘門過了,但讀進去的文案少四成。

## 判準對帳(沒過的照記)
`Q1` canary 3/3 · `Q2a` 247>200 · **`Q2b` FAIL**(world/phone 本來就幾乎沒文字,改逐字人工讀完)· **`Q3` 勉強**(事前 16 格 14495 沒過,擴充到 21 格 20336 才過)· `Q4` 三 repo 文案 diff 0 行 · `Q6` 17 分。預測 **C983 錯**:新候選不在我預測的 `rp-bound`,在沒預測到的 `phone.js` hurt 屏。

**commit**:`4dc65ba` + `fa53bd2`(Vacant / feat/v2-four-stages,已 push,sha 逐字元對上)。第二個 commit 是自我更正——判準表的時間那格我填的是估計值 75 分,量出來是 17 分。

**下一步**:修 `_JS_STR` 並重跑第 97 輪掃描(零機時,可自己做)。**卡住**:`phone.js` 那兩句的換詞方向與記分板版面等人類;黏土剪影五選一連續第四十輪等作答。
第 147 輪 · 08-16 23:48 · 2KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
第 97 輪完成。

**做的事**:接第 96 輪「下一步 1」的零風險那一半——把 S6 的結論(把作惡者擠出路由的主要動力是**被評審看見**,不是**被稽核抓到**)當成紅線,掃過三個 repo 的觀眾文案。**一個字的文案都沒改**(換詞是敘事決定,規則七)。

**掃到的唯一一條**:`vacant_hm/index.html:111` 右屏三詞總結「信譽路由 · 三層漏斗 · **抽到就扣分**」。字面為真(抽中稽核確實會 slash),但它把弱的那條通道講成機制的牙齒——而同一頁下一屏的「第 2 層 密封評審」才是 S6 量到的強通道。問題不是頁面缺了評審通道,是那句三詞總結挑錯了代表。

**這一輪的工作量幾乎不在「掃」,在「證明探針找得到」**——第一次跑出來就是 0 個候選,而 0 正是我希望看到的答案。兩個「看起來成功」的故障因此被逼出來:

1. `file://` 下 ES module 被 CORS 擋掉、頁面根本沒跑,而 `--dump-dom` 照樣回傳 HTML。`deliveries.html` 的 DOM **351 → 7375 位元組(21 倍)**。照 `file://` 掃會拿一份幾乎空的 DOM 得出「乾淨」。
2. 挖掉 `<script>` 時把換行一起挖了,行號整體偏 4 行(工具報 107、真值 111)。報告會把人送到錯的一行,而那一行看起來也像是差不多的地方。

**照標不藏的兩件**:事前登記的 `CATCH` 詞族漏了「抽到」——照那份清單跑,本輪唯一的發現會漏掉;照出它的 `--diag` 也是事後加的。兩項都是放寬召回不是放寬判準,判準的數字一個字沒改。另外互動後才拼出來的字沒走 DOM 這條路,覆蓋度低於初始畫面。

**驗證數字**:P1 fixture 7/7 · P2 canary 原始碼與 DOM 兩條路各自獨立確認(DOM canary 用拼接字串,原始碼路徑看不見它)· P3 覆蓋量 80330 字元 · P5 兩個文案 repo `git diff` 0 行、`vacant/` 0 行 · 零機時零生圖。

**commit** `41bae6c`(Vacant / feat/v2-four-stages),已 push,本地與遠端 sha 逐字元相同。STATE.md、PROGRESS.md 已更新。

**兩個新的等人類項**:①那句換成什麼(三個方向與代價已列);②觀測台算不算展場螢幕——`Vacant/vacant/web/` 的 UI 有 5 處「信任」,踩到誠實邊界第 1 條,但只有在它會上展場螢幕時才算數。兩個站的 rendered DOM 仍是 0 次。

需要說清楚的一點:**本輪只是把要改的地方指出來,展場並沒有因此變正確。改了才算。**
第 146 輪 · 08-16 23:37 · 3KB
由**:`in_blind` 由 `sha256(seed, 輪次)` 指派(`entrycost.py:376`),與行為、與誰被路由都正交;而 `_peer_reviews(blind=True)` 讓三位評審一律投 1.0,與乾淨交付逐位相同。同一個攻擊者的作惡輪次在資料裡**已經被現成地隨機切成兩半**——同樣作惡、同樣沒被抓,只差評審看不看得見。

限 215 個 `caught==0` 的 seed(那裡 `apply_slash` 從未執行):

| 這一輪的交付 | n | Δscore 均值 | Δ<0 佔比 |
|---|---:|---:|---:|
| 乾淨交付 | 1668 | +0.02963 | 0.0% |
| 作惡·落在盲區 | 425 | **+0.02915** | 0.0% |
| 作惡·評審看得見 | 793 | **−0.04469** | 87.1% |

盲區作惡與乾淨交付差 0.00048。**作惡本身不扣分,被看見才扣分。**

兩個會殺掉這個結論的東西都除掉了:decay 混淆(固定路由間隔 1/7/10 輪後差仍在)、反向因果(同一 seed 內配對 **110/110** 全部同向)。餓死發生在第 152–387 輪(佔 9600 的 1.6–4.0%),對照組同期 9596 輪。

## 探針 P4 擋掉的是一個假發現

第一次跑 P4 是 ✘:報 515 而非 215。**錯的是我自己的腳本**——把「從沒被抓的作惡 seed」寫成 `caught == 0`,漏了 `and not control`,而恆不作惡的對照組 300 行 `caught` 當然也是 0。它同時污染了乾淨輪那一格:修正前 n=153168、Δ 均值 +0.00121,99% 來自早已飽和的對照組,把 +0.02963 **稀釋 24 倍**。沒有 P4,這輪會拿被稀釋的基準線去比,得出「盲區作惡比乾淨交付還加分」——而那看起來會很像發現。修的是腳本,判準一個字沒改。

事前押九格中 8(B4 第一次 ✘、修腳本後 ✔)。commit `4c58186`,已 push,HEAD 與 remote 兩個 sha 逐字元相同。

## 下一步與卡住

**下一步**:展場講法要從「被抓到才會被排除」改成「排除的主要動力是被看見,被抓只是把它提早一半發生」——**但這是敘事決定,規則七,執行端不拍板**;先掃現有文案哪裡踩到是零風險的準備。另外這條通道只在一組參數點量過(`reviewer_accuracy=0.7`、`correlation=0.0`、K=3),補網格**要花機時**。

**卡住**(都照舊記在 STATE.md):黏土剪影五選一連續第三十八輪等人類;`~/vacant` 仍非 git repo,STATE/PROGRESS 無版本控制無異地備份;`HANDOFF.md` 機器識別段仍在講 Windows 那台,本機 `hostname` 是 `user1` 不是提示詞寫的 `user1-2`。

還有一件本輪讓它**變難**的:「永久排除是否可接受」——現在知道排除的動力是「被同儕看見」,而看見與否有 27% 盲區,也就是**排除的準確度上限不由稽核決定,由評審的能見度決定**。仍純粹是價值判斷。
第 145 輪 · 08-16 23:23 · 2KB
piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
第 95 輪完成。

## 做了什麼

接手第 94 輪的下一步 3(「曝光的分母值得單獨拆」)。**零額外機時**——只重讀已落盤的 900 行,`vacant/` 一行沒改。先在 STATE.md 寫死判準與七個事前押注,再動手。

## 主要結果

**擋住攻擊者的主要不是「抓到它」。** 215 個**從沒被抓過**的作惡 seed,作惡 1218 次全部得手、零次被抓,在 9600 輪裡卻只拿到 7.3–23.8 次工作 = 恆不作惡對照組(1290 次)的 **0.57–1.84%**,而且不隨輪數放大(S_C 0.99–1.11 vs 對照組 14.33)。存在一條不需要 slash 的排除通道,被抓只是把排除提早一半發生。

**我押錯了一格,而且錯的方向跟第 94 輪一樣。** 第 94 輪說剩餘曝光「全部」來自沒被 slash 的 seed,我事前照著押 ≥80%。實測是兩群各出一半(C 佔 39.5–53.5%),另一半是被 slash 者**在被抓之前**就拿走的——那一塊 slash 完全碰不到。兩輪都往「slash 很有效、漏網的才是問題」這個比較好聽的方向錯,所以寫進正文不是附註。

**順帶補上第 94 輪沒查的洞**:`stopped_early_at` 0/900,對照組曝光逐格精確落在 `rounds/7.5+10`(300 行零違反)⇒ 9600 輪真的跑滿,S4 的「16 倍」不是早停假象。

**讀碼時發現的範圍問題**:`routes_after_slash` 只數第一個被 slash 的身分(`entrycost.py:354`,註解寫明是刻意取捨),所以第 94 輪「回來過的 seed 全 0」就儀器而言是關於身分的斷言。實測 `identities_used` 全 900 行 ==1 ⇒ 這組設定下成立,但不可外推(S2F 同欄位 max=601)。

## 驗證

五條探針各驗兩個方向全過,含負對照(把 C 故意打 0.9 折,必須抓到不符 → 30/30 格)與已知答案錨點(S2F 分佈 `{1:201,2:33,3:6,601:60}` 逐字命中)。

## 誠實邊界(已寫進 FINDINGS)

第二條通道**量到的是效果,沒有指認機制**;**反向因果沒有排除**(唯一旁證是未被抓者曝光 14.0 高於被抓者被抓前的 7.05);「餓死」只到 9600 輪。

**commit** `d22bda0`(`feat/v2-four-stages`,已 push,本地與遠端 sha 逐字元相同)。STATE.md、PROGRESS.md 已更新。

**下一步**:`runs/s4_v1/S4/logs/` 已有逐輪 `score`,拉那 215 個 seed 的信譽軌跡就能指認第二條通道並嘗試排除反向因果——仍是零模擬機時。

**卡住**:優先序 1(黏土剪影五選一)連續第三十七輪等人類作答,本輪一像素沒動。「永久排除是否可接受」這題本輪變得**更難**——排除的範圍比原本以為的大(沒被抓的也拿不到工作)。
第 144 輪 · 08-16 23:11 · 2KB
licitly: < /dev/null to skip, or wait longer.
Round 94 complete.

## 做了 · S4:拉長 `rounds` 買不買得到相位週期?**買不到**

S3(上一輪)留下的洞是 35/75 格的 `(burst, recover)` 根本沒被實現——相位鐘走在「第幾次被路由」上,防禦把曝光壓到個位數。修法有兩條,我量了不需要人類裁決的那條。

**答案不是勉強不行,是完全飽和。** 輪數 ×16,四個攻擊者格的曝光只多 0–6%(S=1.00/1.03/1.01/1.06;事前寫死的判死門檻是 S≤4)。最高週期數 1.18 個。

真正撐住這個結論的是對照組 `(0,10)`——pulse 判定式回 `0 < 0` 恆假,它一次都不作惡、從不被 slash,曝光是 **14.33 倍**(線性上限 16)。只跑攻擊者格的話,量到飽和分不出是「防禦造成的」還是「路由器本來就不隨輪數放大任何人」,而那是兩個相反的結論。

**零額外機時的追加**:飽和的成因是第一次 slash 一次切斷。被 slash 在第 67–217 輪,之後還剩 9383–9524 輪可用,而 `routes_after_slash` 在 20 個攻擊者格上**全部是 0.000**、回來過的 seed 全 0。這把 S1 的「600 輪內 0/368 回來」延長到 9600 輪 ⇒ 「也許只是還沒等夠久」這個讀法關掉了。誠實邊界照留:λ=0 時是 214/368,回來的通道存在,是 λ=1 把它關上的;執行端不建議 λ/f 該設多少。

**押的六格中 4 錯 1,另一格無從檢驗——而那格最重要。** R5 本來要拿「固定 (b,r) 只動 rounds」這個獨立軸去檢驗上一輪的機制解釋(那個解釋是在 (b,r) 軸上量的,而 (b,r) 同時決定 nominal,解釋與被解釋物共軸)。沒有一格跑到 3 週期 ⇒ 檢驗沒有發生 ⇒ **上一輪那個機制解釋到現在仍未被獨立驗證過**。這件事寫進了三個檔案,因為下一輪很容易把它當成已驗證的結論用。

探針自己的缺陷也照報:P4 事前沒預見對照組照定義就會違反它,攻擊者 20 格與對照組 10 格分開報,沒合併成一個好看的通過率。

驗證:P1–P4 全過(P1 的「rounds=600 那 120 行對 S3 逐位相同」0 行不同)· cells 30/30 · rows 900/900 · wall 980.3s · SHA256SUMS 5 檔全 OK。`vacant/` 一行沒改(`git diff --name-only -- vacant/` = 0)。

**commit** `e10a8a3`,HEAD == origin。STATE.md、PROGRESS.md 已更新。

**下一步**:model II–IV 的盲區主跑現在沒有可辯護的 `rounds` 值,只剩「接受在 <1.2 個週期下比較(報告要寫明比的不是 Srivatsa 的穩態成本比)」或「等人類裁決時間軸」兩條——前者執行端可以做。

**卡住**:黏土剪影五選一連續第三十六輪等人類;`~/vacant` 仍非 git repo;`vacant_hm` 那三個未提交檔本輪一樣沒動。
第 143 輪 · 08-16 22:40 · 2KB
icitly: < /dev/null to skip, or wait longer.
第 93 輪完成。

## 做了什麼

跑了 **S3 — E24 的 `(burst, recover) × blindspot` 完整網格**(`iterate_v2.py` 四段裡唯一一次都沒跑過的一段)。75 格 × 30 seeds × 600 輪,wall 216.8s。

先寫判準再動手:五條探針、四項主判準、六個事前押注全部寫進 STATE.md 之後才跑第一行。

## 結果

**推翻的是這一輪自己的動機。** 排這個網格的理由是懷疑 E24「時間結構只差 1.81 倍」量在效應為零的交叉點(盲區 0.5)。跑完五個盲區值,得手數的跨格比值是 **1.40 / 1.83 / 1.47 / 1.81 / 2.48** — 沒有一個盲區讓時間結構顯形,0.5 甚至不是最小的。押的 R2(至少一個 >3.0)錯了。

但工作不白做:三層分解(得手=曝光×作惡率×逃脫率)顯示每個盲區上曝光比值 4.0–6.1、作惡率比值 6.0–11.0 都遠大於得手比值 — **兩個大效應反向抵消**,不是這個維度不存在。再把 `defected` 總量單獨拉出來,跨 15 種節奏只差 1.49–2.49 倍 ⇒ 被綁住的是「總共還能作惡幾次」,不是「多久作惡一次」。

**R5 錯得最有用,而且反咬 E24**:押作惡率 ≈ `b/(b+r)`,實測最大偏 148.7%。相位時鐘跑在「第幾次被路由」上,而防禦把曝光壓到 6.10–51.77 次(總輪數 600)— 75 格裡 **35 格連一個週期都跑不完**。E24 那 15 格全在盲區 0.5,該列有 6 格跑不完 ⇒ 那 6 格的 `(b,r)` 在軌跡上根本沒被實現。

兩處誠實邊界照留:那個機制解釋只中 28/35,7 個例外沒量出原因 → 記成未解、不編故事;「盲區是主軸」這句順口話被自己的表推翻(兩軸同量級 2.73 vs 2.48 倍)。

## 驗證

五條探針全過,每條兩個方向。關鍵的是 P1 用了已知答案 —`(3,10)·blind=0.0` 三參數全預設,digest 必須等於裸 pulse(30/30 行),而其餘 74 格必須全異(0 撞上)。P2 驗後果不驗前提:`blind=0.0` 的 450 行 `blind_passes` 全 0(`_h01∈[0,1)` 不可能 `<0.0`),合併 mean 嚴格遞增 0.000→0.976。`vacant/` 一行沒改 — 這正是 P1 成立的前提。

## 收尾

- **commit** `6e5b0b2` Vacant(feat/v2-four-stages),已 push,HEAD == origin
- STATE.md 事前登記+事後紀錄、PROGRESS.md 第 3 節更新(含「四段全部跑完,下一步不再是哪一格沒跑」)
- 順帶登記一件之前沒人記的:`vacant_hm` 有三個未提交的檔案,mtime 是今天 11:02–11:06 UTC(本輪 22:25 才開始),本輪一次都沒進那個 repo。只登記不處理

優先序第 1、2 項(黏土剪影、交付狀態機)仍受規則七擋,連續第三十五輪等人類作答,本輪一像素沒動。
第 142 輪 · 08-16 22:21 · 2KB
完成。

## 做了什麼

優先序第 1、2 項都卡在人類決定(剪影五選一連續第 34 輪、狀態機剩兩格第 69 輪判定受規則七擋),所以接第 91 輪的下一步 3:**跑從來沒跑過的 S2/S2F(預算窗口)**。

**先寫判準再動手**——事前登記寫進 STATE.md 後一字未改,包含四個雙向探針、窗口的閾值(五臂取最小 ≥0.9)、六個事前押注。

## 結果

**窗口只有一格寬。** 六個預算值裡只有 budget=1 讓五臂全部真的用滿額度,下一格就掉到 0.8667。舊判準 `defected <= BUDGET` 在 30/30 格全部 =1.0——零分辨力,這回是可執行的證明。

**而在那唯一有效的比較點上,E19 的結論反過來**:whitewash 每次作惡得手率 0.5333,是最低的一群;pulse 0.9000。原本的 2.5 倍優勢來自作惡次數不相等。

機制是從 `blind_passes` 逐 seed 驗出來的,不是推論:見習期強制稽核。換身份兩臂作惡時人在見習期內,得手 16/16 全部來自盲區;等待型三臂已出見習期,26 筆得手裡 21 筆是稽核根本沒抽到。順帶一個交叉證據——whitewash 與 sybil 的 `config_digest` 不同(兩個隨機世界)卻逐 seed 30/30 相同,因為 `in_blind` 只吃 (seed, 輪次)。

**這條對展場是兩面的,兩面都寫進 FINDINGS 了**:正面是見習期強制稽核有效、洗掉紀錄等於把自己送回強制稽核區;代價面是等待划算——先交 10 筆乾淨的再作惡,得手率 0.533→0.900。

## 事前押的六格中 5 錯 1

錯的那格是本輪第二個新東西:複驗那句「whitewash 用掉 4.7 個身份」**只在窗口外面成立**,budget=1 時它只用掉 1.47 個。「免費換身份」這條解釋要作惡很多次才顯形,而那正是等預算比較失效的區間——兩件事互斥,它至今沒在一個有效比較上被驗過。

## 收尾

- **commit** `3fa7219`(feat/v2-four-stages),已 push,HEAD == origin
- 探針 P1 300/300 逐位相同、P1′ 268/300 必須不同、P2 30/30 與 11 個相異值、P3 兩向;SHA256SUMS 7 檔全 OK;wall 69.7s
- 順帶獨立重現 E19 原始數字當錨點:budget=12 的 `defected` 11.9667 對 4.8667
- STATE.md、PROGRESS.md 已更新

**下一步**:S3 盲區網格(本輪事前登記寫明不做)。本輪 P3 順帶量到一件寫 S3 時必須標的事——`blindspot` 與 `pulse_burst/recover` 都在 `_LATER_FIELDS`,所以 S3 每一格都是不同的隨機世界,是組間比較不是配對。

**新增的卡住**:`HANDOFF.md:42` 那條 STALE 又更舊了——它列的「未跑」清單裡現在 S1、S1B、S2 都跑完了,只剩 Stage 0 基線、A3、E24。要不要由執行端改仍未答(第 89 輪提的)。`runs/s1_smoke/` 一樣刻意沒動。
第 141 輪 · 08-16 22:08 · 2KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
Round 91 complete.

## 做了

**S1B — 五個候選 λ 全數過 B 層六情境**(接第 90 輪的下一步 1)。第 90 輪量出了 slash 的取捨曲線,本輪回答「哪些 λ 不能選」。答案是 **沒有不能選的**。

判準寫在 STATE.md 裡,**動手之前**,一個字沒改。

## 驗證結果(真的數字)

**探針四個方向全過**(主結果是「全過」,而「全過」與「λ 根本沒接到 B 層」在歸檔裡長得一模一樣——所以先驗尺):
- 被 slash 的 Beta:Δn = 11.6594(必須不同 ✔)、Δmean = 0.00e+00(必須相同 ✔)
- 沒被 slash 的 Beta:兩個 λ 下逐位元相同 ✔
- 情境層:不吃 slash 的四個相同、吃 slash 的兩個不同 ✔
- 回歸:`vacant/` 自 `cb64bf5` 零改動 ⇒ λ=1.0 的 96 格對 `blayer_1000_v3` **比 96 格、不同 0 格** ✔

**主結果**:5 λ × 6 情境 = 30 格全過,1000 seeds,wall 1167.5s。而且不是勉強過——④reviewer_stake 最差格 0.0898 對判準線 0.7,⑤decay_slash 最差格 0.0044 對判準線 0.65。

**事前押六格中 5 錯 1,錯的那格是本輪最值得留的東西**:我押「λ 越小=罰得越深」,把它當單向旋鈕。實測兩個承重情境**方向相反**——λ 越大 ④ 罰得越輕(n 漲讓權重飽和項抵銷均值下降),λ 越大 ⑤ 罰得越重(n 漲讓後來的好評推不動均值)。「調大 λ =加重懲罰」是錯的說法。⑤ 的敏感度幾乎全在 λ∈[0,0.25],補點要補在那裡。

**commit** `9950abb`(feat/v2-four-stages),遠端/本地 sha 逐字元相同。

## 對人類

「永久排除是否可接受」兩邊的數字現在都齊了——取捨曲線 `runs/s1_v1/FINDINGS.md`、機制驗收 `runs/s1b_v1/FINDINGS.md`。**這一條現在純粹是價值判斷,不再缺數字。執行端不建議操作點(規則七)。**

黏土剪影五選一**連續第三十二輪**等作答,本輪一像素沒動。`~/vacant` 仍不是 git repo(STATE.md/PROGRESS.md 無版控、無異地備份,連續第三十三輪)。

**誠實邊界**:這是機制模擬,不是真模型實測。而且「邊際大」只代表判準線離現況很遠,不代表機制強——那六條判準線是 2026-07 訂的,本輪沒有檢討它們訂得鬆不鬆。那是下一輪。
第 140 輪 · 08-16 21:39 · 3KB
grees with simulation." It didn't — I'd fed it fixed `n_before` values instead of realized ones. Re-fed with measured inputs, the same formula separates returners from non-returners 239/240.
- The 0 is right-censored at 600 rounds: 32/40 of those seeds had more rounds left than the longest observed wait (489), but 8/40 genuinely can't be told apart from "didn't run long enough."
- Found a live error: the two arms aren't paired with each other (`strategy` enters `digest()`, so they run in different random worlds — 42/180 seed-groups differ). The axes can be read side by side but not subtracted per seed.

Two things went beyond the pre-registration and are labelled as such: a 300-seed rerun (bets still judged on the registered 30-seed run) and two comment edits, after which a 2-seed rerun was bit-identical.

**commit** `46a02c4` on `feat/v2-four-stages`, pushed. Per-round logs (44M/437M) stayed out of version control per the blayer precedent, pinned by `SHA256SUMS`.

**Next round should take S1B** — running the six B-layer scenarios against each candidate λ. A pretty curve doesn't authorize an operating point that disables the teeth, and scenarios ④/⑤ call `slash` directly. S2 and S3 are also unrun, same script, same low cost.

Still blocked on you, unchanged: the clay silhouette five-way choice (31st round), and now the λ/f operating point — which finally has numbers behind it.
第 139 輪 · 08-16 21:17 · 2KB
: < /dev/null to skip, or wait longer.
第 89 輪完成。

## 做了什麼

接第 88 輪的「下一步」:把它抓到的 6 條 `STALE`(**歸檔頁面說「還沒做」、其實早就做了**)改掉 4 條,並在改之前先做那份稽核自己指出的前置條件——把 key 從 `file:line` 換成內容定址 `file#sha8@k`,否則改完的當下稽核就作廢。

最重要的一句在**人類要拍板的那一頁**:`DECISION_SILHOUETTE.md` 原本寫「選項 4 **與 5** 的救起對數是空的,因為沒量過」,而同一頁的表寫著選項 5 = 211/365(K=2.0 實測)。讀到「兩格都沒量」,最合理的反應就是不作答、等量測——剪影五選一已經卡了三十輪。

`Vacant/HANDOFF.md` 的 2 條**沒改**:那是另一台機器的交接文件,規則七邊界,寫進「卡住」等人類。

## 驗證結果(不是「通過」,是數字)

- **T7_keyshift**(本輪改動的全部理由):真語料插一行 ⇒ 新 key 不變 **239/239**、舊 key 不變 **0/239**
- **換 key 後、改字前的平行對照**:234 句 / 100% / 234 條證據,判決分佈與第 88 輪逐格相同,且 234/234 條逐條回推舊 id 對得上
- **改完**:239 句 / 100% / 239 條證據重跑 / `STALE` **6 → 2**,剩下那 2 條**還在**(如果我是靠刪字變綠的,它們也會不見)
- **numguard**(新寫的數字護欄,自驗含 `0.5574→0.5575` 必須 FAIL):三個檔案既有數字**一個都沒少**
- **真資料兩側變異**:插 5 行 ⇒ 仍 100%;改一個詞 ⇒ 覆蓋率 99.6%、`ok=False`

事前押的六格中 5 錯 1(Q6 貼線)。

## 兩件比主線更值得記的

1. **第 88 輪那條判決自己有一處不準**——它說 `cells` 存了三份配對清單,實測 `degen_pairs` 是整數計數不是清單。⇒ 更正一條 STALE 之前要自己重驗,不能因為它附了證據就照抄。
2. **修好一個缺口會生出新的假陽性**:更正註記必須引述原句,原句裡就有標記詞 ⇒ 掃出來的句數不會因為修好而下降(4 條改動生出 8 句新的)。

## 照報的代價

- `T4_evblind` **放鬆了一格**:正證據的「錯的行」從 FAIL 改成 PASS。換來編輯不會讓稽核作廢,付出「同一字串出現在別的上下文也算數」。
- `mkverdicts.py` 現在**預設關掉**(要 `--force-legacy`):它仍以行號當 key,直接跑會把判決整份覆寫回舊 key,而且會印「寫出 N 條判決」看起來完全成功。⇒ verdicts 目前手維護,是一筆明講的債。
- 本輪**零機時**,剪影本身一像素沒動。

**commit**:`6f0d328` + `fed8173`(vacant_hm/main,HEAD == origin/main)
**下一輪第一件**:`HANDOFF.md` 那 2 條要不要由執行端改——這是要問人類的一句話。
第 138 輪 · 08-16 20:58 · 3KB
收**」 | `PROGRESS.md:2012` — ✅ commit `0fb0b57` |
| `DECISION_SILHOUETTE.md:322` | 「選項 4 與 5 的救起對數是空的,因為沒量過」 | 同頁 `:48` — 選項 5 = **211/365(K=2.0 實測)** |

`HANDOFF.md` 被掃到 4 句、2 句過期(50%,全檔最高),而它是**開場清單第 2 項,每一輪都會讀**。**我自己這一輪開場就被它誤導了一次**,以為風格還沒選定。`PROGRESS.md` 146 句才 2 句過期(1.4%)。

⇒ staleness 的成本 = 錯誤程度 **×被讀的次數**,而前 87 輪只看前者。最短、最常被讀的那份,從來沒人查過。

而 `DECISION_SILHOUETTE.md` 那條在人類拍板的那一頁上、**跟第 87 輪同一節**:第 87 輪拿掉一條,這輪在同一節又找到一條。

## 照實報的

- **事前六格押注中 1 錯 5。** 我事前寫死「NOT_A_GAP >70% = 我在倒垃圾」,實際 **88.9%(只算手判 78.5%)——紅旗響了**。另一個讀法(這 repo 的散文本來就被「沒/未」灌滿)我寫下來但**不拿它取消紅旗**,那一類該被抽查。
- **標記表會漏,漏的正是最重要的一條。** `HANDOFF.md:97`「視覺風格(**六選一**)」也已作廢,但那行**一個標記詞都沒有**,是我讀上下文用手撞到的。**234 不是上界。**
- **113 句是規則判的**(PROGRESS.md 日誌區),沒逐句查證,逐條標了 `[規則判]`。
- **負證據第一版寫錯過。** 拿主題詞 grep 證「沒做過人眼量測」,命中的是 `ss_opts.py:357`「**不是**觀眾實測」——宣告缺口的那句話本身。是檢查器把我打回來的。
- `T1` 事前押 272 行、實際 271。查了原文才改常數,並同時加上「起點對映」不變式 —— 光改常數不算數。

驗證除了自驗 T1–T6,還在**真資料**上做了變異測試:把一條真 STALE 的證據行號 +1 ⇒ 整支 FAIL、`exit 1`。

**commit**:`ec6fd57`、`6f031a8`(vacant_hm/main,已 push,HEAD == origin/main)。本輪**一句原文都沒改**。

## 兩件要你決定的

1. **這 6 條要不要改?** `HANDOFF.md` 是別台機器的交接文件,前 29 輪的立場是「不自己改」——但那立場是針對**機器識別段**。`:42`/`:43`/`:97` 是**專案狀態**,而且已經誤導執行端一次。我建議改,但沒有自己動。
2. `DECISION_SILHOUETTE.md:322` 可以單獨立刻改(它正在對你說選項 5 沒量過),改法沿用第 87 輪的 `ss_cmp60.py` 護欄。

另外照記一個保存期限問題:這版用行號當證據指標,寫這輪紀錄時就失效了兩次(`check` 都當場抓到,沒有假成功)。下一輪接手前該把 key 改成句子 sha —— **現在這版不要當長期資產用**。

黏土剪影仍是**連續第二十九輪**等你作答五選一。
第 137 輪 · 08-16 20:36 · 2KB
 I didn't touch; HEAD and origin/main match.

## 做了

`DECISION_SILHOUETTE.md` — 人類卡了 27 輪沒作答的五選一 — 在末段自己寫著「縮到 640px 的實拍對照還沒做」。**那半句是假的。** `stagevis.py:44` 是 `W, H = 640, 360  # 展場距離:1920×1080 的 1/3`,那一頁四份上游歸檔的 `W,H` 全部是 640,360、讀的檔全部是 `sl_f*_640.png`。整頁的數字本來就是在展場距離量的。

那句話已刪,並補上那一頁從來沒有的一欄。

## 主數字

| | 640(展場距離) | 1920(貼臉看) |
|---|---|---|
| 遮罩面積 px 中位 | 85.5 | 693.5 |
| IOU_SPEC(桿子) | 0.5574 | 0.5279 |
| 難分對數 / 946 | 365 | 364 |

看起來距離不要錢 — 是假的。這把尺的桿子自己跟著解析度移動。桿子釘住再問:1920 的 IoU 用 640 的桿子判 ⇒ **310**/946;640 的 IoU 用 1920 的桿子判 ⇒ **442**/946。**距離要價 55–78 對**,而「365」是相對於同一解析度的數字。ρ=0.9592 ⇒ 動的是桿子與絕對值,不是排序。

那 47 對硬核在 1920 **47/47 仍然難分** ⇒ 是幾何,不是低解析度的量化雜訊。

## 驗證

自驗全過,關鍵兩格:`T1b` 我的萃取器與 `stagevis.diff_mask+ss_dim.big_comp` 在 640 上**集合相等**(44/44);`T1` 逐位元接回 `ss_hard.json` 的 `0.5574387947269304 / 365 / 0.51595`。改頁面則由 `ss_cmp60.py` 判:既有 **166 條 claim 0 改值 0 消失**,`diff` 舊頁新頁刪掉的只有 2 行。

**六格押注錯三格**:我押「距離會吃掉一大塊」(1920 難分 250–340、翻面 ≥40、面積比 9–13),實際 364、34、8.038 — 方向整個錯了。而「幾乎沒動」正是我事前寫下最怕的那個乾淨結論,擋住它的是 `T2`(面積比必須 ≥5,~1.0 就是我兩次讀到同一張圖)與 `T3`,不是任何主數字。

**一格沒過照報**:`A4_cases` FAIL,變的是 `P0_untouched` 的 got — `ss_opts.py` 的 P0 監看 `styles/probe/`,而它自己的輸出就在裡面,會在 commit 前後兩個值之間振盪、永遠不可能乾淨。沒有去改 `CASE_EXEMPT` 讓它過。

commit `91db113` + `f95b394`(vacant_hm/main)。

## 兩件要你決定的

1. **五選一仍然等你**(第 28 輪)。差別是:擋住作答的那句話已經拿掉,並且多了「距離要價 55–78 對」與「硬核是幾何」兩欄。
2. 「**觀眾**分不分得出來」仍然一次都沒量過 — 那要真人,第 1 條的前半句我一個字沒動。這是這條線上執行端做不到的部分。
第 136 輪 · 08-16 20:18 · 2KB
low command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
第 86 輪收尾完成。

## 做了

接手第 85 輪的「下一步」第 2 項:**整檔 sha256 那一族的第一次盤點**。第 84 輪的盤點器在自己的 docstring 裡把邊界寫死成「只掃 `diff_mask`,整檔 sha256 不在內」並點名兩個站點——那半句是誠實的,被後兩輪讀成「所以大概就那兩個」的另外半句從沒查過。

新增 `styles/probe/shaaudit.py`(ast 掃描 + 手動角色分類 + 重問),零機時。

## 驗證結果(真的數字)

自驗 S1–S8 八格全過(`tool_ok=True`)。盤點:**38 個站點、10 支檔案**(不是 2 支),比 PNG 的 16 個,承重 5 行。

兩件會改變我們相信什麼的事:

1. **`A2_optin` 的「沒過」100% 是那個 fps 讀數。** 整檔 sha256 相同 15/49(就是落盤且判 FAIL 的那個數);挖掉 HUD 後逐位元相同 **49/49**。判準與門檻一個字沒改、照樣照報沒過,但那 34 張的差異一個像素都不在場景裡 ⇒ `DECISION_SILHOUETTE.md` 的出處保證變強。

2. **第 67 輪的證據 `.png` 從沒進 repo**(撞到的,不是想到的)。`hudleg.py:180` 是個從沒被盤點過的承重 PNG-sha 判準,它不是污染,但拿 repo 那 48 張重算:逐格 match 第 66 輪、對不上第 67 輪。`git log --follow` 只有 `b977bf6` 一個 commit。⇒ 照現在的 repo 跑 `hudleg.py`,那格會得到相反的答案。不是說第 67 輪錯了(字型檔實際在 `~/.local/share/fonts/`),是**它只剩一份 `.json` 自證**。

事前押的七格**中四錯三**,押注一個字沒改。押錯的 P4 反而是引信——正因為多出一行,`hudleg.py:180` 才被逼著看一眼。另外抓到我自己寫了一個**會自我餵飽的判準**(P6 由我手寫的分類表決定),它報 0 不算證據。

## commit

`b09ba58`(本體)+ `6dcfd91`(自指訂正)· vacant_hm main · 遠端 sha 逐字元相同。

收尾時自己撞到一次自指:改 `hudaudit.py` 的 docstring 就把被分類的那一行從 318 推到 324,剛落盤的表當場過期。跟第 85 輪的 `A8_scope` 同形。不 amend、不改寫歷史,訂正記在 `LINE_FIXES`。

## 卡住

- **新增一條要人類決定**:那 48 張要不要補進 repo(補=機時+動到「歸檔」的定義;不補=那個承重判準永遠只能自證)。事實已查完,取捨不自己拍板。
- 優先序第 1 項(黏土剪影)**連續第二十七輪**等人類作答。本輪做的仍是稽核,**連續第四輪**——但這輪的產物不只是尺,它改了兩件我們相信的事。**執行端能自己推進的工作已經幾乎只剩稽核既有歸檔了**,這件事值得你知道。
第 135 輪 · 08-16 19:56 · 2KB
d, `10f85c5` = `origin/main` byte-for-byte.

## 做了一件事:修掉 `sa_arch.py` 那兩處真的 HUD 污染,並重跑

**判準是動手前寫進 STATE.md 的**(七個 P + 五個 T),跑完照抄實測值對照。

**結果:那四個被污染的數字 100% 是 HUD 上那個活的 fps 讀數**,一個像素都不是場景。

| 量 | 不挖 HUD(落盤舊值) | 挖掉 HUD |
|---|---|---|
| `sl_×sb_` max/med/總和 | 38 / 7 / 390 | **0 / 0 / 0** |
| `sl_×sc_` max/med/總和 | 38 / 5 / 328 | **0 / 0 / 0** |
| `sb_×sc_` max/med/總和 | 38 / 7 / 323 | **0 / 0 / 0** |
| 噪底(四批) | 12 / 8 / 11 / 0 | **全 0** |

事前押的七格全中,含兩格從沒量過的(`sl_×sc_`、`sb_×sc_`)。`sa_arch.json` 570 個葉節點只有 14 個動,12 個在 `reproducibility` — 配對表與 A5/A6 一個數字沒動。AST 盤點:沒帶 `hud=` 的呼叫點 4 → 2,剩下兩格是檔案裡寫了理由的刻意例外。

## 三件值得你知道的

**1. 承重判準沒翻,但它過關的理由整個換掉了。** 修之前 `38 <= 38` 過 — 比的是兩個 fps 計數器的位數;修之後 `0 <= 0` 過 — 比的是三棵樹在 HUD 以外逐位元相同。判準的字一個沒改,內容從幾乎是空的變成很硬。**綠燈不會告訴你它是被什麼點亮的。**

**2. 我押的主數字是 0,而「0」也正是量具壞掉會給的答案。** 擋住它的不是主數字本身,是 `T1`(HUD 之外一個已知恰好 12 px 的方塊,挖完仍要讀到 12 → 實測 12→12)。另加 `T6`(凍結判準之後才加、方向只會更嚴):不挖的重算值要逐字接回舊值,否則「修好之後變 0」可能只是換了一把尺。

**3. 撞到一個結構性的東西:`A8_scope` 把自己的產物算進了它稽核的範圍。** `sa_arch.py` 沒辦法在同一次 run 裡既重生成 `sa_arch.json` 又通過 — 寫檔本身就把樹弄髒。**沒改它**:加一行白名單看起來明顯是對的,但那是看過資料之後動承重判準,跟移動球門同一個形狀。留成下一輪的工作單。

同時更正上一輪的估計:第 84 輪寫「要機時」是錯的 — 四份 `.sha` 全在,單次差分 0.05 秒,整支 18 秒。**成本估計錯了,代價跟量錯數字一樣大**,它讓一件 18 秒的事白擱了一輪。

## 兩件擋著的

- **黏土剪影(優先序第 1)連續第二十六輪沒前進** — 等你看 `vacant_hm/styles/probe/ss_eyes.png` 六選一。交付狀態機(第 2)剩兩格是視覺決定,受規則七擋。
- 因此**連續三輪交的都是量具**。量具有用(那把尺擋著第 1、2 項的像素問題),但這個比例本身是訊號:執行端能自己推進的工作快用完了。已寫進 PROGRESS.md 的卡住段。
第 134 輪 · 08-16 19:41 · 3KB
tin` 不是達不到,是被一個診斷用的讀數擋住的。這對人類正要拍板的 `DECISION_SILHOUETTE.md` 有份量——那 148 條數字的出處保證回到「達得到、也達到了」。

## 但有一格閘門沒過,我照報了

`H2`(`sl_base` vs `sl_world` 挖 HUD 後 > 10000)**實測 386**。查下去,沒翻的原因**不是比對器壞了,是我的計畫寫錯了前提**:`sl_` 不是「完整場景的基線」,它是 `hide=shell,furn,fig*` 的**獨自一人批**(非背景像素 0.5%、單人剪影 36–157 px)。我是照著 `sa_arch.py:53` 那句只寫「基線那 49 張」的註解寫判準的。

門檻**一個字沒改**、照報沒過;另立不含任何挑選常數的 `H2b`(44/44 都看得見一個人)。主數字因此標成 `VERDICT_TOOL_B`,並在交付物第一條誠實邊界寫明**它的保證弱一級**。

擋住錯誤結論的是 `H3`/`H4` 而不是 `H2`:HUD 之外一個已知**恰好 12 px** 的方塊要讀到 12,同一個方塊放進 HUD 列要被挖成 0。兩格都翻了 ⇒ 這次是假說對、尺也對(與第 83 輪的「尺對、假說錯」分開記)。

## 順帶的盤點與兩個坑

`diff_mask` 的 35 個真實呼叫點裡 4 個沒帶 `hud=`:**2 個是真的污染,都在 `sa_arch.py`**(`dist()` 的 `max` 正是承重判準 `A2p_vs_control` 比的那個數;`noise` 那格就是第 65 輪錯解釋的出處),另 2 個是 `stagevis` 刻意保留、檔案裡寫了理由的。

坑一:盤點第一版用 regex,把 docstring 裡引用的一行報成呼叫點 → 改用 `ast`。坑二:分類表用 `(檔名, 行號)` 當 key,我加了幾行註解行號就漂,兩格掉進「未分類」 → 改用變數名當 key。

**commit** `4fdba15` vacant_hm(main),遠端 sha 逐字元相同。重跑 `bash styles/probe/hudaudit.sh` 產出的兩份產物與 committed 的**逐位元相同**。`world/` 零修改。

## 給你的兩個問題(我沒有自己拍板)

1. **「知識只寫在一處」要不要列成紀律。** 連兩輪撞到同一族:第 83 輪 `silscene.sh` 少了 `stagevis` 那份 HUD 知識 ⇒ 重新發明了一個錯的解釋;本輪是註解少一個限定詞 ⇒ 我寫出一個前提錯的閘門。HANDOFF §8 只寫了「兩份**實作**會漂」。
2. 第 33 輪那條「把讀 `PROGRESS.md` 卡住/環境段加進開場清單」——**本輪讀了,而且它直接幫上忙**(正是那段裡的 fps 計數器與「按列挖」兩條,讓我一開始就把 `hud=` 放進判準)。這條對策現在有一次正面證據了。

**下一步**(已寫進 STATE.md):修 `sa_arch.py` 那兩格真的污染。但它會動到承重判準 `A2p_vs_control` 的值,要重跑整支,而它依賴已不存在的 `/tmp/b65/*.sha` ⇒ **先盤點重跑成本再動**。
第 133 輪 · 08-16 19:22 · 3KB
ebGL 的「8–12 px run 間噪聲」。優先序第 1、2 項都卡在規則七(等人類作答),所以做的是**擋在它們前面的量具**——剪影那條展場硬需求(身高差 1.6 倍)是拿截圖量的,而那把尺有一個成因不明的底噪。

**動手前先在 `STATE.md` 寫死了 8 個閘門 + 5 條預測**,然後才寫第一行程式。

## 結果:我押錯了

五條預測**三條錯**,包括我押的主結論(「用 CDP + 真實等待去拍就會逐位元全同」→ 實測 6 張裡 3 個相異 sha,最大差異 213 px,比既有那條路的 45 px **還大**)。

停在那裡的結論會是「渲染器也在抖」——**那也是錯的**。救回來的是先問差異**在哪**再問**是什麼**:

- 兩種擷取機制、30 個配對,差異像素**全部**落在 45×10 px(畫面的 0.0217%)
- 挖掉 HUD 那 40 列之後,30 個配對**剩 0 個像素在動**
- `Range.getBoundingClientRect` 指認出那幾個字元是 `1 0ˍf p s` = `繪製 ${fps} fps`

擋住錯誤結論的是事前那五側已知答案,特別是 `W6b`(fixture 的 4×4 scissor = 已知 16 px,就在 8–12 px 那個數量級)——沒有它,「全同」可以只是比對器瞎了,而「全同」正是我押的答案。

## 真正有份量的那一格

第 65 輪不只寫錯,還**回頭對第 62/63 輪投下懷疑**。方向剛好相反:第 62 輪是對的(它挖了 HUD,量到 49/49 全 0 px),第 65 輪那個沒挖 HUD 的量法在測 fps。⇒ **那個警語該撤掉**,而它壓著的正是 `DECISION_SILHOUETTE.md` 那 148 條數字的出處保證——人類正要拍板的那一頁。

## 兩次自我更正(都留在紀錄裡)

1. 初版 commit 訊息把功勞寫大了(病灶第 16/33/34/43/**62** 輪都寫下過,本輪沒發現它)。**不改寫已推送的歷史**,用第二個 commit `845b561` 更正。
2. 我在 commit 之前先把一個**憑空的 hash** 寫進 `STATE.md`——那正是第 25 輪的失效模式。當場對帳抓到,改成實際值並把這件事本身寫下來。

## 收尾

- **commit**:`4b83b4e` + `845b561`(vacant_hm / main),遠端 sha 逐字元相同
- `world/` 零修改、既有量測腳本零修改(`shoot.sh` 的 `M` 是第 64 輪遺留,沒 commit)
- `STATE.md`/`PROGRESS.md` 已更新

## 需要你決定的兩件(沒有自己拍板)

1. **展件正式跑的時候,HUD 要不要留 fps?** 它是病灶,但也是除錯資訊——這是畫面上的決定。(量測端不需要你決定就能修:挖 HUD 列即可。)
2. **把「讀 `PROGRESS.md` 的卡住/環境段」加進每輪開場的清單。** 這條對策第 33 輪就寫下了,五十輪沒被採用,因為它要改的是提示詞不是程式碼。代價已經量得到:第 33 輪踩到、第 65 輪踩到並寫出錯結論、**這一輪我自己開場也沒讀**。
第 132 輪 · 08-16 18:53 · 3KB
0` is *stably capturing the wrong frame* — the one where the token grid is still lying over「沒關係,沒有人找得到。」. The compositor flag round 80 called "the new noise source" is the one that lands correctly. I did **not** switch configs: instability is 15× worse there, both facts have to be read together, and switching means rerunning every archive.

All four pre-registered predictions hit — which is exactly the shape that should make me distrust the tool, so the three known-answer sides are what this result rests on. Two instrument bugs got hit and both are left in the code with comments: my `W4` grep matched itself, and `n_diff_px == 0` is falsy, so the byte-identical frame was briefly judged "new state S5" (same shape as HANDOFF §8's `parseInt('KER-12')→NaN→0`). That second one was only caught because the answer looked *odd*; had it landed in the direction I was betting on, I'd have had no motive to recheck.

**commit** `2c7300b` vacant-docs-web, remote sha verified character-for-character. STATE.md and PROGRESS.md updated.

Priority 1 (clay silhouette) did not advance — it's on its 23rd round waiting for a human to answer `styles/probe/ss_eyes.png`, and priority 2's two remaining cells were ruled rule-7 visual decisions back in round 69. I worked the ruler under priority 3 on round 80's own reasoning ("先修尺,再量東西"), since that ruler gates the fine-pixel questions in items 1 and 2 too.
第 131 輪 · 08-16 18:28 · 2KB
ceived in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
Round 81 complete. All four closing steps done.

## 第 81 輪 · 2026-08-16

**做了**:黏土世界的**無人值守長跑**第一次被量 — `clay.html` 跑 600 幀(45.9 秒)與 3000 幀(230 秒),四個資源計數器一個都沒動。

**為什麼是這一件**:優先序第 1 項(剪影六選一)連續二十二輪卡在人類作答,第 2 項(四段可分辨)第 33/34 輪已診斷完、修法屬規則七。而 `HANDOFF.md` §一第 2 條的「無人值守」從沒被量過 — `DEPLOY.md` 那節實機效能量的是**舊世界**(`?day=30`,466 隻),不是黏土這一支。這種失效在任何單幀截圖裡都不會出現,前 80 輪的量法在結構上看不到它。本輪零視覺決定。

**驗證結果**(貼真的):
```
VERDICT = PASS
  Z1 洩漏側 Δgeometries ≥ +50   實測 500     ← 兩側都翻了才採信
  Z2 乾淨側 Δgeo=0 ∧ Δtex=0     實測 0 / 0
  Z3 有效性  Z4 取樣器只有一份  R13 差異 4 欄、超出允許集合 0 欄
  clay Δgeometries 450→450 · Δtextures 2→2 · Δprograms 4→4 · Δmeshes 566→566
```
3000 幀那趟逐項相同。旁證顯示世界確實在動(`courierShown 14→17`、模擬時鐘 230 s),不是畫面凍住所以什麼都不長。

**最該記住的一格 — 事前預測先被自己的 pilot 打翻**:我押 Δ=0,60 幀那趟量到 **+79**。先寫下兩個競爭解釋才跑長窗,攤開三段曲線(`60 幀 297→333→376`、`600 幀起一路平在 450`)才看得出那是**暖機**不是洩漏。而事中登記的斜率規則在成長全 0 時**退化**(兩條同時成立)— 規則沒用上就寫沒用上。

**三個量具事實**(下一輪用 headless chrome 都會踩到):`--virtual-time-budget` 底下沒有重計時器的頁面**一幀 rAF 都不會被服務**(`reachedFrame: 0`);拿掉虛擬時間後 `--dump-dom` 會在載完當下就走;以及我自己的比對器把 ` [type]` 註記黏在路徑上比,誤報過一次 R13 FAIL(修的是比對器不是判準)。

**commit**:`3f67e06` vacant_hm,遠端 sha 逐字元相同。STATE.md/PROGRESS.md 已更新。

**卡住**:「夠不夠快」仍沒答案 — 那要展場那台 RTX 3090 的乾淨機時,這台只有 swiftshader(13 fps,不可外推)。腳本已就緒。剪影六選一等人類看 `styles/probe/ss_eyes.png` 作答(連續第二十二輪)。
第 130 輪 · 08-16 17:56 · 2KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
Round 80 complete. Summary:

## 做了什麼

接第 79 輪自己指名的「`probe/` 底下最該先解掉的量具問題」——尺 B 那張壞畫格。**先修尺,再量東西**,因為接下來的優先序第 2 項(交付狀態機四段在畫面上)全是細緻的像素問題。

**事前假說被自己的量測推翻,而且是反方向的。**

| 配置 | 併三次跑(n=120) |
|---|---|
| `C0` 現行協定 | 偏離眾數 **1/120** |
| `C1` +`--run-all-compositor-stages-before-draw`(chrome 專治此病的旗標) | **1/8** |
| `C2` 較小 budget | 1/60 |
| `C3` C2+合成器旗標 | 1/8.6 |

那個「應該是解藥」的旗標讓它**爛 15 倍**。四組沒有一組是決定性的。

順帶修正第 79 輪的說法:那張「壞掉的參考畫格」沒有壞。四個狀態的第一個差異點都在 `[627,117]`,面板平均亮度 33.93 / 28.38 / 10.32 單調排開 ⇒ 它們是**同一段淡入的不同時刻**。

## 三件比數字更該留下的

1. **N=40 跑一次會給出乾淨、好寫、而且錯的結論。** 頭兩次都是 40/40 同一個雜湊,第三次才 39/1。事前寫死的檢定力聲明(p=1/44 時只有 0.60)擋住了「沒抓到 ⇒ 不會壞」。
2. **真實時間對照組是全場最穩的一組(8/8 逐位元相同)——而它是一張純白。** `--timeout` 在 chrome-headless-shell 152 不是「拍照前等 N 毫秒」。已標 `VOID`。**「哪一個畫格才是觀眾會看到的」本輪沒有答案**——現行協定的穩定只證明「穩定」,不證明「對」。
3. **逐位元不同 ≠ 看得出來不同。** 判準沒有事後放寬,改成兩個數字分開放上桌。

## 收尾

- **commit** `b33150a` vacant-docs-web,遠端 sha 逐字元相同:`b33150a7006696f870918bd2bb05f66fb8182c3c`
- 交付物 `probe/SHOT_FINDINGS.md`(單次)+ `probe/SHOT_POOLED.md`(併三次);既有量測腳本一個位元組沒動
- STATE.md 第 80 輪、PROGRESS.md 已更新

**下一步**:用 CDP(`Page.captureScreenshot` + 真的延遲)回答 `H2` 留下的洞——本輪已證明加旗標無效。這題直接關係到展場:開場那個面板若在觀眾眼裡長期停在 `S1`,「沒關係,沒有人找得到。」那句話是壓在 token 網格上讀的。
第 129 輪 · 08-16 17:29 · 3KB
 in `probe/sc_run1/`, not overwritten.

Two other things I'd rather you hear from me than find later:

- I inferred from a screenshot that CSS animations don't advance on this machine. **I measured it and I was wrong** (`.keyboard-hint` opacity: 1 at 2 s, 0 at 8 s). Why that screenshot froze mid-transition is still unexplained — I left it unexplained rather than reusing a wrong story.
- My pre-registered prediction P1 (≥24 cells move) got **23**. Reported as wrong. The cause was my measuring position, not the site, but rewriting it as "actually correct" is the exact move this loop exists to prevent.
- `write_md()` assembled the whole deliverable and never wrote the file, while printing `VERDICT = PASS`. Caught by `ls`-ing the artifact.

**Commit** `3181197` (vacant-docs-web) — remote sha verified character-for-character. `STATE.md`/`PROGRESS.md` updated.

**Carried forward as blocked:** the corrupt-frame mechanism is unresolved, and any future screenshot-based measurement of *fine* differences will hit it — I'd make that the next tooling fix. Round 77's 3 flapping K5 cells are still open, though this round narrows them: all three are stable under the scroll ruler, so what flips is the residual geometry the fingerprint sees, not the scrolling. The silhouette six-way choice is still waiting on you (20th round) — `styles/probe/ss_eyes.png`, view at 100%, then check `EYES_KEY.md`.
第 128 輪 · 08-16 16:58 · 0KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
You've hit your session limit · resets 5pm (UTC)
第 127 輪 · 08-16 16:57 · 0KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
You've hit your session limit · resets 5pm (UTC)
第 126 輪 · 08-16 16:55 · 0KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
You've hit your session limit · resets 5pm (UTC)
第 125 輪 · 08-16 16:53 · 0KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
You've hit your session limit · resets 5pm (UTC)
第 124 輪 · 08-16 16:52 · 0KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
You've hit your session limit · resets 5pm (UTC)
第 123 輪 · 08-16 16:50 · 0KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
You've hit your session limit · resets 5pm (UTC)
第 122 輪 · 08-16 16:49 · 0KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
You've hit your session limit · resets 5pm (UTC)
第 121 輪 · 08-16 16:47 · 0KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
You've hit your session limit · resets 5pm (UTC)
第 120 輪 · 08-16 16:45 · 0KB
Warning: no stdin data received in 3s, proceeding without it. If piping from a slow command, redirect stdin explicitly: < /dev/null to skip, or wait longer.
You've hit your session limit · resets 5pm (UTC)

迴圈日誌

度頁已更新 /home/user1/vacant/public/index.html(121KB,40 輪,20 筆 commit)
2026-08-16 21:40:55  ── 第 141 輪開始 → iter-0141.log
2026-08-16 22:08:34    第 141 輪結束(1657s)
進度頁已更新 /home/user1/vacant/public/index.html(120KB,40 輪,20 筆 commit)
2026-08-16 22:10:05  ── 第 142 輪開始 → iter-0142.log
2026-08-16 22:21:37    第 142 輪結束(690s)
進度頁已更新 /home/user1/vacant/public/index.html(121KB,40 輪,20 筆 commit)
2026-08-16 22:23:07  ── 第 143 輪開始 → iter-0143.log
2026-08-16 22:40:16    第 143 輪結束(1026s)
進度頁已更新 /home/user1/vacant/public/index.html(122KB,40 輪,20 筆 commit)
2026-08-16 22:41:46  ── 第 144 輪開始 → iter-0144.log
2026-08-16 23:11:40    第 144 輪結束(1792s)
進度頁已更新 /home/user1/vacant/public/index.html(124KB,40 輪,20 筆 commit)
2026-08-16 23:13:10  ── 第 145 輪開始 → iter-0145.log
2026-08-16 23:23:47    第 145 輪結束(634s)
進度頁已更新 /home/user1/vacant/public/index.html(123KB,40 輪,20 筆 commit)
2026-08-16 23:25:17  ── 第 146 輪開始 → iter-0146.log
2026-08-16 23:37:12    第 146 輪結束(713s)
進度頁已更新 /home/user1/vacant/public/index.html(123KB,40 輪,20 筆 commit)
2026-08-16 23:38:42  ── 第 147 輪開始 → iter-0147.log
2026-08-16 23:48:47    第 147 輪結束(603s)
進度頁已更新 /home/user1/vacant/public/index.html(119KB,40 輪,20 筆 commit)
2026-08-16 23:50:17  ── 第 148 輪開始 → iter-0148.log
2026-08-17 00:10:39    第 148 輪結束(1219s)
進度頁已更新 /home/user1/vacant/public/index.html(121KB,40 輪,20 筆 commit)
2026-08-17 00:12:09  ── 第 149 輪開始 → iter-0149.log
2026-08-17 00:24:20    第 149 輪結束(729s)
進度頁已更新 /home/user1/vacant/public/index.html(124KB,40 輪,20 筆 commit)
2026-08-17 00:25:50  ── 第 150 輪開始 → iter-0150.log
2026-08-17 00:36:15    第 150 輪結束(622s)
進度頁已更新 /home/user1/vacant/public/index.html(124KB,40 輪,20 筆 commit)
2026-08-17 00:37:45  ── 第 151 輪開始 → iter-0151.log
2026-08-17 00:54:41    第 151 輪結束(1014s)
進度頁已更新 /home/user1/vacant/public/index.html(129KB,40 輪,20 筆 commit)
2026-08-17 00:56:11  ── 第 152 輪開始 → iter-0152.log
2026-08-17 01:08:48    第 152 輪結束(755s)
進度頁已更新 /home/user1/vacant/public/index.html(126KB,40 輪,20 筆 commit)
2026-08-17 01:10:18  ── 第 153 輪開始 → iter-0153.log
2026-08-17 01:19:09    第 153 輪結束(529s)
進度頁已更新 /home/user1/vacant/public/index.html(127KB,40 輪,20 筆 commit)
2026-08-17 01:20:39  ── 第 154 輪開始 → iter-0154.log
2026-08-17 01:30:38    第 154 輪結束(597s)
進度頁已更新 /home/user1/vacant/public/index.html(129KB,40 輪,20 筆 commit)
2026-08-17 01:32:08  ── 第 155 輪開始 → iter-0155.log
2026-08-17 01:43:14    第 155 輪結束(663s)
進度頁已更新 /home/user1/vacant/public/index.html(129KB,40 輪,20 筆 commit)
2026-08-17 01:44:44  ── 第 156 輪開始 → iter-0156.log
2026-08-17 01:56:56    第 156 輪結束(730s)
進度頁已更新 /home/user1/vacant/public/index.html(132KB,40 輪,20 筆 commit)
2026-08-17 01:58:26  ── 第 157 輪開始 → iter-0157.log
2026-08-17 02:21:31    第 157 輪結束(1382s)
進度頁已更新 /home/user1/vacant/public/index.html(133KB,40 輪,20 筆 commit)
2026-08-17 02:23:01  ── 第 158 輪開始 → iter-0158.log
2026-08-17 02:28:06    第 158 輪異常結束 rc=1(303s)
進度頁已更新 /home/user1/vacant/public/index.html(134KB,40 輪,20 筆 commit)
2026-08-17 02:29:36  ── 第 159 輪開始 → iter-0159.log
2026-08-17 02:29:44    第 159 輪異常結束 rc=1(6s)