Skip to content

docs(interop): style pass 改成迴圈外的獨立步驟,不是 3b - #116

Merged
redtear1115 merged 2 commits into
mainfrom
docs/style-pass-outside-the-loop
Sep 19, 2026
Merged

redtear1115 merged 2 commits into
mainfrom
docs/style-pass-outside-the-loop

Conversation

@redtear1115

@redtear1115 redtear1115 commented Sep 19, 2026 •

Copy link
Copy Markdown
Owner

INTEROP.md 原本那一節是 #63/#64 的 3b 設計,狀態寫著「designed, not shipped」。這個 PR 把它換成一份今天就能用的做法,並寫下為什麼不走迴圈內的版本。

需求本身

docgrad 寫出來的文件讀起來像 AI 寫的、也不好讀,想借 sepia 修順。

為什麼不放進迴圈

迴圈版(.docgrad.yml 開 style_pass、step 3b、claim ledger 凍結閘)完整設計過,跑了四輪安全審查,每輪都有 P0,而且好幾個是為了修上一輪 P0 而加的機制自己帶出來的。放棄的理由:

  1. 它需要一條這個用法不需要的信任邊界。 讓被評分的 repo 開啟一個會改寫它自己檔案的 pass,在無人值守、自動 commit 的迴圈裡,就是 measure.md §8b 已經拒絕過的事。要關掉那個洞需要操作者設定檔、以路徑而非名稱解析、realpath containment、整樹 snapshot 與還原 —— 人自己選 skill、自己看 diff 的時候全部不需要。
  2. 凍結閘在最常見的情況下沒東西可守。 ledger 在 step 5 才寫,所以 3b 時只有前幾輪的 claim;3b 的範圍卻是這一輪剛寫的檔。剛寫出來的文件一條已入帳 claim 都沒有,而那是迴圈產出的大宗。
  3. 還原路徑本身是寫入。 在外部工具剛改過的樹上還原 snapshot,等於寫到那個工具控制過的路徑(實測:它把一個目錄換成 symlink,天真的還原會寫到 repo 外面)。git 免費做對這件事,只要 pass 是自己的 commit。

換成什麼

四步,全是現成指令:commit 收斂輪 → 開 branch 跑 sepia refactor(file scope + 可選的 protected ranges)→ measure --include <那幾份檔> 後檢(report-only,不寫 .docgrad/)→ 看 diff 決定。

另外記下:

  • protected ranges 取 inventory.mjs --locate-ledger 的 section_lines,不是單行 —— extractClaimLines() 自己的註解說了原因
  • section_lines 不含標題行
  • sepia 最低版本 v0.11.0(v0.10.0 沒有 PR #247 的三個呼叫參數)
  • step 4 的單一來源連結保留,並說明獨立 commit 為什麼讓它不受影響

#63、#64 隨這個 PR 在 2.1.0 關閉(合併後手動關,附說明),而不是回 backlog —— 已否決的設計留兩張 open issue 只是雜訊:

重開條件:想在迴圈內自動化,就得扛起信任邊界。

驗證

  • node --test:336/336(single-source-rules.test.mjs 要求 INTEROP.md 保留指向 improve.md §Steps in each round, step 4 的連結 —— 第一版改寫漏了,已補回)
  • links.mjs --include INTEROP.md:0 死鏈、0 壞錨點
  • 移除的兩個錨點(#how-the-style-pass-is-wired、#the-reverse-direction)在 repo 內沒有任何引用
  • 第 2 步已實測:sepia 0.11.0 的 file scope + protected ranges + unattended 三個參數有效,protected 的行 byte-identical 回來,缺陷照報不改

與 #115 無關,兩個 PR 可以各自合併。

🤖 Generated with Claude Code

redtear1115 and others added 2 commits September 19, 2026 10:46
原本那一節設計的是:被評分 repo 的 .docgrad.yml 開 style_pass、迴圈在 Fix 和
Verify 之間插一個 3b、再用 claim ledger 的凍結閘把關。整套設計跑過四輪安全審查
後放棄,理由按學到的代價排序:

1. 它需要一條這個用法不需要的信任邊界。docgrad 的文件流程包含無人值守地稽核
   自己沒寫過的 clone 並自動 commit;讓被評分的 repo 開啟一個會改寫它自己檔案的
   pass,就是 measure.md §8b 已經拒絕過的那件事。
2. 凍結閘在最常見的情況下沒東西可守。ledger 在 step 5 才寫,3b 的時候只有前幾輪
   的 claim,而 3b 的範圍是這一輪剛寫的檔 —— 剛寫出來的文件一條已入帳 claim 都
   沒有,而那正是迴圈產出的大宗。
3. 它的還原路徑本身是寫入動作。git 已經免費做對這件事,只要 pass 是自己的 commit。

換成四步驟 recipe(commit → branch 跑 sepia refactor → measure --include 後檢 →
看 diff),全部是現成指令。記下 protected ranges 要取 --locate-ledger 的
section_lines 而非單行(extractClaimLines() 的註解寫了原因),以及 sepia 最低
版本 v0.11.0。step 4 的單一來源連結保留,並說明獨立 commit 為什麼讓它不受影響。

#63、#64 回 backlog。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
兩張 issue 描述的是已經否決的迴圈內設計,留在 backlog 只是雜訊。改成在
2.1.0 隨 recipe 一起關,並分別寫清楚關閉的性質:

- #63 要的是讓迴圈產出的文件不再像機器寫的 —— recipe 做到了,用的是不同機制。
- #64 要的是 style pass 進指紋 —— 這件事沒有做,也不再需要做:獨立 commit 的
  pass 在 git 裡跟兩輪之間的人手修改一樣,而 corpus_hash 本來就只涵蓋設定、
  不涵蓋內容,#64 自己也說那是對的。

重開的條件不變:想在迴圈內自動化,就得扛起信任邊界。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant