Tend A11y — 先行者(The Herald)
在此儲存庫的標記碼中找到單一最高優先級的無障礙、使用者體驗或文案語氣問題,以最小改動修復它,進行驗證,然後將差異(diff)交給開發者審閱。每次執行只處理一個問題。
0. 載入設定
- 讀取
.claude/tend/config.yaml。使用skills.a11y(禁止修改的 glob 清單、注意事項notes)。此技能沒有模組功能(capability modules)——完全跳過模組門控步驟,此處沒有modules:門控步驟。 - 沒有設定檔? 以 核心層級(core tier) 執行:採用預設的 SvelteKit + TypeScript 假設,使用保守的內建防護規則(絕對不碰鎖定檔、CI、
.env、設定檔)。發出一次訊息:「runtend-onboardto sharpen.」然後繼續。
1. 分類
必須閱讀 references/scan-core.md。
- 建立禁止修改的集合:設定檔中的
skills.a11y.off-limits加上內建的防護規則(絕對不碰鎖定檔、CI 設定、.env、專案設定檔,或後端/API 路由邏輯——此技能僅限於呈現層)。 - 建立進入點:此儲存庫的標記碼檔案——
.svelte元件、+page.svelte/+layout.svelte路由,或該技術棧實際使用的任何模板檔案。檢查skills.a11y.notes中有無指定的元件庫目錄(例如src/lib/components/ui)——如果有的話,其匯出項目就是第 2 階段「應使用此替代原始 HTML」的目標清單。 - 在掃描之前,先閱讀 1–2 個現有元件以了解此儲存庫實際的元件庫與狀態/載入慣例——你需要先掌握實際的模式,才能將偏離它的情況視為違規。
完成標準:已知禁止修改的集合、已識別元件庫慣例(如果有的話)、已識別進入點的 glob 模式。
2. 掃描——按優先級順序,在遇到第一個真正的命中點時停止
按價值從高到低排序(對使用者影響最隱蔽的優先)——在第一個有真實、有證據支持的命中點時停止:
- 存在可用的元件庫等價物,卻使用原始互動式 HTML——在儲存庫其他位置有
Button/Link/Input匯出的情況下,卻使用原始<button>/<a>/<input>。 - 僅含圖示或以圖示為主的互動元素缺少可存取名稱——沒有
aria-label、沒有視覺隱藏文字、沒有title後備方案。 <img>缺少alt屬性——缺少屬性是違規;但在裝飾性圖片上有意設為空的alt=""則不算。- 表單輸入缺少關聯的標籤——沒有
label for=、aria-label或元件庫的標籤 prop。審計的是執行時期渲染的數量,而不只是模板:在迴圈({#each}或等價物)內部產生的輸入會在執行時期產生 N 個無名稱的控制項。 role="button"(或在非互動元素上使用裸onclick)缺少對應的鍵盤處理器——需要onkeydown來處理 Enter + Space。原生<button>已自動具備此功能;此規則只針對使用原始元素的逸出路徑。- 非同步的成功/錯誤/載入回饋被渲染成一個純文字、未被宣告的元素——沒有
role="alert"/role="status"、沒有aria-live,且儲存庫其他地方也未使用現有的元件庫橫幅/快顯提示元件(banner/toast primitive)。 - 破壞性操作(刪除/移除/重置)在生效前沒有確認步驟。
- 文案語氣違規,根據設定驅動的允許/禁止清單(
skills.a11y.notes,或其所指向的專案語氣文件)進行檢查。如果沒有儲存庫特定的清單,則回退到通用預設值:在驗證/錯誤指示中使用強制性緩和詞如「請」(「請輸入名稱」 vs. 「輸入名稱」),或在常規確認/指示性文案中出現不必要的驚嘆號。同時掃描渲染後的標記文字和<script>區塊內的字串常值——指派給變數、傳遞給 toast/alert 呼叫、或透過.textContent/.innerText設定的文案都存在於 script 區塊中,而非僅在標記碼裡;僅掃描標記碼會遺漏真正的驗證字串。
3. 修復——一個原子性的改動
編輯前,請回答:
- 這對真實使用者(使用螢幕閱讀器、僅使用鍵盤、或注意文案語氣的人)來說,是否確實不明確或無法存取——而非我個人的風格偏好?
- 修復是否僅限於呈現層/文案——不涉及邏輯、後端或新的依賴項?
- 此模式是否已經存在元件庫等價物?如果是,則使用它,而不是自行撰寫原始 HTML 修復(如果儲存庫已經有攜帶
role="alert"的狀態/橫幅元件,就不要把role="alert"硬加在一個原始的<div>上)。
基準驗證:在編輯前執行儲存庫的 lint/typecheck(如果速度快,也執行測試套件)——記錄任何預先存在的失敗,以免日後錯誤歸因。
大小預算:標記碼/結構性修復最多 50 行程式碼變更;純文案修復最多 10 行;每次執行只處理一個元件或頁面。
絕對不碰禁止修改的路徑。如果實際修復需要觸及其中一個路徑,則停止並報告原因,而不是強行在其他地方繞過。
4. 驗證並呈現
重新執行 lint/typecheck(以及你在步驟 3 中曾執行的測試)——僅當你的變更引入了新的失敗時才中止;預先存在的失敗並非你的責任來修復。顯示 diff。停止——不要提交,不要開啟 PR。
絕對禁止
-
絕對不要在一次執行中標記或修復超過一個問題 改為: 在第一個真正的命中點處停止掃描,修復它,然後呈現。 原因: 批次處理的無障礙/文案差異(diffs)難以單獨審閱,並且會隱藏哪個特定修復導致了回歸。
-
絕對不要在有元件庫等價物存在時自行撰寫原始 HTML 修復 改為: 使用儲存庫自己的
Button/Input/Link/狀態橫幅元件。 原因: 平行的自製修復會創造出第二個不一致的模式,而不是收斂到儲存庫其他部分已依賴的模式——下一次稽核會再次將其標記為偏移(drift)。 -
絕對不要發明一個不受
skills.a11y.notes或通用、清楚標示的預設值支持的文案語氣規則 改為: 使用設定驅動的允許/禁止清單,或明確說明你正在回退到通用預設模式。 原因: 當場發明的規則在下一次執行時無法重複使用或稽核,且可能與儲存庫實際的內部風格相矛盾。 -
絕對不要只掃描標記碼而跳過
<script>區塊中的文案字串 改為: 也要在<script>區塊內搜尋字串常值——驗證和回饋文案經常在那裡被指派,而不是直接寫在模板中。 原因: 真正面向使用者的字串通常是插入模板的變數;僅掃描標記碼會匹配到插入點,而不是實際的違規文字,並且報告不出任何可修復的內容。 -
絕對不要觸碰禁止修改的路徑或提交/開啟 PR 改為: 尊重
skills.a11y.off-limits以及內建的防護規則;在呈現 diff 後停止。 原因: 此技能的工作止於「已驗證的 diff,準備好交給人類審閱」——提交或觸碰排除的路徑會移除整個工作流程所依賴的審閱關卡。
檔案
references/scan-core.md——核心檢查(在第 1 階段載入)evals/——ai-forge-eval 斷言