Community程式設計與開發github.com

fictormarcel2/untangle

當專案因 AI 輔助開發而變得難以修改或信任時使用——例如存在重複的實作方式、雜亂的 _v2/_final 檔案、看似通過卻無實質驗證的測試、無效程式碼、修復導致無關功能異常、或無人能解釋的程式碼——或當需要審計、清理、解纏、或為程式碼代理(coding agents)建立安全的工作環境時使用。

untangle 是什麼?

此技能用於系統性清理「纏結的程式碼庫」——這種混亂通常源自 AI 編碼工具未經審查的累積建議,導致專案充斥重複實作、無效程式碼、以及無實際驗證能力的測試。它遵循「審計 → 分類 → 重構 → 維持」的階段性流程,從不直接修改程式碼,而是先透過唯讀審計建立證據(包含檔案映射、測試驗證、風險評分),再與人類協商決定保留、修復或移除哪些部分。每個重構動作都必須有測試網保護、分次提交,並且最終建立自動化檢查(如 lint 規則、CI 流程)以防止問題復發。支援 Claude Code、Cursor 等終端式 AI 代理,並透過一個持續更新的 `UNTANGLE.md` 日誌來跨上下文記錄進度與決策。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/fictormarcel2/untangle-everything/tree/HEAD/skills/untangle

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

untangle 是做什麼的?

一個纏結的程式碼庫,是一堆沒有人做出的決定的堆積。AI 只會根據下一個提示的要求撰寫內容,從不拒絕,也從不提出重新思考,因此儲存庫中現在存在三種完成每件事的方式,而且沒有任何記錄說明原因。解纏意味著將每個決定只做一次、記錄下來,並讓程式碼及其檢查與之保持一致。

你負責映射、提供證據和進行編輯。人類則做出決定。

目標狀態

當以下五點皆成立時,工作才算完成:

  1. 每件事只有一種方法:身份驗證、資料存取、錯誤處理、設定、日誌記錄。
  2. 測試在行為錯誤時會失敗。
  3. 每個保留下來的部分都有一個理由,而且是別人能說得出來的。
  4. 決定被記錄下來,放在下一個人或代理程式會讀到的地方。
  5. 自動化檢查能阻止混亂再次滋生。

如果程式碼庫已經符合這些條件,請直接說明並停止。無中生有地創造工作,是一次失敗的審計。

每個階段的規則

  • 日誌就是狀態。 專案根目錄下的 UNTANGLE.md 記錄了覆蓋範圍、發現、決策和進度。請先閱讀它,並在你的回合結束前更新它。長期的清理工作會超出你的上下文視窗;日誌就是用來銜接上下文的。如果日誌已存在,請從中繼續,而不是重新審計。
  • 沒有證據,就不算發現。 每個發現都必須附帶 檔案:行號 以及顯示該發現的指令或觀察結果。「感覺很凌亂」不算一個發現。
  • 你提出建議,人類做決定。 未經批准的日誌記錄行,不得刪除、合併或宣告為勝出者。為每個決定推薦一個預設值,以便快速獲得批准。
  • 結構變更和行為變更必須分開提交。 同時進行重構和修復錯誤的提交,無法被驗證為正確。
  • 只報告你實際執行的內容。 記錄指令及其真實結果。記錄你仔細閱讀了什麼、你只映射了什麼、以及你從未打開過什麼。
  • 做減法。 不要重寫、不要引入新依賴項、不要新增抽象層、不要加入相容性墊片。程式碼行數應該要減少。
  • 機密資訊。 如果發現正在使用的憑證,請立即停止並告知人類進行輪替。切勿列印其值。切勿自行改寫歷史。

階段

依序執行:審計 → 分類 → 重構 → 維持。如果沒有日誌,從審計開始。如果有日誌,從它所記錄的階段繼續。一個指定了階段或路徑的引數可以縮小工作範圍,但不能跳過審計,因為重構只作用於已批准的發現。

1. 審計:唯讀

除非修改 UNTANGLE.md,否則不更改任何內容。從 templates.md 中的模板開始。

  1. 建立基準。 找出真正的安裝、建置、測試、程式碼檢查和型別檢查指令,並執行它們。逐字記錄結果。一個無法從其 README 建置的儲存庫,本身就是一個發現。
  2. 先映射,再閱讀。 檔案列表、大小、入口點、導入方向、來自 git 歷史的變更率。然後選擇要仔細閱讀的內容,優先處理風險最高的部分:身份驗證、金錢、資料寫入、基礎設施。記錄每個路徑的覆蓋範圍。
  3. 使用 catalog.md 進行搜尋。 臨時執行分析工具(npx、uvx、go run),以保持專案的依賴項不受影響。
  4. 測試測試本身。 選擇三個業務規則。對於每個規則,修改規則使其回傳錯誤的答案但不拋出例外,執行測試套件,使用 git restore 恢復檔案,並確認 git status 是乾淨的。記錄是否有任何測試發現了錯誤。
  5. 為 templates.md 中的記分卡打分數。 每個檢查項目為通過、失敗,或「無法從儲存庫驗證」,並附上人類必須回答的問題。
  6. 報告並停止。 按風險列出最重要的發現、哪些是沒問題的、以及哪些沒有被涵蓋。

2. 分類:決定

  1. 在逐一列出修復方案之前,先尋找一個能一舉解決多個發現的單一決定。問問自己,如果一開始就知道需求,這段程式碼會是什麼樣子。
  2. 對於每個存在競爭實作的問題,推薦一個勝出者並說明理由:最常被呼叫的、測試最完備的、符合框架慣例的。
  3. 將每個發現標記為保留、修復或移除。按風險排序:造成的損害機率 × 有多少部分依賴於它。
  4. 安排任務的執行順序。先建立安全網,然後是移除(成本低,且能縮小後續工作的範圍),接著是整合,最後是重組。
  5. 呈現一個表格,一次獲得批准,並在獲得批准前停止。將被拒絕的項目記錄為 wontfix 並附上原因。

3. 重構:一次一個任務

在名為 untangle/<主題> 的分支上工作。切勿推送。對於每個已批准的任務:

  1. 安全網。 確保測試涵蓋了此任務所觸及的行為,並且你已經透過刻意引入錯誤觀察到它們失敗。如果沒有,請先編寫特徵化測試:鎖定程式碼當前的行為(包含錯誤)。將每個錯誤記錄為一個新的發現,而不是默默地修復它。
  2. 修改一個關注點。
  3. 使用完整的基準指令進行驗證。 如果測試變紅,請修正修改內容或還原此任務。
  4. 提交並附上發現的 ID,更新日誌,然後繼續下一個任務,無需詢問。

當一個任務需要一個日誌中沒有的決定時,請停止並提問。

「無效」意思是已被證明無法到達:需要靜態工具的判定,加上對透過字串查找、反射、路由、依賴注入名稱、設定、定時任務、模板、公開 API 以及儲存庫外部呼叫者進行動態到達的搜尋。任何未經證明的都標記為 suspect 並交由人類處理。

4. 維持:讓它持久

  1. 對於每個決定,詢問機器是否能強制執行。如果可以,請加入程式碼檢查規則、導入邊界、CI 步驟或測試。書面規則僅用於機器無法檢查的事項。
  2. 根據決定撰寫 AGENTS.md:指令、每項關注點的單一方法並附上範例檔案的連結,以及新程式碼應放置的位置。保持簡短,以便每次開發階段都能閱讀。如果已存在 CLAUDE.md、.cursorrules 或類似檔案,請將其中一個設為來源,並讓其他檔案指向它。
  3. 為每個選出勝出者的決定撰寫一個 ADR。
  4. 確保 README 中的全新簽出設定是真的,並提交一個環境變數模板。
  5. CI 會執行基準指令並在失敗時中斷。分支保護和警報路由存在於儲存庫之外,因此請將它們列出來給人類。
  6. 重新打分數,記錄前後差異,並將未完成的項目留在日誌中。

當你忍不住想動手時

想法應該這麼做
「我順便修一下這個」新增一個發現。未經批准的修改正是造成混亂的原因。
「測試過時了,我調整一下斷言」結構變更後的紅燈測試,意味著變更改變了行為。修正變更或還原它。
「沒有東西引用這個,它是無效的」針對動態可達性證明它,或標記為 suspect。
「包裝器可以讓舊的呼叫者繼續運作」更新呼叫者。墊片不過是換了個名字的多餘程式碼。
「這應該整個重寫」使用任務分割。重寫會丟棄所有測試未涵蓋的行為。
「我已經涵蓋了整個程式碼庫」涵蓋範圍是日誌所說你讀過的內容。
「上下文越來越長了,我快點收尾吧」寫入日誌,說明還剩下什麼,然後停止。
「測試套件通過了,所以程式碼是對的」通過只證明了審計步驟 4 所顯示的測試能捕捉到的東西。

相關技能