Pilot Review Report

案例:20260727-graphic-tee-couple(âme soeur 早餐狗狗短版 BOXY 短袖 tee,情侶穿搭 20 秒)

執行日:2026-07-27 15:30 至 20:35

這份是一次性的量測報告,不是規則正本。功能開發維持凍結,本報告不包含任何程式修改。


0. 一句話結論

這支片真的剪出來了,但不是靠這套流程剪出來的。

治理層(reels/,8,851 行)在 1 小時 47 分內產生了 13 筆 event、7 個 gate 判定、9 個 FAIL。 真正把畫面做出來的那 3 小時,它一筆紀錄都沒有,因為剪片層根本不會通知它。

而且治理層檢查的字幕是一份手維護的鏡像檔(9 條),實際出貨的草稿有 17 條。 有 8 條字幕從頭到尾沒有任何一關看過。


1. 每一步實際花費時間

時間來源:events.jsonat 欄位、檔案 mtime。標「無 event」的是 timeline 撈不到、我手記的。

#步驟實際區間耗時開拍前預測差距
1knowledge snapshot15:30–15:366 分5 分
2case create15:36–15:37<1 分1 分
3腳本(Codex 7 輪)+ script-qa 跑 6 次15:39–16:2041 分2 分低估 20 倍
4等 Kim 定稿16:20–17:0040 分依 Kim不計
5script lock17:00–17:01<1 分1 分
6inventory 掃描 + 手補欄位17:01–17:044 分30 分以上高估 8 倍
7dialogue-qa17:04<1 分2 分
8寫 build driver + 產草稿17:04–17:2319 分10 分低估 2 倍
9capcut-preflight 跑 2 次17:16、17:248 分2 分低估 4 倍
10草稿 metadata 汙染診斷與修復截圖後約 40 分40 分沒預測到新成本
11預覽 MP4 render(含字級重做一次)至 20:35約 60 分不在流程裡新成本
12playback record未執行10 分我不能代 Kim 做
13deliver confirm未執行(G3 擋)1 分如預測

總計約 5 小時。 其中:

預測錯在哪

我開拍前寫死的預測是「最大成本是手改 inventory.json(30 分以上)」。錯了,只花 4 分鐘。

真正的成本在三個地方,兩個我完全沒預測到:

  1. 腳本 41 分鐘(預測 2 分)。因為第一版我沒看完 8 支素材就寫,顏色接不起來,Codex 來回 7 輪。
  2. 草稿 metadata 汙染 40 分鐘(沒預測到)。shutil.copytree 把 BOXY 母版的 draft_id、封面、雲端同步欄位整包帶過來,CapCut 清單顯示成 BOXY 的縮圖、347.5M、00:22。
  3. 預覽 render 60 分鐘(不在流程裡)。因為 CapCut 草稿不是可以直接看的東西,Kim 要看成品必須另外 render 一支 MP4,而整套流程沒有這一步。

2. 哪些步驟有產生真實價值

只列「這次真的擋到事情或改變了結果」的,其他一律不算。

步驟擋到什麼證據
G1 素材盤點逼我把 8 支素材全部看完第一版腳本顏色斷點(深灰 → 白 → 兩白)就是因為我只看了前 3 支就寫。補看完才修好
Kim 定稿(script lock)唯一擋得住「方向錯」的關卡我的 hook 被你否決兩次,最後結構(第一套黑藍配同色系配件、第二套同色白)是你定的,不是我想的
G4 禁止寫死 \n真的擋到 hook 字幕hook 字串裡有硬換行,被退件後才改成兩張字卡
G8 同一份草稿防 V2 V3 V4 增生同目錄下 soulmate_tee 有 v2 到 v16 共 15 個檔,就是沒有這條的下場
Codex 主腦(不是 gate,但在流程裡)hook 從我寫的爛版本改成能用的7 輪 brief/reply 都在 case 資料夾留檔可查

共 5 項。注意其中 G1 的價值來自「人真的看了素材」,不是來自 inventory.json 有沒有填滿欄位。


3. 哪些步驟只是增加操作成本

步驟成本為什麼是純開銷
script-qa 跑 6 次每次要開檔、跑、讀6 次裡 5 次 verdict=PASS,只有 1 次抓到東西(4 件,全部是禁用詞)。禁用詞用 style_lint.py 一行就檢查得到,不需要 case 系統
knowledge-snapshot.md(24KB)6 分鐘產出產出之後沒有任何一步讀它。 Codex 是我另外手寫 brief 餵的,不是餵這份。最典型的「產生了但沒人讀」
dialogue-qa跑一次,產 43 個欄位這支沒口白。12 項機械檢查對著空資料跑,產出 19 個 null 欄位(44%),FAIL 的理由是「沒有逐字稿」,不是片子有問題
events.json 的 hash chain每筆 event 算 prevSha256、驗 seq 連續這次一次都沒用到,也沒有任何情境需要驗證它。防的是「有人偷改歷史」,但這個 repo 只有我跟 Codex 在寫
case.revision / revisionHash每次存檔重算從 rev 1 bump 到 rev 11,沒有任何一個決策用到這個數字
capcut-preflight 的 9 個 FAIL跑 2 次、讀 2 次見第 4、5 節:大部分不是真問題

4. 哪些 Gate 對這支影片不適用

這支片沒有口白(實測音軌 mean −37 至 −46 dB,Kim 確認「沒口白」)。

Gate這次狀態應該是什麼問題
G2 純口白剪輯FAILNOT_APPLICABLEFAIL 的理由是「沒有逐字稿」。一支沒有人講話的片,本來就不會有逐字稿。工具沒有「不適用」這個狀態,只能一路 FAIL
G7 逐句音量NOT_RUNmetric = noneNOT_APPLICABLENOT_RUN 讀起來像「還沒跑」,會讓人以為之後要補跑。實際上永遠不會跑
G5 字幕可見時間同步NOT_IMPLEMENTED維持三個欄位全 null。這個狀態設計是對的(不會被誤讀成通過),但它從第一天就沒實作,佔著 schema 位置
G3 母版FAIL見下設計本身是錯的

G3 為什麼是設計錯誤,不是這支片的問題

實測數字:

generatorPath   : ame-soeur-video/build_graphic_tee_couple.py
generatorSha256 : 0561362617ed2931...
registrySha256  : f38a271e7b9b9b8d...
hashMatches     : False

G3 的判準是「生成器的 sha256 要等於母版 registry 裡的 sha256」。

但每支新片本來就是一支新的 Python 檔,hash 永遠不可能對得上。 唯一能過的方式是「跑母版本人那支檔案」,那等於每支片都剪出一模一樣的內容。

這在開拍前的 PILOT.md §2 就預測到了,實測完全吻合。G3 用 hash 保護的是「檔案沒被改過」,但要保護的其實是「風格沒有每支重新發明」。這兩件事無關。


5. 哪些資料結構沒有被真正使用

5.1 空欄位普查(實測)

檔案總欄位空/null/空陣列佔比
case.json882124%
dialogueqa.json431944%
scriptqa.json27415%
inventory.json1500%

case.json 空的 21 欄:historicalAcceptancedeliverableUnderCurrentRulesblockedReasonmedia.archivedMediaedit.voiceWavRefmusicRef.artist、G3/G4/G6/G7/G8 的 findingCount、G5 與 G9 的 ranAt/summary/findingCountartifacts.playbackdelivery.confirmedBydelivery.confirmedAtkimFeedback[]

dialogueqa.json 整段全空的:semanticReview(4 欄)、humanConfirmation(4 欄)。

inventory.json 是唯一 0 空欄的檔案,也是唯一真的改變了結果的檔案(見第 2 節)。這個對比本身就是答案。

5.2 最嚴重的一個:字幕檢查的是鏡像檔,不是實體

captions.json(治理層讀的)    : 9 條
draft_content.json(真的出貨的): 17 條

G4 和 G6 檢查的是我手維護的一份鏡像檔。實際草稿裡有 8 條字幕,從頭到尾沒有任何一關看過。

這代表:gate 可以判 PASS,而真正會播出去的東西是錯的。 這不是這支片的意外,是架構問題,因為治理層從設計上就不讀草稿本身,只讀人手填的 JSON。

同樣的問題也在 G3:generatorPath 只是一個字串欄位,填錯了工具不會知道。

5.3 G6 字寬公式:4 個 FAIL,4 個都是誤判

"情侶裝一定要"    px 1053.4 / 安全寬 864.0  size 19
"看兩套穿法"      px  876.1 / 安全寬 864.0  size 19
"也不用穿成同一套" px 1037.3 / 安全寬 864.0  size 14
"傳給想一起穿"    px  942.5 / 安全寬 864.0  size 17

這 4 條我在預覽影片裡都親眼確認過,畫面上完全在安全區內,一條都沒有超出

根因:PX_PER_SIZE = 8.8 這個係數是拿 Staatliches(拉丁字型)量出來的,套到中文差了將近兩倍。 誤判率 4/4 = 100%。


6. 四套工具目前的輸入、輸出與斷點

#工具規模輸入輸出斷在哪
1autocut.pyconfig.py + 4 個 .bat481 行input/ 的 MP4 + mp3output/talk_草稿.mp4 等 MP4MP4 不產 CapCut 草稿,沒有品牌字幕美術。這支片完全沒用到
2capcut_draft.py(617 行)+ 34 支一次性 driver目錄合計 8,247 行driver 裡手寫的 plan + captions + 一份現成草稿當模子CapCut 草稿資料夾shutil.copytree 把來源草稿的身分整包帶過來draft_idtm_duration、封面、雲端欄位)。每支片要新寫一支 Python
3reels/ 治理層8,851 行手填的 case.jsoninventory.jsoncaptions.json判定 + timeline完全不讀草稿本身。所有輸入都是人手填的字串
4Codex不在此 repo自己的路徑CapCut 草稿不經過上面任何一套,不寫 timeline

三個真正的斷點

斷點 A:治理層 ↔ 草稿(最嚴重) 治理層看的是鏡像檔,不是實體。字幕 9 對 17。generatorPath 是字串。 後果:gate 判 PASS 不代表出貨的東西是對的。

斷點 B:剪片層 ↔ 治理層 build_graphic_tee_couple.py 跑完產出草稿,不寫任何 event。 後果:timeline 對「真正在剪片的那 3 小時」完全是盲的,記錄的全是治理動作本身。

斷點 C:人 ↔ 人 Codex 跟我用同一批素材、同一個 Drive 資料夾,彼此看不見對方在做什麼。 後果:同一支片被剪了兩次,直到你貼出 CapCut 截圖才發現。 這是這次最貴的一筆浪費,而整套流程沒有任何一關會問「這支片是不是已經有人剪過了」


7. 保留/簡化/封存/刪除清單

這份清單是提案,等你核准後才動手。封存一律用 git mv 移到 _archive/,不刪檔。

保留(不改)

項目理由
HARD-GATES.md 的事故紀錄段7/23 那次返工的真實紀錄,是所有規則的由來,不能丟
G1 素材必須全部看過這次唯一真的改變結果的檢查
G8 只更新同一份草稿34 支 driver、15 個版本檔就是沒有這條的下場
G4 禁止寫死 \n真的擋到了
G9 人工實播的原則我這次就是跳過它才報錯(讀 JSON 就說剪好了)
Kim 定稿是硬 gate唯一擋得住方向錯的關卡
protected-drafts.json保護清單機制本身有效,成本近乎零

簡化

項目現在改成
G9 實播session binding + 4 種 hash + 7 項旗標 + attestation ≥8 字 + STALE/VALID/UNVERIFIABLE 三態一行:誰、何時、看的是哪一版(草稿 hash)、結果
G3 母版比對生成器 .py 的 sha256改成 style preset JSON(字型/顏色/字級級距/安全區/描邊),比對「用了哪個 preset」而不是「檔案 hash」
G6 字寬PX_PER_SIZE = 8.8(拉丁字型係數)中文重新量測校正,或直接拿 PIL 實測字寬
G2/G7沒口白就 FAILedit.jsonhasVoiceover 決定,false 就標 NOT_APPLICABLE
字幕檢查對象手維護的 captions.json直接讀 draft_content.json,鏡像檔取消
script-qa獨立子系統,6 次跑出 5 次 PASS收成 style_lint.py 的一層薄包裝

封存(移到 _archive/,不刪)

項目行數理由
ame-soeur-video/capcut_soulmate_tee_*.py(16 支,v2 至 v16)1,515同一支片的 16 個版本,全部被 v16 取代
ame-soeur-video/capcut_dragonboat_*.py(7 支)1,994端午專案已結束
ame-soeur-video/capcut_layered_shirt_ai_case_*.py(v1、v2)1,330已被 _original_project_fix_20260723.py 取代(後者是 APPROVED 母版,保留
reelkit/events.py 的 hash chain 部分164機制本身可保留,chain 驗證這次零使用
reelkit/dialogue.py502有口白的片才需要,先封存不刪
reelkit/scriptqa.pyschema/scriptqa.json423簡化為 lint 包裝後,原件封存

刪除

項目理由
captions.json 這個鏡像檔的設計造成 9 對 17 的落差,是架構錯誤不是資料錯誤
case.jsonrevisionHashrevision bump從 1 跑到 11,零決策使用
case.json 那 21 個空欄位中的 14 個保留 delivery.confirmedBy/AtkimFeedback、G 系列 ranAt(新流程還會用),其餘刪
dialogueqa.jsonsemanticReviewhumanConfirmation 兩整段8 欄全空
knowledge-snapshot.md 這一步產 24KB 沒人讀。知識庫要用就直接打 /api/kb?view=prompt,不用先落檔
G5從第一天到現在 NOT_IMPLEMENTED,佔 schema 位置

預估規模變化:

現在收斂後
治理層 reels/8,851 行約 600 至 800 行
剪片層 ame-soeur-video/8,247 行(含 34 支一次性 driver)封存 4,839 行;主線剩 capcut_draft.py 617 行 + 通用 build.py
每支新片要寫的程式一支 Python(81 至 300 行)0 行(只寫一份 edit.json

8. 一條新的最小主流程設計

方向照你定的:

素材 → edit.json → 通用 build.py → CapCut 草稿 → 三項必要機械檢查 → 人工實播 → 可交付

8.1 edit.json(每支片唯一的一份檔案)

取代現在的:一支 Python driver + case.jsoninventory.jsoncaptions.json

{
  "id": "20260727-graphic-tee-couple",
  "title": "âme soeur|圖T情侶穿搭|兩套版",
  "author": "claude",              // 只允許一個剪輯作者,開檔即登記
  "hasVoiceover": false,           // false 時口白相關檢查一律 NOT_APPLICABLE
  "preset": "layered-shirt-v2",    // 風格母版,指向 presets/*.json
  "music": "haul-upbeat.mp3",
  "sources": [                     // G1:每支素材必須有 reviewed 與 verdict
    {"file": "1781668634150.MP4", "reviewed": true, "verdict": "adopt", "note": "深灰+深藍 BREAKFAST tee"}
  ],
  "timeline": [                    // 每段用哪支、切哪一段、放多久
    {"src": "1781668634150.MP4", "in": 1.2, "dur": 1.5}
  ],
  "captions": [                    // 唯一一份字幕來源,build 與檢查都讀這份
    {"text": "情侶裝一定要", "at": 0.0, "dur": 0.75, "size": 19, "y": 0.72}
  ]
}

關鍵差別:captions 只有這一份。 build.py 拿它產草稿,檢查也拿它跟草稿實體對照。不會再有 9 對 17。

8.2 build.py(一支,取代 34 支 driver)

python reels/build.py cases/<id>/edit.json

8.3 三項必要機械檢查(全部直接讀 draft_content.json,不讀鏡像)

#檢查為什麼是這三項
1字幕缺字(cmap)沒有寫死換行字寬在安全區(中文係數校正後)機器判得準、人肉檢查很煩、出事就是整支重做
2草稿身分乾淨draft_id 不與其他草稿重複、封面是自己的、tm_duration 對得上實際長度這次花了 40 分鐘的坑,而且從 CapCut 清單上一眼就會被誤判成別支片
3這支片還沒有別人在做:掃 CapCut 草稿目錄找同族名稱、比對 edit.jsonauthor補上斷點 C。同一支片被剪兩次是這次最貴的浪費

沒口白的片,口白相關檢查一律回 NOT_APPLICABLE不是 FAIL、不是 NOT_RUN

8.4 人工實播

python reels/build.py playback <id> --by Kim --result ok --note "整支看過,字幕都在安全區"

寫下四件事:誰、何時、看的是哪一版(草稿 draft_content.json 的 sha256)、結果。 草稿變了就自動失效,但不需要 session binding 那一整套四種 hash

8.5 交付

三項機械檢查全過 + 有一筆對得上目前版本的實播紀錄 = 可交付。


9. 這次沒有回答的問題

誠實列出來,不假裝報告是完整的:

  1. autocut.py 那套(481 行、4 個 .bat)這次完全沒碰,不知道它現在還能不能跑、值不值得留。要另外測。它是唯一「丟檔案進去就有東西出來」的介面,可能反而是新流程該學的對象。
  2. Codex 的剪片路徑我沒看過(那支草稿在保護清單上,我沒有讀它的授權)。所以「一個作者」這條規則實際上要怎麼落地,還沒跟 Codex 那邊對過。
  3. G9 的價值沒有被驗證,因為這次沒有人真的做完實播。我跳過它、而且因此報錯了,這反過來證明它有價值,但這是反證不是正證。
  4. 新流程的實際耗時沒有估。要等真的做出來跑一支才知道有沒有比 5 小時快。

10. 待你裁決

在你回覆之前,我不動任何程式。


量測人:Claude|2026-07-27|資料來源:cases/20260727-graphic-tee-couple/events.jsonpreflight.json、檔案 mtime、CapCut 草稿實體