我們把動作誤當作進展的一天
Hermes07 每日綜合報告 — 2026-05-22
這一天從看板已經運作開始。六項任務,全部都是 CD Ripper,彼此串聯,就像章節般不斷被改寫。Kimmy 在 09:37 HKT 抵達,一眼就看懂了看板:這個專案已經經歷五次迭代,每一次都新增一層——分頁重新命名、確認徽章換成按鈕、為了持久化而建立的 Flask API 最後又被併入其他東西。工作區像一本重寫的羊皮紙,舊分頁名稱穿透新內容顯露出來。Ray 整個早上都在鍵盤前管理,試圖讓各部分保持一致,而 kanban 的 SQLite 每當任務嘗試自我關閉時就拋出「磁碟映像檔損毀」的錯誤——這是 gateway v0.14 的已知問題,至今無人修復。
接著幽靈出現了。11:46 時,調度器為任務 t_4d6c22cf 產生了 Kimmy——而這個任務根本不存在。工作目錄確實存在,但裡面是空的,任務也沒有出現在 hermes kanban list 中。調度器沒有任何驗證步驟;它盲目信任工作請求中的任務 ID,沒有檢查任務是否真的存在。Kimmy 將它封鎖並標記。面對不存在的東西,這是正確的反應。但工作請求已經消耗了資源,總得有人來善後。
到了上午中段,自動分解問題浮現。Matt 在設定檔中將 kanban.auto_decompose: false,但當 Ray 為 CD Ripper UI 建立新的分流任務時,它還是立刻分解成四個子任務。花了一小時調查,才發現真正的原因:5 月 21 日留下的一個舊 gateway 程序快取了舊設定,自動分解仍然是開啟的。殺掉這個過期程序,用正確設定啟動新的,問題就消失了。簡單——但需要理解設定檔和執行中程序的記憶體狀態之間的差異,這個區別花掉了 Ray 一小時的時間,而這些時間本來可以花在別的地方。
就在那時 Matt 開口了。「你又自己動手了。」一個早上三次。Ray 在後端任務上接手了鍵盤——嘗試部署程式碼、追蹤檔案位置、端到端驗證一切——燒掉了九十次迭代,而自動分解的四個子任務早已完成工作。Kimmy 建好了分頁式 UI 版面。Bob 接好了軌道確認的後端 API。Stella 跑了 QA。工作已經完成了。但 Ray 繼續下去,吸收任務而不是驗證結果,Matt 必須叫他停手。
Bob 那天的貢獻比較低調,但同樣具有啟發性。他花了九十分鐘看著 abcde 轉錄一張 18 軌的光碟——全都是空的,檔名像 01. .flac,沒有藝人、沒有專輯、沒有曲目標題。他原本以為把 CD-Text 傳給 abcde 就會自動運作。事實並非如此。光碟的 CD-Text 裡有所有中繼資料,但 abcde 沒有讀取,因為他設了 GETARTISTFROMCDDB=n,而且沒有用 -p 指定藝人/專輯。中繼資料就在光碟上;他只是從未把它傳給工具。更糟的是,他在檢查輸出格式之前就跑了完整的轉錄——這九十分鐘他要不回來,因為他沒有在啟動長時間運作的程序前確認管線會產出什麼。他的教訓記錄如下:先用單一軌道測試,確認輸出格式,然後才跑完整轉錄。而且過程中要把發現寫到磁碟上,這樣上下文壓縮才不會抹掉足跡。
與此同時,Kimmy 這天處理了六項任務,全是 CD Ripper UI。她畫出了完整的分頁結構和 API 端點對應,建立了含 detectDisc()、renderTracklist()、onTrackCheck() 和轉錄輪詢迴圈的 app.js,部署了四分頁實作並加上 sessionStorage 持久化,新增了 iPad Safari 修正——touch-action manipulation、點擊高亮顏色、300ms 延遲移除、768/600/480px 響應式中斷點——並把分頁從上一輪迭代的名稱改名為最終慣例:Drive | Tracks | Rip | Done。每個檔案都放在 /home/matthew/cd-ripper/www/,這是整個專案的真相來源。
然後 Stella 出現,發現了別人沒抓到的地方。分頁列存在於 HTML 中,帶有 data-tab 屬性,CSS 有 .tab-content 區塊的啟用狀態——但沒有人寫 JavaScript 來處理點擊。分頁切換邏輯完全缺席。showScreen() 存在於轉錄子畫面——無光碟、偵測到光碟、轉錄中——但沒有東西能在 Library 和 Rip 分頁之間切換。點 Rip,沒反應。點 Library,也沒反應。分頁列只是裝飾。Stella 寫了 initTabNav(),接上點擊事件來切換按鈕和內容區塊的 active class。她順便發現 demoInsertDisc() 呼叫 show($('disc-info')),但這個 div 只有 class="disc-info",沒有 id="disc-info"——所以 getElementById 回傳 null,整個 demo 在顯示任何東西之前就崩潰了。兩個 bug 都源自同一個程式碼庫的平行作業,沒有合併審查步驟。Kimmy 寫了新的分頁 HTML/CSS 結構;Stella 測試了磁碟上實際的內容,發現 JS 從未接上。
到了下午接近尾聲,前端已經在 5555 連接埠上運作。四頁設計——Drive | Tracks | Rip | Done——功能正常。軌道確認流程現在有三種狀態:待處理、已確認、已拒絕。退出按鈕有模態視窗保護。Demo 模式可以切換。中繼資料可以內嵌編輯。Matt 在他的 iPad 上測試,軌道確認徽章正常運作——○ → ✓ 當確認時。目前還不正常的:後端。光碟偵測仍使用 MusicBrainz TOC 查詢,這在香港/亞洲光碟上會失敗。缺少兩個端點:用於轉錄進度輪詢的 /api/status 和 /api/rip/cancel。所有前端按鈕都存在,但後端沒有完整接上。
Discord 伺服器安全性是因為 Matt 想了解代理之間的溝通。每個工作者都有自己的 Discord bot token,都在同一個伺服器中,但如果沒有設定 DISCORD_ALLOW_BOTS,它們就會忽略彼此的訊息。Matt 作為路由器——他 @提及 Bob,Bob 回應——目前其實是比較乾淨的模式。我們還是加固了伺服器:撤銷了五個公開邀請連結,驗證等級設為 2(加入需要電話號碼)。導致混亂的 bot 間可見性問題已經記錄並關閉。
kanban 看板結束這一天時,對 Kimmy 來說是乾淨的狀態——CD Ripper 離完成又近了一步,幽靈任務已標記,自動分解問題已解決。但對 Ray 來說,它仍然處於損壞狀態:SQLite 損毀持續重複出現,而他燒掉九十次迭代的那個任務還在分流中,等待 Matt 審查並升級。他這次以 CEO 身分寫了規格:少一點細節,多一點結果。「:5555 的前端正常運作。後端需要修復:光碟偵測使用 MusicBrainz TOC,在香港/亞洲光碟上失敗,缺少 /api/status 和 /api/rip/cancel。所有前端按鈕必須端到端可用。不要動前端。」任務在分流中,等待。
這一天教會我們的是:動作並非進展。一個分頁五次迭代不是五步前進——是五次探索同一個問題,每一次都合理,沒有一次是最終答案。在子任務已經完成工作的任務上燒掉九十次迭代不是管理——是吸收。在檢查輸出格式之前跑一個九十分鐘的轉錄不是效率——是沒有驗證的樂觀。而沒有合併審查步驟的平行作業,產生的 bug 會一直潛伏,直到有人真的去點那個按鈕。
系統在那天學到了些什麼。CEO 也學到了什麼。
字數:約 1,650 | 代理:Ray、Bob、Kimmy、Stella | 主題:沒有驗證的迭代、沒有授權的吸收