Skip to content

Audit #012 — Content Foundry (workflow sinh course content) ​

Audit chuyên đề cho xưởng sinh nội dung workers/foundry (SRC-632, SDD-027): Cloudflare Workflow LessonForge (WF-19), sổ model + AI Gateway, rubric máy, schema hợp đồng, và toàn bộ lớp chuẩn/tài liệu bao quanh. Không đặt thang điểm mới (lý do). Câu hỏi dẫn đường của chủ đạo SRC-633: hệ tự sinh, tự chấm, tự nâng cấp — thì cái gì đang giữ chất lượng của chính nó, và giữ ở những đâu?

1. Phương pháp ​

Rà bằng 11 agent theo 3 vòng: 5 chiều rà độc lập (ngữ nghĩa Cloudflare Workflows · độ lệch rubric↔chuẩn CD · chất lượng prompt · vận hành/governance · chuẩn và tài liệu) → mỗi chiều một agent phản biện mở lại đúng file, xác minh hoặc bác từng finding trên code thật → một agent soát độ đầy đủ tìm vùng chưa ai rà. Kết quả: 38 finding qua vòng phản biện (0 bị bác, 3 được chỉnh chi tiết) + 6 finding từ vòng soát = 44 thô — khử trùng lặp giữa các chiều còn 40 finding: 9 nặng, 17 vừa, 14 nhẹ. Mọi finding đều kèm bằng chứng file:dòng.

Sau khi sửa, chính bản sửa lại bị rà một vòng phản biện thứ hai (6 agent trên diff: đúng đắn code · test có đo đúng lời hứa · docs nhất quán) — ra thêm 12 finding (6 code, 4 test, 2 docs), sửa cả 12 trong phiên; chi tiết ở §4b.

2. Chuẩn so sánh (đọc từ chính chuẩn đang hiệu lực, không tự bịa) ​

ChiềuChuẩn đối chiếu
Ngữ nghĩa workflowHợp đồng step.do/retry/replay của Cloudflare Workflows; chính lời hứa trong comment của workflow.ts ("chạy tiếp từ chỗ hỏng", "đã trả tiền thì không trả lần hai")
Rubric ↔ chuẩnCD-7/CD-8, thang course A/B/C, bài học 7 vòng soạn tay trong skill /course-design (§5b-5g)
PromptCD-4/CD-6/CD-9 (những gì model PHẢI biết mới tuân được), khuôn JSON của course-content-to-sql.mjs
Vận hànhQG-004 (migrations), QG-010 (AI governance: gateway, prompt registry versioned)
Chuẩn & tài liệuNguyên tắc "sửa chuẩn: doc trước, code sau" (ghi ngay trong header lessonSpec.ts), sổ Content Standards, sổ workflow WF-xx

3. Phát hiện nặng nhất (9 🔴) ​

#Phát hiệnVì sao nặngTrạng thái
1Retry của Workflows là code chết: callModel nuốt mọi exception và trả {ok:false}, mà Workflows chỉ retry khi callback THROW — cấu hình retries chưa từng chạyMột cú nghẽn model 10 giây thành thất bại vĩnh viễn của trial, nhiễu thẳng vào bảng so sánh model — đúng cái lý do chọn Workflows bị vô hiệu ở bước đắt nhất✅ đã sửa
2content_runs kẹt running vĩnh viễn khi workflow chết giữa chừng hoặc LESSON_FORGE.create ném lỗi — chỗ duy nhất đổi status là step cuốiBảng admin đầy run "đang chạy" giả, không phân biệt nổi với run thật, số liệu so model thiếu hụt im lặng✅ đã sửa
3Schema cho phép check kind reflection, trái CD-7.4 (câu kiểm cuối bài phải máy chấm được) — zod, rubric, D1 cùng thảLesson máy sinh có thể mang toàn câu kiểm không chấm được: điều kiện "vượt lesson = qua câu kiểm" gãy✅ đã sửa
4Rubric thiếu bất biến đếm chỗ nhiễu (skill §5g: số misconception ≤ mcq×3, ≥1 mcq) — đúng cổng chặn cứng của audit-course.mjsDraft đạt 100 ở foundry vẫn chết cứng ở cổng hạ nguồn, phí trọn lượt sinh + tiền model; §5g là "nguyên nhân gốc của gần như mọi lỗ phủ"✅ đã sửa
5Brief không mang key concepts của unit nên model không thể tuân CD-4.4 (concepts ⊆ key concepts) — lỗi thiếu đầu vào, không vòng sửa nào cứu đượcDraft trượt đúng bất biến mà quy trình soạn tay kiểm trước commit✅ đã sửa
6Vòng sửa vứt bỏ toàn bộ Luật viết (system prompt một câu) và chỉ biết tên bài + tên unitBản sửa tái phạm giọng SGK / em dash / bịa link — chính hai kiểu hỏng mà prompt vòng sinh dựng lên để chặn✅ đã sửa
7Không stamp version của prompt/rubric vào R2 lẫn D1 — vi phạm QG-010 mà SDD-027 khai verified_byĐổi một tiêu chí rubric là điểm tuần này hết so được với tuần trước, và không dấu vết nào cho biết✅ đã sửa (0165)
8workflows.md khẳng định "chưa dùng Cloudflare Workflows" trong khi LessonForge đang chạy thật; không mã WF nào cấp cho nóTrang reference để debug đang nói ngược sự thật ở đúng câu cảnh báo in đậm✅ đã sửa (WF-19)
9Rubric 12 tiêu chí chỉ tồn tại trong code, không doc quality nào khai từng dòng + điểm — trái nguyên tắc "doc trước, code sau" của chính header fileCái máy sinh lặng lẽ là nguồn chuẩn duy nhất; muốn đổi ngưỡng không có doc nào để "sửa trước"✅ đã sửa

4. Phát hiện vừa và nhẹ (17 🟡 · 14 ⚪ — rút gọn, đủ bằng chứng trong code mới) ​

🟡 đã sửa trong phiên: PASS 90 trên thang có 44/100 điểm chết do schema bảo đảm sẵn (tái phân bổ còn 13, thêm L13-L16); outcome_seq ma qua được cả zod lẫn rubric lẫn audit B7 (superRefine + L12 chỉ đếm mối nối có thật); first hỏng hẳn vẫn đốt tiền vòng sửa với bản thảo rỗng (bỏ); TrialResult trộn ok của bản đầu với error của bản sửa thành dòng "ok=1 kèm error" (kế toán theo đúng nguồn phán quyết); max_tokens 4096 cắt JSON giữa chừng không tên lỗi (8192 + finish_reason); extractJson regex tham lam vồ từ { đầu tới } cuối (đếm ngoặc cân bằng); brief thiếu Misconception Map + lesson anh em (thêm cả hai); prompt gài bẫy schema (minutes: 0 vi phạm min(1), mẫu outcome_seq luôn 1); luật phủ CD-8 "câu kiểm viết NGƯỢC từ misconception" không có trong prompt (thêm); story.question bị rubric trừ điểm vì luật model chưa từng nghe (thêm vào prompt); gateway không metadata đối soát (thêm run_id/model_key/step); workflow.ts + index.ts 0 test (thêm 41 test — xem §6); thiếu dòng CS cho artifact "bản thảo máy sinh" (CS-11, sửa luôn QG-012 đang khai CS-01..CS-09 lệch từ khi có CS-10); bản thảo đạt không có đường được khai nào ra production (SDD-027 §7); không endpoint liệt kê run (thêm GET /runs + proxy admin); ước token 4 ký tự/token lệch đôi cho tiếng Việt và không phân biệt số đo với số ước (hệ số 2 + cờ usage_estimated, migration 0165).

⚪ đã sửa trong phiên: model chạy tuần tự dù độc lập (song song, wall time MAX thay vì TỔNG); judge() ngoài step làm replay đổi phán quyết khi redeploy (vào step cham:); R2 không lưu bản thô vòng sửa (lưu cả repair_raw/repair_score); rubric không bắt em dash dù prompt cấm (L14); misconception trùng nguyên văn error (L15); vòng sửa cùng nhiệt 0.4 với vòng sinh (0.15); chưa dùng JSON mode dù cả hai provider hỗ trợ (response_format theo cờ json_mode của sổ model); không trần chi phí (FOUNDRY_DAILY_USD_CAP, 429 khi chạm); thiếu upload_source_maps; Trace của course-design-standard không khai CD-8 đã có bản thi hành máy; problems/model_keys trả chuỗi JSON lồng JSON qua HTTP (parse tại biên); audit log foundry.run.start chỉ ghi số byte (thêm target_label + model_keys); vòng sửa chỉ được xem 12000 ký tự đầu của raw (đưa draft đã parse, raw nâng trần 20000).

📋 còn mở (ghi vào SDD-027 §6/§8): vòng judge bằng model thứ hai; nút duyệt trên admin; trừ điểm trùng nội dung giữa các bài (ba mục này vốn khai "chưa làm" từ SDD-027 v0.1, không thuộc 40 finding); đặt R2 lifecycle rule cho prefix foundry/ — việc làm tay trên dashboard, phần chính sách đã khai ở §8; cron quét run running quá hạn khi cả catch lẫn D1 cùng hỏng. Tổng kết: 40/40 finding đã xử lý bằng code hoặc chuẩn trong phiên; 1 việc tay còn chờ (lifecycle rule).

4b. Vòng phản biện thứ hai — rà chính bản sửa ​

Diff của đợt sửa được 6 agent rà lại (3 chiều × find + skeptic). 12 finding, sửa cả 12:

  • Code (6): model_keys trùng nhau lọt validate làm hai chuỗi step TRÙNG TÊN dùng chung cache và đè nhau trong D1/R2 (khử trùng ở cả hai biên); Workers AI không có finish_reason nên output cắt cụt lọt qua như ok:true (bắt thêm bằng usage.completion_tokens ≥ trần); tiền của lượt gọi HỎNG biến mất khỏi kế toán làm trần chi phí mù đúng kịch bản nó phải chặn (chi phí đi theo message của exception, parse lại ở catch); version stamp đọc hằng số module lúc replay nên redeploy giữa run làm stamp nói dối (đóng băng vào step phien ban đầu run); chính WRITING_RULES chứa một em dash làm mồi cho lỗi L14, và L14 phạt cả en dash mà luật chưa cấm (sửa cả hai phía); một model chết ở step chấm/lưu kéo Promise.all sập làm mất sổ D1 của mọi model đã trả tiền (catch theo từng model).
  • Test (4): index.ts chưa có test (thêm 9: trần 429, cap "0" tắt chốt, fail-open, create hỏng → failed + 502, parse tại biên); ống dẫn unitCtx brief→judge chưa được pin (thêm test concepts ngoài danh sách phải bị nêu tên); lời hứa "vòng sửa mang đủ brief" chưa được pin (assert big idea + problem cụ thể trong message vòng sửa); hàng đợi response của fake env dựa thứ tự gọi ngầm giữa các model chạy song song (đổi sang kịch bản THEO MODEL).
  • Docs (2): số học finding trong chính báo cáo này không khớp (đã sửa: 44 thô → 40 sau khử trùng); số test khai 20 trong khi thực tế khác (đã sửa thành số cuối ở §6).

5. Cơ chế giữ chất lượng sau đợt sửa — giữ ở NHỮNG ĐÂU ​

Trả lời thẳng câu hỏi dẫn đường: sau SRC-633, chất lượng của hệ tự-sinh được giữ ở bảy chỗ, mỗi chỗ một việc, không chồng nhau:

ChỗGiữ cái gì
1 · Prompt (WRITING_RULES + brief đủ ngữ cảnh unit)luật viết + thông tin mà thiếu nó model không thể đúng; dùng CHUNG cho sinh lẫn sửa
2 · Schema zod (lessonDraftSchema)hợp đồng hình dạng: JSON méo, mối nối ma, check kind ngoài CD-7.4 không bao giờ lọt vào phần còn lại
3 · Rubric máy L1-L16 (thang ở course-audit.md)điều kiện CẦN đo được bằng máy; bất biến đếm chỗ nhiễu chặn TRƯỚC khi tốn tiền sinh lại
4 · Vòng sửa có kỷ luậtchạy khi còn bất kỳ chỗ hỏng nào, nhiệt thấp, chỉ nhận khi thật sự hơn
5 · Version stamp (prompt_version + rubric_version, migration 0165)tính so sánh được của mọi con số theo thời gian — QG-010
6 · Cổng hạ nguồn (audit-course.mjs + người duyệt, SDD-027 §7)bản thảo đạt máy vẫn phải qua mắt người và qua audit course trước khi chạm learner
7 · Chuẩn thành văn (CD-8 Trace, CS-11, WF-19, rubric doc-first)phiên sau sửa chuẩn có đúng MỘT chỗ để sửa trước, máy không lặng lẽ định nghĩa lại chuẩn

6. Bằng chứng thi hành đợt sửa ​

workers/foundry: 56/56 test, 4 file (models 17 · rubric 15 · workflow 15 · index 9 — 41 test mới so với 15 ở HEAD), tsc -b sạch cả foundry lẫn api; migration 0165 áp dryrun sạch, chạy lại no-op; code chịu được cảnh code lên trước cột lên sau (INSERT đủ cột có đường lùi về khuôn 0164 — luật deploy của skill d1-migrate); npm run check:docs PASS. Toàn bộ finding-fix map ở §3-§4b; diff cùng commit với báo cáo này.