Skip to content

SDD-038 · Sổ bằng chứng và thang band ​

Một phần của SDD-038 Cổng IELTS. Phần đầu là đặc tả đang áp dụng, mỗi mục giữ số § cũ; diễn biến và lý do các vòng quyết định nằm ở mục Lịch sử quyết định cuối trang.

5b. Evidence Registry và IELTS Learner Model (chỉ đạo 2026-09-17, vòng 4) ​

Một cửa ghi. shared/evidence.ts là chỗ duy nhất ghi vào learner_evidence. Trước đó bảy module tự viết câu INSERT riêng, mỗi chỗ tự chọn một hằng số reliability (0.85 · 0.8 · 0.75 · 0.7 · 0.6 · 0.5) mà không chỗ nào nói vì sao và không chỗ nào biết chỗ kia chọn số mấy. Bảng EVIDENCE_SOURCES nay trả lời hai câu cho từng nguồn: đáng tin tới đâu, và có được phép đẩy mastery không.

feeds_mastery là khác biệt quan trọng nhất. "Ghi vào sổ" và "được đổi hồ sơ năng lực" là hai việc: một nhận định của model về bài viết phải được ghi (nó là việc đã xảy ra với learner), nhưng không được đẩy mastery (nó là ý kiến, không phải phép đo). Chốt đặt ở đường ghi chứ không ở lời dặn: nguồn khai false mà vẫn truyền mastery_before/after thì cặp số ấy bị bỏ.

Nhịp 2 nối bốn nguồn trước nay im lặng: chép chính tả, bài viết, đoạn ghi âm, và quiz luật chơi. Bài viết và ghi âm vào sổ ngay khi nhận, không đợi chấm — việc đã xảy ra là "đã viết một bài", không phải "đã được model cho một con số".

Lỗ ấy đã vá (chỉ đạo chủ dự án 2026-09-17): apps/ielts nay có đăng nhập. Thêm đăng nhập, không phải thêm tường — 1.560 câu và 140 trang nội dung ở đó đọc được từ ngoài vào, và đó là lý do chúng tồn tại. Người chưa đăng nhập luyện y như cũ, không bị chặn một câu nào; đăng nhập rồi thì bài làm mới được ghi về hồ sơ. Phiên dùng chung cookie .nemo12.com, nên ai đã đăng nhập ở learn thì mở trang này ra là đã có tài khoản sẵn.

Ba chi tiết của lần vá này đáng giữ:

  • Một BÀI một lượt, không phải một CÂU một lượt (bảng ielts_practice_attempts, migration 0230). Learner chấm từng câu khi làm, nhưng đơn vị có nghĩa là cả bài; ghi từng câu sẽ đẻ mười ba dòng cho một bài đọc và một đống bài dở dang không bao giờ kết thúc.
  • Chốt chống gửi trùng nằm trong ref, không trong state. useEffect chạy lại mỗi lần state đổi và chạy hai lần ở StrictMode; một cờ trong state chỉ được đặt sau render kế tiếp, tức là vẫn kịp gửi hai lượt.
  • Router riêng ở server. Mọi đường khác của modules/ieltsPractice cố ý không có requireSession vì chúng phục vụ trang công khai; đường ghi này thì gác vai. Gộp chung một router là sớm muộn có người thêm một đường ghi vào nhầm bên, và bên ấy không gác gì cả.
  • Không có anonymous_id, và cố ý không có: gắn định danh cho người chưa đăng nhập là dựng một hồ sơ theo dõi sau lưng họ.

IELTS Learner Model có bảng riêng (ielts_learner_models, migration 0229). layer.ts vẫn là chỗ chứa toàn bộ suy luận và không lặp lại ở đâu; model.ts lo ba thứ nó cố ý không lo: đọc bằng chứng từ sổ, ước lượng bốn band, và lưu ảnh chụp. Trước đó lát cắt dựng lại mỗi lần mở trang rồi vứt đi, nên hệ không nói được "Reading của con đã đi từ 5.5 lên 6.0" — câu mà một đứa trẻ luyện sáu tháng cần nghe nhất.

Band ước lượng theo đúng ba nguồn, từ đáng tin nhất: mentor_band → ai_band → điểm tự khai. Không có nguồn thứ tư: bài đo hai mươi tư câu không được quy ra band (giới hạn đã ghi ở diagnostic.ts), nên Listening và Reading thường chỉ có số khi learner tự khai. Một ô trống nói đúng điều đó còn hơn một con số nói sai.

Ảnh chụp chỉ ghi khi có gì đổi (thêm bằng chứng, đổi bản thuật toán, hoặc một band đổi) — mở trang mười lần không đẻ mười dòng giống nhau. Câu đọc "ảnh mới nhất" phá hoà bằng rowid DESC: created_at chỉ tới mili-giây, và hai ảnh trong cùng một mili-giây là chuyện xảy ra thật.

5b-bis. Sân luyện nối trọn vào sổ bằng chứng (SRC-849, chỉ đạo 2026-09-19) ​

Rà lại sau SRC-792 thì ba chỗ đứt, và cả ba đứt im lặng — API trả 201, learner thấy đúng màn hình, chỉ cuốn sổ là trống:

Đường learner điTrước SRC-849Sau
POST /learning-events — bài tập năng lực nhỏ, vocab, replay, readchỉ vào learning_eventslượt có đo vào sổ với nguồn ielts_micro, rồi tính lại model
POST /ielts-ladder/writing + /speaking (track practice)chỉ vào ielts_productions + learning_eventsvào sổ với ielts_writing/ielts_speaking, rồi tính lại model
Suy luận của lát cắtevidenceBySkill chỉ đọc assessment_responses của bài đothêm practiceEvidence.ts đọc thẳng Evidence Registry

Hai cuốn sổ, không phải một. learning_events là sổ công sức (mở lại một đoạn nghe, tra một từ, ngồi hai mươi phút); learner_evidence là sổ bằng chứng, mỗi dòng phải trả lời được "đúng mấy trên mấy". Nên chỉ lượt items > 0 mới vào sổ thứ hai. Đổ lượt không đo vào đó sẽ hỏng hai chỗ cùng lúc: confidence của lát cắt tăng theo số dòng, nên bấm phát lại nhiều thành "hệ tự tin hơn" mà không chứng minh thêm gì; và evidence_count là chốt ghi ảnh chụp, nên mỗi lần bấm lại đẻ một dòng lịch sử giống hệt dòng trước.

Rổ luyện tập đứng RIÊNG với rổ bài đo. Dồn chung thì câu "bài đo đúng 4/6" thành một câu nói dối, và calibrate đem lời khai đi so với một hỗn hợp mà chính nó không biết thành phần. Bài đo là một lượt đo có kiểm soát; buổi luyện là learner tự chọn bài, thấy đáp án ngay, làm lại được. Hai thứ ấy không cộng được.

Bằng chứng luyện tập KHÔNG đẩy band (chủ dự án chốt 2026-09-19). Thứ tự mentor_band → ai_band → tự khai giữ nguyên, không có nguồn thứ tư. Rổ luyện nuôi ba thứ khác, tất cả đều nói được mà không cần một con số 0..9:

  • độ tin cậy, trần riêng 0.15 và mỗi câu chỉ đáng một phần sáu câu bài đo. Không có trần ấy thì một learner cày ba trăm câu luyện đạt tin cậy tối đa trong khi hệ chưa từng đo họ lần nào — tức là hệ tự tin nhất đúng lúc nó biết ít nhất;
  • xu hướng 14 ngày so với 14 ngày trước, chỉ nói khi cả hai cửa sổ đủ 6 câu. "Đang khá lên" dựa trên ba câu là một lời hứa dữ liệu không chống lưng được;
  • thứ tự ưu tiên, biên độ 3 — bằng một nửa phần bài đo. Kỹ năng đang tụt được cộng thêm, kỹ năng đang lên không bị trừ: hai vế cố ý không đối xứng, vì đẩy một kỹ năng đang có đà xuống cuối danh sách là làm learner bỏ dở đúng thứ đang chạy tốt.

Kỹ năng lấy từ đâu ra. learner_evidence không có cột skill, và thêm một cột chỉ cho IELTS vào bảng dùng chung cho mọi môn là sai chỗ. Quy ước mới: node_id = 'ielts:{skill}'. Dòng ghi trước quy ước (node_id rỗng) vẫn đọc được qua source + type, nên bằng chứng đã nằm sẵn trong sổ đếm được ngay chứ không bắt learner luyện lại từ đầu để lịch sử của chính mình có giá trị.

Điều kiện ghi ảnh chụp đổi theo. Trước SRC-849, chỉ cần evidence_count khác lần trước là ghi một dòng mới. Điều ấy đúng khi sổ chỉ nhận bài đo và bài nộp — những việc hiếm; từ khi mỗi bài tập nhỏ là một mẩu thì nó biến một buổi hai mươi bài thành hai mươi dòng lịch sử có bốn band y hệt nhau, đúng thứ §5b cấm. Nay so kết quả: bốn band, độ tin cậy, và xu hướng từng kỹ năng. Luật này tự thưa dần — confidence chạm trần rồi thì buổi luyện thứ năm mươi không ghi dòng nào nữa, tức là lịch sử dày lúc đang đổi nhanh và thưa lúc đã ổn định, đúng hình dạng người đọc muốn thấy. evidence_count vẫn được lưu trên dòng (nó trả lời "ảnh này dựng trên bao nhiêu mẩu"), chỉ là không còn quyết định có ghi hay không.

IELTS_MODEL_VERSION lên 2. Ảnh chụp cũ vẫn đọc được đúng như lúc ra đời, và màn admin nói ra khi ảnh đang xem do bản cũ sinh: người vận hành cần biết điều đó trước khi kết luận "hệ đổi ý về đứa trẻ này" — có thể chỉ là cách tính đã đổi, và hai nguyên nhân dẫn tới hai hành động khác hẳn nhau.

Xem ở admin: GET /v1/admin/learners/{id}/ielts-model, màn hình ở admin.nemo12.com/#/models/{learnerId}/ielts. Trang bày ba tầng theo đúng thứ tự người vận hành cần đọc — hệ đang nói gì → bằng chứng nào nuôi kết luận ấy → đã đi từ đâu tới đâu. Thiếu tầng giữa thì tầng đầu là một lời tuyên bố không kiểm được, mà đó đúng là thứ bảng lịch sử dựng ra để tránh. Mở trang không tự tính lại: người đi điều tra mà làm thay đổi hiện trường thì không còn điều tra được nữa, nên tính lại là một nút bấm, và cái bấm ấy để lại một dòng lịch sử.

22. The "Where am I strong?": hai cot, bo chu lap (SRC-877, 2026-09-19) ​

Hai cot. Muoi nang luc xep mot cot doc day moi thu dung sau no xuong duoi man hinh, nen learner phai cuon het bang moi thay duoc cac loi vao luyen tap. Nay sm:grid-cols-2 - mot cot o man hep, hai cot tu 640px.

Vach ngan doi tu divide-y sang vien duoi tung o. divide-y chi dung voi MOT cot doc; trong luoi hai cot no ke ca nhung canh khong phai ranh gioi giua hai dong lien nhau. O cuoi moi cot van giu vien, va do la co y: hai cot khong nhat thiet dai bang nhau nen bo vien theo last: se cat nham mot ben.

Bo chu lap, nhung chi o cho no lap. Voi learner moi, ca muoi dong deu mang dung mot cau "8 more to rate" va dung mot chu "not yet" - muoi lan noi cung mot dieu, va dieu ay thi thanh rong da noi roi, noi bang hinh. Hai chu nay nay chi bien mat KHI CHUA XEP DUOC BAC.

Dong DA co bac giu nguyen ca nhan (Solid) lan phan so (9/12). Go luon hai thu ay thi gon hon nua nhung la go mat chinh thong tin: phan so that noi luon co mau, con co mau la thu quyet dinh con so dang tin toi dau (xem muc 5c).

Mot lo hong cong kiem duoc lap cung luc. The nay truoc do KHONG co ca e2e nao - duong ielts-skills chua co mock nen mastery luon undefined va the tu an di, lang le. Nay fixture tra ve muoi nang luc TRON HAI TRANG THAI (co bac va chua du cau), vi chinh cho giao giua hai trang thai ay la noi chu thua moc ra.

Ma: MasteryRow va MasteryCard trong apps/learn/src/ielts/Hub.tsx. Cong kiem: mot ca trong apps/learn/e2e/smoke.spec.ts.

55. Bảng "Where am I strong?" đọc theo thang band (SRC-941, 2026-09-21) ​

Chín vạch, không phải mười. Chín là số bậc của thang band IELTS, nên mỗi vạch đọc ra đúng một band thay vì một phần mười vô danh. Cùng một cái liếc mắt, nhưng nay nó trả lời được câu learner thật sự mang đi thi. Số vạch nằm ở hằng BARS trong apps/learn/src/ielts/Hub.tsx — một chỗ cho cả bốn kỹ năng, vì thẻ chỉ có một bản.

Nhãn bậc xuống cạnh cụm vạch, phần trăm biến mất. Hai thứ ấy đi thành cặp: phần trăm và cụm vạch nói y hệt một điều, chỉ khác cách viết, nên bỏ một giữ một là bỏ đúng phần thừa; còn nhãn thì thêm thứ cụm vạch không nói được — bấy nhiêu vạch ấy gọi là gì.

Đây không phải lần quay lại của mấy nhãn bị gỡ ngày 2026-09-20 (§31): thứ bị gỡ khi ấy là PHÂN SỐ ("9/12"), vốn mời learner so tử số hai dòng có mẫu số khác nhau. Nhãn ở đây chỉ có một từ, và một từ thì so được với nhau. Dòng chưa đủ câu vẫn không có nhãn nào: ở đó chưa có bậc để gọi tên, và một chữ thay thế kiểu "not yet" đúng là thứ chỉ đạo hôm ấy đã gỡ.

Bản mẫu vẽ chữ "Band 7.5" cho từng năng lực nhỏ. Hệ thống thật không có band ở mức ấy — workers/api/src/modules/ieltsSkills/mastery.ts xếp bậc chứ không chấm band — nên nhãn mang đúng bậc thật. Bịa một con số band vào đây là in ra một điểm thi chưa ai chấm.

Mỗi dòng là một khối HAI DÒNG (chỉ đạo vòng hai cùng ngày, kèm bản mẫu): tên ở dòng trên, cụm vạch ở dòng dưới, pill đè vào đúng ô mà con số phần trăm chiếm trong bản mẫu, mũi tên neo bên phải, tất cả nằm trong một nền bo góc. Bản một dòng trước đó phải buộc tên vào một cột rộng cố định (w-48) vì đó là cách duy nhất giữ mép trái của mọi cụm vạch thẳng hàng, và cái giá là một tên ngắn như "Detail" bị bỏ lại cách cụm vạch của chính nó gần nửa cột. Xếp hai dòng thì hết cả hai cùng lúc: cụm vạch bắt đầu ở mép trái của khối nên tự nó thẳng hàng ở mọi dòng và ở cả hai cột của lưới, còn tên dài bao nhiêu cũng được vì nó không còn đẩy thứ gì. Mũi tên là dấu hiệu bấm được: cả dòng vốn đã là link, nhưng trên màn cảm ứng thì không có động tác rê chuột để phát hiện ra điều đó.

Đầu thẻ căn trái. Tiêu đề lớn ở mép trái với một dòng nhãn nhỏ phía trên, câu hướng dẫn cách đọc bảng chuyển từ cuối thẻ lên ngay dưới tiêu đề, và lối đi "Or practise by task type" thành một nút bên phải cùng hàng. Câu hướng dẫn in sau bảng thì learner chỉ gặp lúc đã đọc xong và đã tự đoán ra một luật nào đó, thường là luật sai; lối đi phụ đứng dưới đáy thì learner đã cuộn qua nó trước khi kịp hỏi "còn cách chia nào khác không". Ba thẻ số liệu phía trên cũng căn trái theo cùng lẽ: mắt đọc một hàng thẻ bằng cách bám một đường dọc bên trái, mà tiêu đề căn giữa cho mỗi thẻ một điểm bắt đầu khác nhau tuỳ độ dài câu hỏi.

Gác: apps/learn/e2e/smoke.spec.ts — ca "Where am I strong: hai cột…" nay đếm chín vạch, đòi nhãn bậc hiện ra trên dòng đã xếp bậc, và đòi không còn dấu % nào trên dòng. Số vạch là thứ hỏng im lặng: mười vạch vẫn vẽ ra một hàng đẹp, chỉ là mỗi vạch không còn đọc ra một band nào cả. Toàn bộ 262 ca của bộ e2e chạy xanh trên bản build thật.

111. Luật "Strong" chặt hơn (SRC-1032, 25.09.2026) ​

  • Mỗi bài chỉ tính lần làm gần nhất. Làm lại bài đã quen đáp án không phải bằng chứng mới.
  • "Solid" và "Strong" cần ít nhất MIN_ADVANCED = 5 câu ở bậc 3 trở lên (tiếng Anh). Đủ tỉ lệ mà thiếu thì dừng ở "Getting there". Câu trong bài đọc/nghe thật (ielts_subskill_results) tính là nâng cao.

Lịch sử quyết định ​

Từ mục 5b-bis. Sân luyện nối trọn vào sổ bằng chứng (SRC-849, chỉ đạo 2026-09-19) ​

Chỉ đạo: "Hãy đảm bảo là khi learner vào học ielts trong learn.nemo12.com/ielts, thì mọi evidence đều được lưu vào evidence registry, rồi sau đó được suy luận và tính toán để update IELTS Learner Model. Rồi tôi có thể xem IELTS Learner Model trong admin.nemo12.com."

Từ mục 22. The "Where am I strong?": hai cot, bo chu lap (SRC-877, 2026-09-19) ​

Chi dao chu du an: "tach cai bang WHERE AM I STRONG thanh 2 cot. Bo bot cac text '8 more to rate' hay 'not yet' di cho gon."

Từ mục 55. Bảng "Where am I strong?" đọc theo thang band (SRC-941, 2026-09-21) ​

Chỉ đạo chủ dự án 2026-09-21, kèm một bản mẫu giao diện: sửa trang kỹ năng theo bản mẫu ấy, và với riêng bảng năng lực thì "chuyển 'Band 7.5' xuống chỗ 70%, bỏ 70% đi" và "chuyển số lượng box của mỗi sub-skill từ 10 xuống còn 9", cho cả bốn trang kỹ năng.

Từ mục 111. Luật "Strong" chặt hơn (SRC-1032, 25.09.2026) ​

Chủ dự án hỏi vì sao learner "Hồng" mới làm ba bài Main Idea đã "Strong". Dữ liệu production: warm-up L1 3/3 làm hai lần + một bài L1 5/5 = 11/11, vượt MIN_ITEMS 8 và ngưỡng 85%. Đúng luật cũ, sai về ý nghĩa. Chủ dự án đồng ý sửa hai chỗ:

Với Hồng: nay 8 câu, "Getting there".