所有 P0 項目都通過後,才可宣稱「84 小時教材完成」。檔案存在不等於教學完成。
P0:課程結構
- [ ]
sessions/恰好有 28 個01-*至28-*章節目錄,編號連續且不重複。 - [ ]
course-allocation.json恰好有 28 章與 28 次授課;每次授課 180 分鐘,合計 5040 分鐘。 - [ ] 每章
durationMinutes可浮動,manifestschedule合計必須等於本章時數。 - [ ] 課次 segments 回加後與每章時數相等;全課程恰好有 28 段各 10 分鐘休息。
- [ ] 主講義使用
CHAPTER NN · NNN MINUTES,不把章節誤標成SESSION NN · 180 MINUTES。 - [ ] 每章都有
index.html、teacher-notes.md、practice-manifest.json、answer-map.md與學生可開啟的answer-map.html。 - [ ] 每章都有
starter/、checkpoint-1/、checkpoint-2/、solution/,且各自至少有index.html。 - [ ] 本機 HTML、CSS、JavaScript 與章節連結皆存在。
- [ ]
starter-downloads/恰好有 28 份與章節目錄同名的*-starter.zip;每章主講義的#practice都有帶download屬性的「下載 Starter ZIP」入口。 - [ ] 每份 ZIP 只有一個
NN-*-starter/頂層資料夾,其下包含初學者README.md與starter-project/;不包含 checkpoint、solution 或教材站步驟導覽。 - [ ] 下載版
starter-project/保留該章全部 Starter 檔案,並以本機assets/自包含載入共用 CSS、JavaScript 與 favicon;所有本機連結可在解壓後開啟。 - [ ] Starter ZIP 可重現建立:固定檔案時間、順序與 metadata 後,連續兩次重建的 SHA-256 必須與交付檔一致。
P0:Starter → Solution 教學合約
- [ ] 每個
TASK-NN都有且只有一個DONE-NN;兩邊編號集合完全相等。 - [ ]
practice-manifest.json的 tasks 與實際 starter TASK、solution DONE 集合一致。 - [ ]
practice-manifest.json是 observe 唯一來源;builder 只讀 manifest,不提供--sync-observe或其他回寫 observe 的能力。 - [ ] 四階段 HTML 的標籤結構、
id與class集合一致;class rename 教學只允許 manifest 明列的一對一改名,Solution 不得殘留舊名稱。 - [ ] 每個階段頁恰好有一個
<main>;每個同頁href="#id"都有目標。刻意失效連結只可用domContract.allowedMissingFragmentsByStage精確列出 stage/id,且不得保留無對應 href 或目標已存在的過期豁免。 - [ ] 主講義有醒目的四步流程;四階段頁都有相同 DOM 的進度導覽與上一步/下一步。
- [ ] 每個階段頁只有當前步驟使用
aria-current="step"。 - [ ] 四階段頁套用
practice-standard共用版型,保留各章原本作品main;頁面不產生pc-guide-summary、STEP GUIDE、dialog.pc-guide-dialog或「查看步驟說明」按鈕。 - [ ] 固定三任務章節的 DONE 集合不可漂移:Checkpoint-1 恰為
DONE-01,Checkpoint-2 恰為DONE-01、DONE-02,Solution 恰為DONE-01、DONE-02、DONE-03。 - [ ] Solution 不殘留
TODO、TASK-NN、待完成、請補等未完成標記。 - [ ]
answer-map.md與answer-map.html都必須恰好三列、每列恰好五欄;TASK ID、DONE ID、files、location、visibleResult 必須逐格精確等於practice-manifest.json,不得多列、少列或自行改寫結果。 - [ ] 所有學生可見 HTML 的
href都不直接指向.md。 - [ ] 第 15、16、20、21、23、24、25、26、27、28 章所有階段都不得把不可信輸入寫入 HTML sink:禁止
node.innerHTML/node['innerHTML']、node.outerHTML/node['outerHTML']、node.insertAdjacentHTML(...)/node['insertAdjacentHTML'](...)、node.srcdoc/node['srcdoc']、setAttribute('srcdoc', ...)、HTMLsrcdoc屬性,以及 jQuery.html()/['html']()。 - [ ] 真正負責動態渲染的第 20、21、24、26、28 章,其 Solution 必須使用
createElement、textContent、replaceChildren三種安全 DOM API。 - [ ] 根目錄
SESSION_TEMPLATE.md必須同步列出上述所有 sink;Solution 下一步固定前往../index.html#creation-challenge,不得跳到../index.html#evidence。 - [ ] Solution 只完成既定任務,不進行無關重構。
- [ ] 進階功能列在 manifest 的
extensions,不混入標準答案。
P0:初學者可授課性
- [ ] 每章開頭接住上一章或上一課次的成果,並說明本章要解決的畫面問題。
- [ ] 學習目標最多 3 項,而且描述學生能做出的結果,不只列技術名詞。
- [ ] 每章新術語以 4–6 個為上限;先用生活比喻,再接回網頁實作。
- [ ] 明列「今天必會」、「只需辨識」與「今天刻意不教」。
- [ ] 每章至少有一個可照順序排查的錯誤案例。
- [ ] 每章都有學生能操作、截圖或口頭解釋的成果證據。
- [ ] 缺課學生能從 checkpoint 接回,不必重新抄完整 solution。
P0:能力遷移與獨立創作
- [ ]
creation-path.json恰好有 28 章挑戰,每章與唯一的sessions/NN-*/index.html對應。 - [ ] 能力不倒退:01–06 模仿、07–13 改作、14–20 遷移、21–28 創作。
- [ ] 每章有獨特 summary 與 brief、至少兩個學生決定、禁止照抄邊界、至少兩項證據與解答政策。
- [ ] 每章恰好提供 3 層
<details>提示,預設不顯示完整做法。 - [ ] 第 13、20、28 章是能力關卡,必須交付自己的設計決策與可驗證成果。
- [ ] 第 26–28 章不提供「學生自選創作挑戰」的完整答案,只能提供規格、驗收條件、排錯順序或局部範例;既有 Solution 僅核對課堂固定 TASK,不得當作創作交件。
- [ ] 28 份主講義與 JSON 精確同步,挑戰區與
CREATION_PATH.html所有本機連結都存在。
P1:共同專案與回歸
- [ ] 每章說明成果如何合回共同作品,不把 28 章做成 28 個孤島。
- [ ] 第 13 章完成作品集整合與桌機/手機回歸。
- [ ] 第 14 章建立可檢查的 GitHub repo 與 commit history。
- [ ] 第 20–25 章都有外部服務失效時可使用的 mock 或教師備援資料。
- [ ] 第 25 章若採概念模擬,頁面與講義清楚寫「這不是真實登入」;若採真實 Auth,驗證 uid、Rules 與未登入情境。
- [ ] 第 28 章不預填假部署證據;工具只做格式預檢,最終由教師或同儕實際開啟 Production URL、比對 commit history 並觀看手機操作。
自動檢查
node tools/build-practice-step-guides.mjs
node tools/build-student-docs.mjs
node tools/check-course.mjs
node tools/check-practice-contract.mjs
node tools/check-learning-transfer.mjs
node tools/check-session-pages.mjs
node tools/check-starter-zips.mjs
自動檢查通過後,仍需教師手動走完 starter → checkpoint-1 → checkpoint-2 → solution,並用桌機與手機寬度檢查代表頁面。自動工具無法判斷生活比喻是否好懂、答案是否偷教新語法,這兩項必須人工審查。