Sổ nguồn SRC-0225 tới SRC-0249
Một mảnh của sổ tiếp nhận. Chỉ CHÈN dòng bằng node scripts/src-new.mjs, không ghi đè cả file.
| ID | Ngày nhận | Nguồn | Canonical hóa vào | Trạng thái |
|---|---|---|---|---|
| SRC-225 | 2026-08-17 | Chỉ đạo: đổi label "Mục tiêu" thành "Điểm thi học kỳ" | App.tsx (thẻ trên trang Hôm nay + nhãn trang), GoalPage.tsx (tiêu đề), lang.tsx (EN: Term exam scores). "Mục tiêu" quá rộng — trang này chỉ nói về lịch thi và đích điểm của từng kỳ, không phải mọi loại mục tiêu của learner | ✅ |
| SRC-226 | 2026-08-17 | Chỉ đạo trang Luyện đề: bỏ nút "Đóng"; learner chọn 1 trong 4 cụm, hệ thống tự chọn trước theo thời điểm trong năm; learner cần xem được đã làm thử đề này bao nhiêu lần, kết quả ra sao | ExamPractice.tsx + endpoint GET /v1/learners/{id}/exam-attempts + 5 test cho termForMonth. Chọn cụm sắp tới chứ không phải cụm vừa qua (9-11 → giữa kỳ 1 · 12,1 → cuối kỳ 1 · 2-3 → giữa kỳ 2 · 4-8 → cuối kỳ 2): learner mở trang này để chuẩn bị cho kỳ trước mắt, mở sẵn cụm đã thi xong là mở nhầm việc. Chỉ hiện cụm đang chọn — bản cũ đổ cả 20 đề ra một màn, phải cuộn qua ba cụm không liên quan. Lịch sử làm đề lấy tách khỏi danh sách đề (danh sách là dữ liệu chung của môn, cache được); chỉ đếm lượt đã nộp vì lượt bỏ dở không phải một lần "đã làm đề này". Thẻ đã làm hiện "đã làm N lần · cao nhất x/10" (quy về thang 10 cho khớp điểm ở trường), thẻ chưa làm hiện nút "làm thử" chứ không hiện "0 lần · chưa có điểm". Không có "mastery của đề": mastery là của BÀI trong bản đồ kiến thức, một đề chạm nhiều bài — con số trung thực ở đây là điểm cao nhất và số lần làm | ✅ |
| SRC-227 | 2026-08-17 | Chỉ đạo trang Interactive Labs: bỏ link "Đường học", bỏ tiêu đề "Interactive Labs · Toán" và dòng "51 lab · vào xem cái nào cũng được…"; mỗi lab chỉ hiển thị tên | LabLibrary.tsx. Breadcrumb ở header đã nói đủ ba thứ (đang ở đâu · môn nào · quay lại bằng cách nào) nên nhắc lại ngay bên dưới là ba dòng không thêm thông tin. Thẻ bỏ dòng "kiểu tương tác · số câu kiểm tra" và dòng cảnh báo phần mô phỏng: ở danh sách 51 thẻ chúng thành 51 dòng chữ lặp gần giống nhau; chi tiết chuyển vào tooltip, learner biết ngay khi mở lab ra | ✅ |
| SRC-228 | 2026-08-17 | Feedback (ảnh bài Các tập hợp số): "xem hình này không hiểu gì cả", tìm cách minh hoạ khác. Kèm hai chỉ đạo nhỏ: thêm icon "exit" để thoát bất kỳ lúc nào ở màn Khám phá, và bỏ em dash trong câu "Chọn gì cũng được, không tính điểm — …" | explore/engine.tsx (kiểu vẽ mới nested) + 3 test. Hình cũ vẽ bốn nhánh toả ra từ vòng tròn "Số thực", tức là nói sai quan hệ: nó trình bày bốn tập hợp như bốn thứ ngang hàng và tách rời, trong khi thật ra chúng lồng nhau (N ⊂ Z ⊂ Q ⊂ R, còn I nằm ngoài Q nhưng vẫn trong R) — thêm nữa các nhãn nằm đè lên nhau nên đọc còn khó hơn. Hình mới là các khung lồng nhau, nói đúng ba điều cùng lúc mà không cần chữ: cái nào trong cái nào · vô tỉ ngoài hữu tỉ nhưng vẫn trong số thực · càng ra ngoài tập càng rộng; mỗi tầng kèm vài số ví dụ vì "0 1 2 3" nói nhanh hơn một định nghĩa. Cũng sửa hai câu chú thích còn nói "hai thanh" từ thời hình cũ của phân số (nay là hai hình tròn) | ✅ |
| SRC-229 | 2026-08-17 | Chỉ đạo: công tắc VI/EN phải ảnh hưởng tới tên các mục trong menu avatar | AvatarMenu.tsx + lang.tsx. Bốn mục trước đây viết cứng và lẫn hai thứ tiếng ngay trong một menu ("Profile · Xem hướng dẫn · Settings · Logout"); nay lấy qua t() như mọi chỗ khác, VI: Hồ sơ của con · Xem hướng dẫn · Cài đặt · Đăng xuất | ✅ |
| SRC-230 | 2026-08-17 | Chỉ đạo: học kỳ 1 bắt đầu 1/9, học kỳ 2 bắt đầu khoảng 15/1; dựa vào đó tính ra thời gian mặc định của các học kỳ | schoolYear.ts (mới) + 10 test. Hai ngày này là dữ liệu gốc duy nhất; bốn mốc kiểm tra tính ra từ chúng chứ không gõ tay từng tháng — gõ tay thì mỗi màn đoán một kiểu và sửa một chỗ là quên ba chỗ. Giữa kỳ rơi vào chính giữa kỳ học, cuối kỳ 1 rơi ngay trước ngày mở HK2, cuối kỳ 2 là ngày kết thúc năm học (31/5). Cụm đề mở sẵn = mốc sắp tới; nghỉ hè thì mốc sắp tới là giữa kỳ 1 của năm học mới (bản trước để cuối kỳ 2 suốt hè, không đúng nguyên tắc "cụm sắp tới") | ✅ |
| SRC-231 | 2026-08-17 | Chỉ đạo trang Luyện đề: đổi nút "làm thử" thành "xem thêm"; vào đề thì được XEM trước, có nút bắt đầu, bấm rồi mới chọn được đáp án; khi làm bài hiển thị icon từng câu để biết câu nào chưa làm | ExamPractice.tsx. Màn xem trước không chỉ là chuyện giao diện: bản cũ vừa mở đề là đã tạo một lượt làm bài, nên learner tò mò bấm vào xem rồi thoát ra cũng bị ghi "đã làm đề này" — con số lịch sử (SRC-226) sẽ nói sai. Nay start chỉ gọi khi bấm "Bắt đầu làm". Dãy ô câu hỏi dính trên đầu: ô đặc = đã chọn, ô viền đứt = chưa làm, kèm dòng "còn N câu chưa làm"; bấm vào ô nhảy tới đúng câu. Trước đó learner phải cuộn lại từ đầu và tự nhớ, bỏ sót một câu là mất điểm oan | ✅ |
| SRC-232 | 2026-08-17 | Chỉ đạo trang Luyện đề: mỗi đề nằm trên một dòng, bỏ "11 câu"; cần tín hiệu thể hiện learner đã làm đề này bao nhiêu lần | ExamPractice.tsx. Lưới 5 thẻ ngang bắt mắt đọc theo hai chiều, và mỗi thẻ nhắc lại "11 câu" trong khi cả cụm cùng số câu — nhắc năm lần không thêm gì. Một dòng một đề đọc thẳng từ trên xuống và còn chỗ cho tín hiệu. Tín hiệu số lần: mỗi lần một chấm, đếm bằng mắt tới 5; hơn 5 thì gộp thành số vì lúc ấy chấm chỉ còn là một vệt dài. Kèm điểm cao nhất quy về thang 10; chưa làm thì nói thẳng "chưa làm lần nào" | ✅ |
| SRC-233 | 2026-08-17 | Chỉ đạo thiết kế: tách hẳn Coverage và Mastery thành hai kênh. Coverage = "học được bao nhiêu" → progress ring tô dần, không cần hiện 4/5 hay %. Mastery = "biết tốt đến đâu" → chỉ dùng MÀU, dải màu mảnh ở cạnh trái card, 5 bậc đỏ → cam → vàng → xanh nhạt → xanh, xám khi chưa đủ evidence. Mục đích: một Unit có thể vừa "coverage gần đầy" vừa "mastery đỏ" | ProgressViews.tsx viết lại phần hiển thị + 5 token --state-mastery-0..5 + class .n12-mastery-edge + 11 test. Bản cũ trộn hai kênh vào một vòng tròn đặc: màu nói mastery, độ mờ nói coverage — mà độ mờ là kênh thị giác yếu nhất, cạnh nhau còn so được, đứng một mình thì không ai đọc ra "mờ 60%" nghĩa là gì; hệ quả là learner không bao giờ đọc ra được "đã học nhiều mà chưa hiểu tốt". Nay: cung tròn nói SỐ LƯỢNG, màu nói CHẤT LƯỢNG, một hình mang hai kênh mà không trộn. Bỏ luôn con số điểm in trên vòng (theo chỉ đạo "không cần hiện nếu không cần thiết") — số vẫn còn ở tooltip và ở nhãn cho trình đọc màn hình. Luật cũ SRC-205 ("chưa đo thì hiện ?, mờ hẳn") được thay bằng bậc xám: xám đứng riêng một bậc nên không lẫn với "rất yếu", và không cần dấu "?" nữa. Kiểm: cổng tương phản 148/148 đạt | ✅ |
| SRC-234 | 2026-08-17 | Chỉ đạo trang Luyện đề: bỏ tiêu đề "Luyện đề Toán · lớp 8" và bỏ tiêu đề cụm "Giữa kỳ 1 A1–A5"; thêm câu giới thiệu "Đây là khu vực luyện đề thi giữa kỳ và cuối kỳ, giúp con đạt 10 điểm trong sự ngỡ ngàng của cả gia đình" | ExamPractice.tsx. Breadcrumb ở header đã nói môn và chỗ đang đứng; thanh chọn cụm ngay phía trên đã nói đang xem cụm nào, còn mã đề thì in trên từng dòng — ba nhãn kia chỉ nhắc lại. Câu giới thiệu do chủ dự án viết, giữ nguyên giọng; bản EN dịch sát nghĩa chứ không dịch chữ | ✅ |
| SRC-235 | 2026-08-17 | Chỉ đạo tiếp về hai kênh: (1) hai nút bật/tắt riêng cho Coverage và Mastery, luôn còn tối thiểu một cái bật, bật cả hai thì hiện đồng thời; (2) không dùng viền trái card để nói mastery; (3) mastery vẽ bằng Mastery Continuum Bar — nét liền = phần đã chứng minh là ổn định, nét chấm = vùng chưa chắc/chưa đủ evidence; mastery càng cao thì nét liền càng dài, vùng chấm càng co. Không gọi là progress bar vì nó không nói "đã làm bao nhiêu" | ProgressViews.tsx + 1 test e2e. Dải chấm được chọn có lý do đúng như chỉ đạo: progress bar trả lời "đã làm được bao nhiêu phần việc" — đại lượng đếm được và chỉ tăng; còn mastery có thể TỤT khi learner quên hoặc khi có bằng chứng trái chiều, nên vẽ giống progress bar là mời learner đọc sai và khó chịu khi thấy nó ngắn lại. Phần còn lại để nét chấm chứ không phải mảng đặc: chấm đọc ra "vùng chưa rõ", mảng đặc đọc ra "phần chưa làm". Vòng coverage nay mang màu trung tính, không còn nhuộm theo mastery — để màu ở cả hai chỗ thì hai kênh lại dính vào nhau. Công tắc nhớ lựa chọn qua localStorage (hỏng thì về mặc định, không làm hỏng trang) và khoá nút đang bật một mình, kèm title nói vì sao — im lặng bỏ qua cú bấm thì learner tưởng nút hỏng. Class .n12-mastery-edge xoá khỏi Design System | ✅ |
| SRC-236 | 2026-08-17 | Chỉ đạo chỉnh kiểu hai kênh: Mastery Bar ngắn lại một nửa; Coverage Ring có dấu mục tiêu (ví dụ mốc 80%) để learner thấy luôn "còn cách mục tiêu bao nhiêu"; Mastery Bar chuyển tiếp mượt bằng gradient — đầu dải màu rõ, cuối tan dần vào pattern chấm | ProgressViews.tsx + 2 test. Dấu mục tiêu vẽ bằng vạch xuyên qua nét vòng, không phải chấm nổi trên vòng: vạch đọc ra là MỐC, còn chấm dễ bị đọc thành "đang ở đây"; vạch đậm lên khi đã qua mốc. Gradient thay cho mép cắt vì mức chắc chắn không có ranh giới thật — không có điểm nào mà bên trái là "chắc" bên phải là "không", vẽ một vạch cắt sắc là bịa ra một cái mốc không tồn tại. Bẫy kỹ thuật gặp ngay lúc làm: linearGradient mặc định tính theo khung bao của hình, mà khung bao một đoạn thẳng NGANG có chiều cao 0 nên gradient suy biến và cả nét biến mất — nhìn ra thì dải chỉ còn chấm; phải khai gradientUnits="userSpaceOnUse" | ✅ |
| SRC-237 | 2026-08-17 | Chỉ đạo: Mastery Bar dày lên gấp 3 | ProgressViews.tsx: nét 3 → 9 đơn vị, khung cao 6 → 12. Ở độ dày cũ phần chấm gần như biến mất trên màn thường, mà chính phần chấm mới là thứ nói "vùng chưa chắc" — tín hiệu quan trọng nhất của kênh này. Kèm một chỉnh nhỏ bắt buộc phải làm cùng: đầu nét chấm đổi từ tròn sang vuông, vì với nét dày 9 thì đầu tròn cộng thêm 4,5 đơn vị mỗi bên, mỗi chấm phình thành một viên thuốc dài và dải đọc ra như chuỗi hạt chứ không như vùng chưa chắc (trục ngang lại còn bị kéo giãn nên càng lộ) | ✅ |
| SRC-238 | 2026-08-15 | Chỉ đạo: tạo trang riêng so sánh môn Văn/Tiếng Việt ở cấp Curriculum giữa Building 21 · Việt Nam · IB (thứ tự trình bày: B21 trước, VN thứ nhì, IB cuối), kèm bảng Learning Package × Modules của cả ba hệ và kết luận: Nemo12 ghép competency backbone (B21) + conceptual layer (IB) + knowledge coverage (VN); curriculum không tổ chức theo "bài trong sách" nhưng vẫn phủ đủ kiến thức VN. Chủ dự án cấp ~50% dữ liệu, yêu cầu tự tra cứu bổ sung 50% | Pearl /ideas/curriculum-van. Tra cứu bổ sung: B21 ELA có 8 competency dạng câu "I can…" (thật: ELA.2 Expressing Ideas, ELA.3 Writing Arguments, ELA.7 Conducting Research), continuum ELA mức 6·7·8·10·12 theo dải Common Core, learner làm việc trong "vùng của riêng mình" độc lập khối lớp, đơn vị dạy = studio quanh một nhóm competency, framework mở tải về sửa được; GDPT 2018 đã là chương trình định hướng năng lực — trục chính là 4 kỹ năng đọc/viết/nói/nghe xuyên 3 cấp, kiến thức tiếng Việt + văn học hình thành QUA hoạt động chứ không dạy rời, chương trình "mở" chỉ quy định yêu cầu cần đạt từng lớp + kiến thức cốt lõi + 6 tác phẩm bắt buộc, nên phê phán "VN chỉ dạy kiến thức" là phê phán bản TRƯỚC 2018; khác biệt thật còn lại = đơn vị tổ chức vẫn là khối lớp; IB: MYP 4 tiêu chí A-D chấm riêng, DP có 3 areas of exploration (readers-writers-texts · time and space · intertextuality) + 7 concepts (identity, culture, creativity, communication, perspective, transformation, representation) → curriculum xoắn ốc quanh khái niệm, không tuyến tính theo thể loại. Trang ghi rõ bảng 6 package của B21 là bản dựng lại áp cho Văn tiếng Việt, không phải danh sách chính thức (framework thật sau đăng nhập); có mục Nguồn 12 link. Cảnh báo kiến trúc: cách ghép 3 tầng chỉ có nghĩa nếu có bảng đối chiếu coverage tra ngược được từ mọi yêu cầu cần đạt của CT VN tới ≥1 module | 🔵 docs xong, coverage matrix chưa xây |
| SRC-239 | 2026-08-17 | Chỉ đạo Toàn cảnh: Module cũng nằm trong card, viền cực mảnh và cực đen; viền Module, Package, Unit giống hệt nhau; tên Unit xuống dưới; Mastery Bar rộng gấp 150%; cụm "27 Toán" đưa tên xuống dưới và cho vào một card | ProgressViews.tsx. Một hằng số viền chung (CARD_EDGE) dùng cho cả bốn chỗ — ba tầng là cùng một loại vật thể ở ba cấp, viền khác nhau sẽ đọc thành "ba thứ khác nhau" và mắt phải học lại cách đọc ở mỗi tầng; thứ bậc đã nói bằng CỠ (vòng 56 · 44 · 36) nên không cần nói lại bằng viền. Tên xuống dưới ở cả bốn tầng (môn · Package · Module · Unit) để một cách đọc duy nhất: vòng + dải ở trên, tên ở dưới. Dải mastery 12 → 18px | ✅ |
| SRC-240 | 2026-08-17 | Chỉ đạo: viền thẻ đổi sang xám, thẻ đang chọn thì viền đen nhưng không được to hơn | ProgressViews.tsx: edgeStyle(selected) — cùng 1px, chỉ đổi màu (--border ⇄ --n12-ink-900). Bỏ ring-2 ở thẻ đang chọn: vòng ring nằm ngoài viền nên thẻ đang chọn phình ra, cả hàng bị đẩy lệch mỗi lần bấm, và mắt đọc ra "thẻ này khác loại" chứ không phải "thẻ này đang mở". Đổi MÀU nói đúng trạng thái mà không đụng kích thước | ✅ |
| SRC-241 | 2026-08-17 | Chỉ đạo: vòng Coverage cần có màu; số ở giữa nhỏ lại và thêm ký tự %; mỗi lúc chỉ chọn được một trong hai "Đã học" / "Mức vững"; cạnh dải mastery thêm số x/10 | ProgressViews.tsx + 4 token --state-coverage-1..4 + 1 test e2e viết lại. Vì sao trước đó nhìn ra "không có màu": vòng đang dùng thang ocean của Design System, mà thang này đã bị kéo về gần xám ở SRC-160 ("nhiều màu quá, tôi thấy kinh tởm") — đúng nhận xét của chủ dự án. Nay dùng một thang xanh dương riêng, vẫn là MỘT sắc đậm dần nên không đụng thang đỏ→xanh lá của mastery. Số trong vòng nhỏ lại (0,3 → 0,24 cỡ vòng) và có "%" cỡ nhỏ hơn nữa: % nói rõ đơn vị, cỡ nhỏ để con số không lấn mất chính cái cung — cung mới là thứ đọc lướt được cả hàng. Hai nút đổi từ bật/tắt sang radio một-chọn-một (đổi luật SRC-235): hai kênh trả lời hai câu khác nhau, bày cả hai trên mọi thẻ thì mỗi thẻ mang hai hình và mắt phải chọn đọc cái nào trước. Số x/10 cạnh dải cho khớp cách chấm ở trường; chưa đo thì không hiện số nào — in "0/10" ở đó là khẳng định sai (0 = đã đo và kém) | ✅ |
| SRC-242 | 2026-08-18 | Câu hỏi: thời gian hiển thị toàn hệ thống có bị sai không, cần tính theo GMT+7 | Có sai, và sai ở hai tầng khác nhau. (1) Hiển thị: admin in thẳng UTC kèm "Z" (09:36:44Z cho việc xảy ra lúc 16:36 chiều), learn/marlins/coral thì cắt chuỗi ISO (.slice(0,10)) — cắt chuỗi UTC nghĩa là mọi việc sau 17:00 giờ Việt Nam bị ghi sang ngày hôm trước. Thêm vnTime.ts (canonical ở packages/design-system/ui/, bản sao ở admin · learn · marlins · coral) dùng timeZone: "Asia/Ho_Chi_Minh" chứ không cộng tay 7 tiếng — cộng tay thì đúng hôm nay và sai khi múi giờ đổi hoặc khi đoạn mã bị copy sang vùng có DST. Sổ bằng chứng của admin ghi rõ (GMT+7) vì người đọc sẽ đối chiếu với log Cloudflare (UTC) lúc điều tra. (2) Tính toán ngày ở server — nặng hơn: active_days gom theo substr(occurred_at,1,10) tức cắt ngày theo UTC, nên học 22h tối và 1h sáng hôm sau bị gộp thành MỘT ngày; ba chỗ so exam_date >= date('now') cũng lệch, khiến kỳ thi diễn ra trong ngày bị coi là đã qua suốt 0h–7h sáng. Sửa bằng datetime(...,'+7 hours') ngay trong SQL. DB vẫn lưu UTC — một sự kiện chỉ có một mốc, chỉ đổi ở tầng đọc | ✅ |
| SRC-243 | 2026-08-18 | Chỉ đạo: vòng Coverage cần "nhiều màu", một sắc đơn nhìn hơi chán | ProgressViews.tsx + 5 token --state-coverage-1..5: tím → xanh dương → xanh ngọc → teal → xanh lá, mỗi bậc một SẮC rõ ràng khác nhau. Phân biệt bằng sắc dễ hơn hẳn phân biệt bằng đậm nhạt — nhìn cả hàng là thấy ngay khối nào đang ở đâu, không phải so từng cặp. Vẫn giữ nguyên tắc tách kênh: cả năm bậc nằm ở nửa LẠNH của bánh xe màu, không đụng dải đỏ → cam → vàng của mastery, nên hai kênh không bao giờ đọc nhầm nhau. Bậc cuối là xanh lá vì "gần xong" đọc ra xanh lá là tự nhiên. Đây là chỗ cố ý đi ngược luật gần-đơn-sắc của SRC-160 — luật đó nói về nền và chrome của trang, còn đây là kênh dữ liệu, nơi màu MANG THÔNG TIN chứ không phải trang trí | ✅ |
| SRC-244 | 2026-08-18 | Chỉ đạo (kèm ảnh câu "3/(x - 2)"): cần dùng thư viện để thể hiện công thức toán dạng này | Thư viện đã có từ SRC-219 (KaTeX), thiếu là ở NỘI DUNG: 2.160 câu viết bằng chữ thường nên không có gì để KaTeX vẽ. scripts/mathify.mjs (hàm thuần, 8 test) + scripts/mathify-items.mjs (chạy trên D1): quét 468 câu có ký hiệu toán, đổi 357 câu sang $…$. Bốn luật an toàn vì đây là sửa hàng loạt lên học liệu thật: chỉ đổi mẫu chắc chắn, không đụng chuỗi đã có $, kiểm lại số $ phải chẵn và phần chữ phải giữ nguyên (bảo đảm chỉ đụng ký hiệu chứ không mất lời văn), mặc định dry-run. Hai lỗi bắt được ngay ở dry-run đầu tiên — lý do bắt buộc phải chạy khô trước: (1) 51² − 49² bị dịch thành 5$1^{2}$ − 4$9^{2}$ vì cơ số bắt thiếu, tức sai hẳn nghĩa; (2) đơn vị đo m/s² bị bọc nửa vời thành m/$s^{2}$ đọc còn khó hơn để nguyên. Sửa: cơ số bắt trọn cụm \d+[A-Za-z]?, và bỏ qua khi trước cơ số là dấu /. Chạy lại lần hai ra 0 thay đổi (idempotent). Thêm 1 test e2e giữ đường: KaTeX vẽ ra phân số chồng và không để lọt $ hay \frac ra màn hình — kiểm bằng innerText chứ không bằng DOM, vì KaTeX luôn kèm một khối MathML ẩn chứa nguyên văn LaTeX | ✅ |
| SRC-245 | 2026-08-15 | Ba chỉ đạo: (1) gom curriculum các môn ra khu vực riêng; (2) tạo curriculum môn Toán theo cách đã làm với Văn; (3) chuẩn cấu trúc bắt buộc: mỗi môn 3-6 Learning Package, mỗi package 3-6 Module, mỗi module 3-6 Unit, mỗi unit 1-2 key concept; (4) bỏ toàn bộ em dash trong mọi tài liệu | Pearl: khu vực mới /curriculum/ (nav thêm mục Curriculum) gồm index (khung bắt buộc + hai loại coverage + 4 tầng thực thể), toan (6 package / 19 module / 59 unit, key concept lấy từ bộ chuẩn MYP Toán Form · Logic · Relationships + related concepts; đối chiếu 5 thành tố năng lực toán học VN và 4 tiêu chí MYP; mục 'một bài toán thuộc package nào' và 'một định lý thuộc unit nào'; coverage 6 package × 3 mạch VN lộ ra khoảng trống Thống kê-Xác suất), van (chuyển từ /ideas/curriculum-van, bổ sung tầng Unit: 6 package / 21 module / 65 unit + ví dụ Lão Hạc và Bánh trôi nước chạy qua sáu package). Redirect 301 _redirects cho URL cũ. Đã kiểm bằng script: cả hai môn ĐẠT ràng buộc 3-6/3-6/3-6. Em dash: thay 832 dấu trong 60 file bằng script theo ngữ cảnh (cặp chú thích thành ngoặc đơn hoặc phẩy; đơn lẻ thành phẩy nếu theo sau là liên từ, còn lại thành hai chấm; trong code block thành gạch nối; tiêu đề và ô bảng thành ' · '), rồi hai lượt sửa văn phong (hai chấm trước liên từ, hai dấu hai chấm cùng dòng) | ✅ |
| SRC-246 | 2026-08-15 | Chỉ đạo: dựng lại curriculum Toán và rà soát curriculum Tiếng Việt, bám Building 21 là chính, IB thứ nhì, phạm vi cấp 1 (lớp 1-5) và cấp 2 (lớp 6-9); vẫn phủ chương trình trong nước nhưng tối thiểu hoá tối đa phần nội dung riêng của Việt Nam | Viết lại /curriculum/toan (5 package: Represent · Compute · Reason · Model · Solve, 19 module, 62 unit) và /curriculum/van (5 package: Decode · Comprehend · Interpret · Compose · Engage, 17 module, 51 unit). Bỏ hẳn khung so sánh ba hệ ở trang môn, thay bằng continuum mức 1-8 thay cho khối lớp (mượn thẳng Building 21: mức không phải lớp, learner có thể ở mức 7 package này và mức 4 package kia cùng lúc). Mỗi package có cột 'learner nói được câu gì về mình' theo kiểu I can, cộng hai cột cấp 1 / cấp 2. Key concept mỗi unit lấy từ bộ chuẩn IB. Phần Việt Nam rút còn một bảng ánh xạ ngắn ở cuối; riêng môn Tiếng Việt, danh mục tác phẩm bắt buộc chuyển thành ràng buộc trên ngữ liệu, không phải package, nên cây dùng lại được cho bất kỳ tiếng mẹ đẻ nào. Kiểm bằng script: cả hai ĐẠT ràng buộc 3-6 package / 3-6 module / 3-6 unit | ✅ |
| SRC-247 | 2026-08-18 | Chỉ đạo: tạo mới Package/Module/Unit/Key Concept môn Toán và Tiếng Việt theo Building 21 (dựa curriculum trong pearl), rồi sinh 30 Learning Experience + 30 Assessment Experience mỗi môn theo kiểu IB, ưu tiên lớp 4-7 | Nạp cây B21 từ trang Pearl vào D1 bằng scripts/curriculum-parse.mjs + scripts/seed-b21-tree.mjs (parse markdown thay vì gõ lại, giữ Pearl là nguồn duy nhất): 5 package × 21 module × 49 unit cho math, 5 × 18 × 39 cho vietnamese, gắn lớp cân đều 4/5/6/7 bằng thuật toán greedy (lấy giữa khoảng thì 21 unit dồn về lớp 6). Nội dung: 31 LX + 31 Assessment (496 câu) môn Toán, 30 LX + 30 Assessment (310 câu) môn Tiếng Việt. Toán sinh bằng hàm có kiểm chứng, Tiếng Việt viết tay từng ngữ liệu vì không công thức nào sinh nổi một câu văn đáng đọc. Mỗi đáp án nhiễu gắn một hiểu lầm có thật (items.misconception); câu hỏi dẫn dắt kiểu IB vào skill_nodes.objective_vi. Assessment là bài đo trên chính node, rút từ kho câu nên mỗi câu sai truy ngược được về đúng unit và đúng hiểu lầm. Cây mới mang source='b21' nên rollback bằng một câu DELETE | ✅ |
| SRC-248 | 2026-08-18 | Chỉ đạo: mỗi Learning/Assessment Experience hiển thị ngay trong Unit và click vào thì đi tới trang riêng | Trước đó trong thẻ Unit chỉ chấm LAB bấm được, hai loại kia là hình trang trí. Cả ba loại thành nút, mỗi loại một địa chỉ chia sẻ được. Nhãn aria kèm loại vì bài học hay trùng tên với lab của chính Unit đó | ✅ |
| SRC-249 | 2026-08-18 | Feedback (ảnh): công thức toán hiện nguyên dạng $\frac{5}{10}$ ở màn xem lại cuối phiên | Màn xem lại quên bọc MathText (màn làm bài thì có). Sửa cả đề bài lẫn đáp án; thêm test đếm: mọi lần chèn {it.prompt} / {opt} vào JSX đều phải nằm trong <MathText>. Sửa kèm một đáp án nhiễu hỏng: bài rút gọn phân số trừ đi k nên khi tử bằng 1 ra $\frac{0}{5}$ — không ai chọn, câu hỏi thực chất chỉ còn ba phương án | ✅ |